使用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>
我应该怎么做?
答案 0 :(得分: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]
答案 1 :(得分: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
变量中,该变量反映实例的状态,但不反映模型的数据。
也许您想要保留属性的哈希值?
答案 2 :(得分:1)
这是我找到的最佳方式
item=self.instance_values.symbolize_keys
item.each do |k,v|
...
..
end
有一个代码可以在这里显示它的用法(查看问题本身的更新) - Grouping via an element in hash
答案 3 :(得分:1)
如果您想要实例变量的字符串表示,您可以这样做:
self.instance_values.keys.each do |k|
..
end
这应该循环遍历为您的类定义的所有键(实例变量名称为字符串)。
答案 4 :(得分:0)
您引用的属性是ActiveRecord模型上的实例变量,它返回模型db属性的哈希值。
除非您明确定义,否则非ActiveRecord模型将不具有您正在调用的属性方法。所有对象都有一个名为instance_variables的方法,您可以使用该方法获取属性名称列表,然后反复查找属性值。
答案 5 :(得分: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"}]