如何获取ActiveRecord属性方法功能?我有这堂课:
class PurchaseForm include ActiveModel::Validations include ActiveModel::Conversion extend ActiveModel::Naming attr_accessor :name,:surname,:email validates_presence_of :name validates_format_of :email,:with => /^[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i def initialize(attributes = {},shop_name) if not attributes.nil? attributes.each do |name,value| send("#{name}=",value) end end def persisted? false end end
解决方法
这是重构的变体:
class PurchaseForm include ActiveModel::Model def self.attributes [:name,:email] end attr_accessor *self.attributes # your validations def to_hash self.class.attributes.inject({}) do |hash,key| hash.merge({ key => self.send(key) }) end end end
现在您可以轻松使用此类:
irb(main):001:0> a = PurchaseForm.new({ name: 'Name' }) => #<PurchaseForm:0x00000002606b50 @name="Name"> irb(main):002:0> a.to_hash => {:name=>"Name",:surname=>nil,:email=>nil} irb(main):003:0> a.email = 'user@example.com' => "user@example.com" irb(main):004:0> a => #<PurchaseForm:0x00000002606b50 @name="Name",@email="user@example.com"> irb(main):005:0> a.to_hash => {:name=>"Name",:email=>"user@example.com"}
更重要的是,如果要使此行为可重用,请考虑将.attributes和#to_hash方法提取到单独的模块中:
module AttributesHash extend ActiveSupport::Concern class_methods do def attr_accessor(*args) @attributes = args super(*args) end def attributes @attributes end end included do def to_hash self.class.attributes.inject({}) do |hash,key| hash.merge({ key => self.send(key) }) end end end end
现在,只需将它包含在您的模型中即可完成:
class PurchaseForm include ActiveModel::Model include AttributesHash attr_accessor :name,:email # your validations end