Associations?


#1

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.

Thanks for the help here.


#2

On 9 Mar 2009, at 15:32, elliottg wrote:

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.

Fred


#3

OK, I hear that.

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.

Thanks for the help.

On Mar 9, 11:37 am, Frederick C. removed_email_address@domain.invalid


#4

Elliott G. wrote:

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 %>

is how you would get at that tidbit


#5

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!

On Mar 9, 12:46 pm, Frederick C. removed_email_address@domain.invalid


#6

On 9 Mar 2009, at 17:19, elliottg wrote:

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.

Fred


#7

On 9 Mar 2009, at 16:10, elliottg wrote:

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 ?

Fred


#8

Thanks Fred.

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?

EG

On Mar 9, 1:49 pm, Frederick C. removed_email_address@domain.invalid


#9

Excellent.

Thanks so much for the help. I get it now.

Best, Elliott

On Mar 9, 3:15 pm, Frederick C. removed_email_address@domain.invalid


#10

On 9 Mar 2009, at 17:54, elliottg wrote:

Thanks Fred.

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)

Fred