RousseauAlexandre RousseauAlexandre - 2 months ago 10
Ruby Question

Does ActiveRecord object not have instance variables for it's attributes but only methods?

In Rails I have the following model:

class Recipe < ActiveRecord::Base
attr_accessible :name , :description ,
:t_baking , :t_cooling , :t_cooking ,:t_rest

# other stuff here

end


with
t_baking
,
t_cooling
,
t_cooking
,
t_rest
as
Time
.

So In my view I want to loop on each value.

<% ['cooking', 'baking', 'cooling' , 'rest'].each do |time| %>
<% time_of_recipe = @recipe.instance_variable_get("@t_#{time}") %>
<% if time_of_recipe.is_a? Time %>
<%= time_of_recipe.strftime "%H:%M" %>
<% else %>
<%= time_of_recipe %>
<% end %>
<% end %>


It doesn't work because

@recipe.instance_variable_get("@t_cooking").class # give NilClass


but

@recipe.t_cooking.class # give Time


Why?

Answer
@recipe.instance_variable_get("@t_cooking")

returns nil because there is no instance variable @t_cooking for @recipe.

It is a bunch of methods defined by ActiveRecord that you have access to, but these are not instance variables.

Applying it to your code, you'd want to change it to:

time_of_recipe = @recipe.public_send("t_#{time}")

Also, it is pointless to save single letter of typing.

It would be much more readable to do the following:

<% %w(t_cooking t_baking t_cooling t_rest).each do |time| %>
    <% time_of_recipe = @recipe.public_send(time) %>
    # ...

EDIT

If you want to check available instance variables (you look to be using Rails 3.2, so your output might be slightly different):

@recipe.instance_variables
#=> [:@attributes, <============ this one is of particular interest
#     :@aggregation_cache,
#     :@association_cache,
#     :@readonly,
#     :@destroyed,
#     :@marked_for_destruction,
#     :@destroyed_by_association,
#     :@new_record,
#     :@txn,
#     :@_start_transaction_state,
#     :@transaction_state
#   ]

So you see, that it defines one instance variable @attributes, that holds all attributes.