12

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

PurchaseFormオブジェクトのすべての名前と値を一覧表示する属性メソッドを作成するにはどうすればよいですか?

4

5 に答える 5

17

リファクタリングされたバリアントは次のとおりです。

class PurchaseForm
  include ActiveModel::Model

  def self.attributes
    [:name, :surname, :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", :surname=>nil, :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, :surname, :email

  # your validations
end
于 2015-08-28T21:35:04.323 に答える
14

#instance_values仕事をすることができます:

class PurchaseForm
  attr_accessor :name, :email

  def attributes
    instance_values
  end
end

出力サンプル:

purchase.attributes #=> {"name"=>"John", "email"=>"john@example.com"}
于 2016-11-18T15:06:44.303 に答える
7

私はこのコードで問題を解決することができました:

class PurchaseForm
  include ActiveModel::Validations
  include ActiveModel::Conversion
  extend ActiveModel::Naming

  attr_accessor :attributes,
                :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 = {})
    @attributes = attributes
  end

  def persisted?
    false
  end
end
于 2011-03-28T18:08:07.207 に答える
6

これを試してみましょう

self.as_json

=> {:name=>"Name", :surname=>nil, :email=>"user@example.com"}

于 2016-08-16T14:23:52.397 に答える
-3

使用する方が良いのではないでしょうか

include ActiveModel::Serialization

def attributes
  JSON.parse(self.to_json)
end
于 2013-03-18T14:07:03.523 に答える