6

使用 Active Record 时循环遍历对象的所有属性的简单方法是

order_item_object.attributes.each do |key,value|
....
end

但这不起作用,当我们不使用 Active Record 时。那么如何遍历对象的所有属性呢?

例如-:我在 Rails 中有一个不使用活动记录的模型。模型 order_item 中的对象可以在控制器中使用,例如 order_item_object.product_id、order_item_object.quantity、order_item_object.quoted_price。但是当我尝试order_item_object.attributes.each do |k,v|......时,我得到undefined method "attributes" for #<Order:0x00000005aa81b0>

我该怎么办?

4

6 回答 6

3

试试这个:

class Parent
  def self.attr_accessor(*vars)
    @attributes ||= []
    @attributes.concat vars
    super(*vars)
  end

  def self.attributes
    @attributes
  end

  def attributes
    self.class.attributes
  end
end

class ChildClass < Parent
  attr_accessor :id, :title, :body
end

p ChildClass.new.attributes.inspect #=> [:id, :title, :body]
于 2013-04-24T19:59:57.577 回答
3

attr_accessor只是一个宏,它创建一些方法来设置实例变量。所以也许你想要的是instance_variables方法,它返回一个实例变量数组,你可以迭代

class Foo
  attr_accessor :bar
  attr_accessor :baz
end

foo = Foo.new
foo.bar = 123
foo.baz
foo.instance_variables.each do |ivar_name|
  ivar_value = foo.instance_variable_get ivar_name
  # do something with ivar_name and ivar_value
end

但我不会真的推荐这个。ActiveRecord 将模型数据分开是有原因的。您的实例可能有很多实例变量的用途。例如,也许您想跟踪记录是否已保存。这可以保持在@saved变量中,它反映了实例的状态,但不反映模型的数据。

也许您想保留属性哈希值?

于 2013-04-24T20:00:17.180 回答
1

这是我找到的最好方法

item=self.instance_values.symbolize_keys
item.each do |k,v|
  ...
  ..
end

有一个代码在这里显示它的用法(查看问题本身的更新) -通过哈希中的元素进行分组

于 2013-04-25T10:19:14.437 回答
1

如果您想要实例变量的字符串表示形式,您可以执行以下操作:

self.instance_values.keys.each do |k|
 ..
end

这应该遍历为您的类定义的所有键(实例变量名称为字符串)。

于 2014-07-30T17:52:57.113 回答
0

您引用的属性是 ActiveRecord 模型上的实例变量,它返回模型数据库属性的哈希值。

一个非 ActiveRecord 模型不会有你调用的属性方法,除非你明确定义它。所有对象都有一个名为 instance_variables 的方法,您可以使用该方法获取属性名称列表,然后反射性地查找属性值。

于 2013-04-24T19:58:37.437 回答
0

一种不太优雅的做法:

class Test
  attr_accessor :firstname,:lastname
  def initialize(fn,ln); @firstname = fn; @lastname = ln; end
end

o = Test.new("Fernando", "Mendez")
o.instance_variables.each {|e| p o.send e.to_s.sub("@","").to_sym}
output:
"Fernando"
"Mendez"

如果要跟踪键值对:

r = o.instance_variables.map {|e| Hash[e,(o.send e.to_s.sub("@","").to_sym)]}

#[{:@firstname=>"Fernando"}, {:@lastname=>"Mendez"}]
于 2013-04-24T20:04:18.147 回答