to "loop through" the instance variables of ActiveRecord?

to wrap each instance variable of an ActiveRecord object between "<td>" and "</td>", is there a way to "loop through" them, at least in the debug mode, no matter there is getter methods to get them or not, or at least the ones with the getter methods?

Such as

<% @stories.each do |s| %>   <%= "<tr>" %>   <% s.each_property do |i| %>     <%= "<td>#{h i}</td>\n" %>   <% end %>   <%= "</tr>\n" %> <% end %>

?

to wrap each instance variable of an ActiveRecord object between "<td>" and "</td>", is there a way to "loop through" them, at least in the debug mode, no matter there is getter methods to get them or not, or at least the ones with the getter methods?

Such as

<% @stories.each do |s| %> <%= "<tr>" %> <% s.each_property do |i| %>    <%= "<td>#{h i}</td>\n" %> <% end %> <%= "</tr>\n" %> <% end %>

@stories.attributes....

-philip

Philip Hallstrom wrote:

   <%= "<td>#{h i}</td>\n" %> <% end %> <%= "</tr>\n" %> <% end %>

@stories.attributes....

ActiveRecord::Base

-philip

Great thanks.

So I have come up something like this:

the row == 1 check is to print the header

<style>   table { border-collapse: collapse }   td, th { border: 1px solid #ccc; padding: 0.33em }   th { background: #eee } </style>

<%= "<table>\n" %> <% row = 1 %> <% @all_stories.each do |s| %>   <% if row == 1 %>     <%= "<tr>" %>     <% s.attributes.each do |i| %>     <% p i %>     <%= "<th>#{h i[0]}</th>\n" %>     <% end %>     <%= "</tr>\n" %>   <% end %>

  <%= "<tr>" %>   <% s.attributes.each do |i| %>   <% p i %>   <%= "<td>#{h i[1]}</td>\n" %>   <% end %>   <%= "</tr>\n" %>

  <% row += 1 %> <% end %>

<%= "</table>\n" %>

it might be better if the internal loop counter can be used for looping @all_stories so that now extra local variable "row" is needed.

also, the use of i[0], i[1] seems a little less structured than if i.attr_name, i.attr_value can be used.

the row == 1 situation also seems like somewhat not adhering to DRY.

Philip Hallstrom wrote:

  <%= "<td>#{h i}</td>\n" %> <% end %> <%= "</tr>\n" %> <% end %>

@stories.attributes....

ActiveRecord::Base

-philip

Great thanks.

So I have come up something like this:

the row == 1 check is to print the header

<style> table { border-collapse: collapse } td, th { border: 1px solid #ccc; padding: 0.33em } th { background: #eee } </style>

<%= "<table>\n" %> <% row = 1 %> <% @all_stories.each do |s| %> <% if row == 1 %>    <%= "<tr>" %>    <% s.attributes.each do |i| %>    <% p i %>    <%= "<th>#{h i[0]}</th>\n" %>    <% end %>    <%= "</tr>\n" %> <% end %>

<%= "<tr>" %> <% s.attributes.each do |i| %> <% p i %> <%= "<td>#{h i[1]}</td>\n" %> <% end %> <%= "</tr>\n" %>

<% row += 1 %> <% end %>

<%= "</table>\n" %>

it might be better if the internal loop counter can be used for looping @all_stories so that now extra local variable "row" is needed.

I'm not sure that attributes() returns an ordered hash. That is, for each iteration you might get the fields in a different order. You should check that.

also, the use of i[0], i[1] seems a little less structured than if i.attr_name, i.attr_value can be used.

look into "s.attributes.each_pair |k,v|"

the row == 1 situation also seems like somewhat not adhering to DRY.

You could consider using Story.column_names to print out the header and then using that to loop through and print out each object's attributes...

-philip

Philip Hallstrom wrote:

also, the use of i[0], i[1] seems a little less structured than if i.attr_name, i.attr_value can be used.

look into "s.attributes.each_pair |k,v|"

the row == 1 situation also seems like somewhat not adhering to DRY.

You could consider using Story.column_names to print out the header and then using that to loop through and print out each object's attributes...

-philip

yes, column_names gave a better order:

C:\Software Projects\ror\shov10>ruby script/console Loading development environment (Rails 2.3.5)

Story.column_names

=> ["id", "name", "link", "created_at", "updated_at"]

s.attributes came in the order of:

name created_at updated_at id link

with the primary index somewhere in the middle.

In either case however, make *sure* that the order they come in is consistent. Hashes by default do not guarantee any order when looping through them.

Jian Lin wrote:

yes, column_names gave a better order:

C:\Software Projects\ror\shov10>ruby script/console Loading development environment (Rails 2.3.5)

Story.column_names

=> ["id", "name", "link", "created_at", "updated_at"]

so the code can be:

<style>   table { border-collapse: collapse }   td, th { border: 1px solid #ccc; padding: 0.33em }   th { background: #eee }   tr:hover { background: #eee } </style>

<%= "<p><p><p><table>\n" %> <% row = 1 %> <% @all_stories.each do |s| %>   <% if row == 1 %>     <%= "<tr>" %>     <% @column_names.each do |i| %>     <%= "<th>#{h i}</th>\n" %>     <% end %>     <%= "</tr>\n" %>   <% end %>

  <%= "<tr>" %>   <% @column_names.each do |k| %>   <%= "<td>#{h s.attributes[k]}</td>\n" %>   <% end %>   <%= "</tr>\n" %>

  <% row += 1 %> <% end %>

<%= "</table>\n" %>

I found that either

  s.attributes[k]

or

  s.send(k)

can be used. the second one is to invoke the getter method and it gave a slight different version of the datetime object.

kind of interesting that in script/console, i get

s.created_at

=> Thu, 13 May 2010 09:22:50 UTC +00:00

s.send("created_at")

=> Thu, 13 May 2010 09:22:50 UTC +00:00

but on the webpage, i get a different format:

2010-05-13 09:23:58 UTC