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 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
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.
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.
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 :)).
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.
has_many :through replaced it. If you need attributes on yr join model, has_many :through is the way to do it. has_many :through doesn’t need push_with_attributes because it has an ActiveRecord model with proper attributes. You can just create an instance of that model and set its attributes as needed.
No, @user.admireds is a collection of User objects.
When you do #map, it iterates the collection and replaces the current
index with the return value of the block. So in this case, an array
of User objects is transformed into an array of avatars for those
users. So, @avatars becomes an array of Avatar objects.
Read up on the #map method and it will make more sense.