Perfect! This works, you are the man. Thank you. I can now collect
all the user_id’s of the admirers of a user by using @user.admireds.
Now if I can only trouble you for some more brain power, I am trying
to use these user_id’s to create an instance of @avatars. There is a
user_id field in each avatar object and I want to gather all the
avatar objects in @avatars that correspond to to the @user.admireds.
I think this may be simple, but it is still giving me trouble. Any
thoughts?? Thanks!
HABTM does have its use. It is NOT deprecated and will NEVER be removed
out
of Rails, period. If your domain does not need any attributes other
than
the foreign keys of the tables that are connected then HABTM is good
enough.
In this case the association class is just a join table.
When your application demands that other attributes needs to be
persisted
that belongs to the association class then you have to go for the
has_many :
through relationship.
When your application demands that other attributes needs to be persisted
that belongs to the association class then you have to go for the has_many :
through relationship.
I also had a weird case with a many-to-many relationship between two
classes in the same inheritance hierarchy. I had to use hmt for that.
I never said it was going to be removed from Rails. I do think it’s a
gimped solution compared to HMT and is generally viewed as, shall we
say, outmoded in 99% of cases.
I never said it was going to be removed from Rails. I do think it’s a
gimped solution compared to HMT and is generally viewed as, shall we
say, outmoded in 99% of cases.
I think that 99% is way overstated.
HABTM works just fine for cases where there are no attributes needed
in the association. In my experience, that’s probably 90% of the
time.
What’s deprecated is push_with_attributes, NOT HABTM. If you need
what Josh calls a “rich association” then, yes, HMT is the way to
model it.
In fact HABTM got a little love in Rails 2.0 with the new fixture
support which was included from the rathole plugin
I can honestly say that in 99% of cases where I would use HABTM, I
use HM:T because I can almost guarantee that I will be attaching extra
data to the relationship OR I will want to fetch all the relationships
separately (for example, I want to see all book selections for a
bookstore or something).
Perhaps it’s the work that I’ve been doing and have always done, but
that’s the case that I’ve found myself in.
Please don’t confuse the newbies with your opinions. It is your wish to
follow a speculative design in your projects. Newbies need guidelines to
follow for a given situation.
This has basically degenerated into a stupid pissing match.
This is all opinion. You could easily do the same thing we’re talking
about here with raw MySQL drivers and regular Ruby classes, but AR and
habtm or hm:t is a better solution. I was merely sharing what I’ve
learned to be best practice and what has been deemed less than best
practice by myself and others.
As for “speculative design,” it’s not “speculative” if one is simply
thinking ahead. Going about software without doing that is what leads
to “refactoring” that are actually just fixing your stupid mistakes
because you didn’t think when you were writing code. If you think
that implementing something that I can nearly always expect to use is
speculative, one could say that any abstraction is speculative. “I’ll
probably need to share this piece of ERb so I’ll push it into a
partial” or “I’ll probably be adding a lot of different types of data
to this collection so it might be better to make it a Hash rather than
an Array so I can get at it by key” are both, by your definition,
statements of speculative design but are sound design decisions to
make. Surely you can’t contend that thinking ahead isn’t a good idea?
As for this thread, I think we’re done here. My HM:T code worked for
him, a newbie has been helped, problem solved.
This example sets @avatars to the value of avatar for every element in @user.admireds. For a block as simple as this, the following will
probably
do the same thing.
@avatars = @user.admireds.map(&:avatar)
I saw this usage on a Web page somewhere and use it regularly, but I
don’t
know Ruby well enough to understand exactly what it means.
I think this code is calling the .avatar for each user.admireds object
though. And that method is undefined for that class. I dont think
this works. What about doing something like: @avatars =
Avatar.find(:all).select {|avatar| avatar.user_id == @user.admireds }
This doesnt work though b/c it doesnt iterate through the @user.admireds. This is the problem, I need to do two iterations and
make comparisons with each. I’m just not sure how to do this.
On 27 Dec 2007, at 15:41, Jeffrey L. Taylor wrote:
@avatars = @user.admireds.map(&:avatar)
I saw this usage on a Web page somewhere and use it regularly, but I
don’t
know Ruby well enough to understand exactly what it means.
It’s a shortcut. The & tells ruby that the parameter being passed
should be used as the block to this method. ruby calls to_proc on it
(in this case :avatar) to make sure it gets a proc.
Symbol#to_proc creates a proc which when given an object calls the
named method on it
Sorry about that! You might need to change admirer to admiree
depending on which side of the relationship you’re doing (sorry about
not being able to scrollback and see but I’m in a bit of a hurry :)).
Right. I have already defined this relationship but when I do @user.admireds.avatar it says: undefined method `avatar’ for
Admiration:Class.
so I dont think @user.admireds is creating user objects in the first
place.
This gives me a null object. Cause its basically saying @user.admireds.admirer.avatar…which creates a null object I guess.
Im pretty confused now, Ive been tinkering with this for a while now.
Any other ideas are appreciated. Thanks.