Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Looping over attributes of object of a Non-Active-Record-Model

The simple way to loop over all attributes of an object when using Active Record is

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

But this doesn't work, when we are not using Active Record. How can I iterate over all the attributes of an object then?

For eg -: I have a model in Rails which does not use active record. The object from model order_item can be used in the controller like order_item_object.product_id, order_item_object.quantity, order_item_object.quoted_price. But when I try to order_item_object.attributes.each do |k,v| ...., I get undefined method "attributes" for #<Order:0x00000005aa81b0>

How should I go about this?

like image 211
Pratik Bothra Avatar asked Apr 24 '13 19:04

Pratik Bothra


2 Answers

try this:

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]
like image 191
Arup Rakshit Avatar answered Nov 08 '22 08:11

Arup Rakshit


attr_accessor is simply a macro that creates some methods to set an instance variable. SO perhaps what you want is the instance_variables method, which returns an array of instance variables that you can iterate through

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

But I wouldn't really recommend this. ActiveRecord keeps model data separate for a reason. Your instance may have lots of uses for instance variables. For instance, perhaps you want to track if the record is saved yet or not. This may be kept in @saved variable, which reflects the state of the instance but not the data of the model.

Perhaps you want to keep a hash of attributes instead?

like image 3
Alex Wayne Avatar answered Nov 08 '22 08:11

Alex Wayne