@H_403_1@如何获取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