Hello,
I have a has_and_belongs_to_many relationship that I''ve realized I need
to add additional attributes to. So I''m converting it to a has_many
:through (HMT) relationship. This is the first time I''ve used an HMT,
and it seems like I''m using too much code. I couldn''t figure
out how to
get the join model objects to update automatically as a result of
updating the primary object, so I''ve ended up doing individual
saves/updates on each join model object.
The story is a regatta can include many boat classes, and a boat class
can be included in many regattas.
class Regatta < ActiveRecord::Base
has_many :inclusions
has_many :boat_classes, :through => :inclusions
has_and_belongs_to_many :users
end
class BoatClass < ActiveRecord::Base
has_many :inclusions
has_many :regattas, :through => :inclusions
end
class Inclusion < ActiveRecord::Base
belongs_to :regatta
belongs_to :boat_class
end
Eventually, I''ll attach a fee to each boat_class when it gets included
in a regatta. But for now I''m just trying to get back to the same
functionality I had when it was a HABTM relationship, and there was no
"include" model. So, here is what the update method looks like now:
@regatta = Regatta.find(params[:id])
Inclusion.find_all_by_regatta_id(params[:id]).each { |i|
boat_class = i.boat_class
if params[:boat_classes]
i.included = params[:boat_classes].include? boat_class.id
params[:boat_classes].delete boat_class.id
else
i.included = false
end
flash[:notice] = ''inclusion failure'' if !
i.update_attribute(:included, i.included)
}
params[:boat_classes].each { |boat_class_id|
boat_class = BoatClass.find boat_class_id
logger.info "*** boat class #{boat_class.name} inclusion not
found"
@regatta.inclusions << Inclusion.new { |i|
i.boat_class_id = boat_class_id
i.included = true
flash[:notice] = ''inclusion failure'' if ! i.save
}
} if params[:boat_classes]
@regatta.users = User.find(params[:users]) if params[:users]
if @regatta.update_attributes(params[:regatta])
flash[:notice] = ''Regatta was successfully updated.''
redirect_to :action => ''show'', :id => @regatta
else
render :action => ''edit''
end
It seems to me that I shouldn''t have to individually update all the
existing inclusions, or manually create & save the new ones. I''d
like
suggestions for how I can reduce the amount of code here. Considering
that the first 20 lines used to simply be:
@regatta = Regatta.find(params[:id])
@regatta.boat_classes = User.find(params[:boat_classes]) if
params[:boat_classes]
Additional background info: a) this keeps the join model objects around
even when a boat_class gets excluded, so that it''s attributes will be
saved. That''s not critical, if I can have it be much tighter,
I''m happy
to give that up. b) there is a bug in this that I haven''t found yet,
but
is irrelevant to this question: this code creates a new inclusion even
when there is an existing one found already. It seems params[...].delete
is not working the way I expect it to.
Thanks for any help,
Avram
--
Posted via http://www.ruby-forum.com/.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---