Amit Erandole
Amit Erandole

Reputation: 12263

How do I get an associated attribute out on my view?

I am rails noob and still trying to wrap my mind around how querying associative data works. Here is my simple schema:

  create_table "microposts", :force => true do |t|
    t.text     "content"
    t.integer  "user_id"
    t.datetime "created_at", :null => false
    t.datetime "updated_at", :null => false
  end

  create_table "users", :force => true do |t|
    t.string   "name"
    t.string   "email"
    t.datetime "created_at", :null => false
    t.datetime "updated_at", :null => false
  end

My Associations are as follows:

class Micropost < ActiveRecord::Base
  attr_accessible :content, :user_id
  belongs_to :user
    accepts_nested_attributes_for :user
end

class User < ActiveRecord::Base
  attr_accessible :email, :name
  has_many :microposts
  accepts_nested_attributes_for :microposts
end

What I am trying to do is query my microposts in such a way that they include an author attribute that corresponds to the user's name in the user table. Here is my html:

<% @microposts.each do |micropost| %>
  <tr>
    <td><%= micropost.content %></td>
    <td><%= micropost.user_id %></td>
    <td>
      **<%= micropost.author %>**
    </td>
    <td><%= link_to 'Show', micropost %></td>
    <td><%= link_to 'Edit', edit_micropost_path(micropost) %></td>
    <td><%= link_to 'Destroy', micropost, method: :delete, data: { confirm: 'Are you sure?' } %></td>
  </tr>
<% end %>

How do get an attribute like microposts.author in one of cells above? I tried querying Microposts.users.name but it seems to return ruby object data like this:

[#<Micropost id: 1, content: "Though good for getting a general overview of Rails...", user_id: 2, created_at: "2012-09-02 01:52:47", updated_at: "2012-09-02 01:52:47">, #<Micropost id: 2, content: "This is another", user_id: 2, created_at: "2012-09-02 01:53:09", updated_at: "2012-09-02 01:53:09">, #<Micropost id: 3, content: "A close cousin of create_table is change_table, 

What's more the data contains no mention of user name data. What am I doing wrong? How can I get micropost.author to work?

Upvotes: 0

Views: 71

Answers (2)

anxiety
anxiety

Reputation: 1709

The belongs_to association works by storing (in your case) the user_id in the Micropost. This allows you to reference the User the Micropost belongs to like this:

micropost.user

And at this point you have access to any of the user attributes, such as name:

micropost.user.name

Edit

Two more things:

1) accepts_nested_attributes_for declarations are typically made in the parent class. They provide you with the ability to make calls like this:

# when creating, it infers the user_id attribute thanks to the nested attribute declaration
user.microposts.create(content: "blah blah")

# similarly, user_id is inferred here as well
user.microposts.where( ... ) 

Including the declaration in your Micropost model implies you intend to create a user (or search for one) from a micropost. Unnecessary in your use cases I think.

2) If you wanted to alias user as "author", you could replace the belongs_to call in Micropost with this:

belongs_to :author, class_name: "User", foreign_key: "user_id"

Which would allow you to query the author name as follows:

micropost.author.name

Upvotes: 1

Ryan Bigg
Ryan Bigg

Reputation: 107718

<%= micropost.user.name %>

You call user to get to the associated user, then call name to get that record's name attribute.

Upvotes: 1

Related Questions