Reputation: 12263
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
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
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