I am having a hard time seeing how some aspects of associations
work...
For instance, I have a "Role" class with a "has_many :users" assoc.
and a "User: class with a "belongs_to :role" assoc., when I run this
sample code in the console "u = User.find(:all)" and then "u.methods"
I do not see the new role related methods in the methods list, same if
I run the similar code for "Role", no new user methods.
However, I run "u = User.new" then "u.methods" the new role methods
show that they have been added to the "u" object.
Since this is the case, I am stumped as to how running something like
"@users = User.find(:all)" in the user's controller's index action
allows me to successfully use <% for user in @users %> <%=h
user.role.name %> <%end%> etc. in my views.
I am having a hard time seeing how some aspects of associations
work...
For instance, I have a "Role" class with a "has_many :users" assoc.
and a "User: class with a "belongs_to :role" assoc., when I run this
sample code in the console "u = User.find(:all)" and then "u.methods"
I do not see the new role related methods in the methods list, same if
I run the similar code for "Role", no new user methods.
However, I run "u = User.new" then "u.methods" the new role methods
show that they have been added to the "u" object.
I wouldn't read to much into that - methods get added at what can seem
like odd times sometimes.
Maybe you could help me out with a more pragmatic issue...
Based on the User and Role model associations I outline above, I am
able to successfully run this in the User index view
<% for user in @users %>
<%=h user.role.name %>
<%end%>
"name" is a property of the Role model. No problem here.
However, when I try and call a property of "users" thru "role" I get
undefined method errors.
Here's an example:
<% for role in @roles %>
<%=h role.users.login %>
<%end%>
"login" is definitely a property of the "user" model but it and other
"user" properties all throw undefined method error errors.
What gives? The Role model "has_many :users" so it seems logical that
this should work even if the "user" view code didn't.
Here's an example:
<% for role in @roles %>
<%=h role.users.login %>
<%end%>
"login" is definitely a property of the "user" model but it and other
"user" properties all throw undefined method error errors.
True, login is a property of user, but a role can have multiple users,
so which login should it return from role.users.login? login, in that
context, is indeterminate.
<% for role in @roles %>
<% for user in role.users %>
<%=h user.login %>
However, when I try and call a property of "users" thru "role" I get
undefined method errors.
Here's an example:
<% for role in @roles %>
<%=h role.users.login %>
<%end%>
"login" is definitely a property of the "user" model but it and other
"user" properties all throw undefined method error errors.
What gives? The Role model "has_many :users" so it seems logical that
this should work even if the "user" view code didn't.
Doesn't seem logical to me - users is an array of users. what does
users.login mean ?
OK, this is starting to make sense now. I have not really been aware
of when I was working with collections or singular objects apparently,
and further how to correctly interact with them.
This code worked great:
<% for role in @roles %>
<% for user in role.users %>
<%=h user.login %>
Is there some kind of more succinct way of getting this information by
using some kind of chaining syntax instead of nested loops, whether it
be in the controller or view?
Thanks for the help guys. I understand much better already!
OK, this is starting to make sense now. I have not really been aware
of when I was working with collections or singular objects apparently,
and further how to correctly interact with them.
has_many is plural, has_one, belongs_to are singular. if you are
following the conventions then if the association name is plural (ie
users) then it's a collection.
This code worked great:
<% for role in @roles %>
<% for user in role.users %>
<%=h user.login %>
Is there some kind of more succinct way of getting this information by
using some kind of chaining syntax instead of nested loops, whether it
be in the controller or view?
You can be a little more economical with puncuation but it boils down
to the same thing.
Just to clarify, the only way I can use method chaining is If I am
working with an Object instead of a collection... The loops are just a
way to get to the Objects I need to work with. That make sense right?
Just to clarify, the only way I can use method chaining is If I am
working with an Object instead of a collection... The loops are just a
way to get to the Objects I need to work with. That make sense right?
That's more or less it (the less being that collections are objects
too - you just can't call instance methods of a given user on an array
of users)