Morgan Grubb
2008-Jun-16 11:44 UTC
Quick question on updating attributes on the join model in a has_many :through relationship
The question is this: how are you supposed to do it? I''ve seen a lot of blog posts that say that HM:T has beaten HABTM and that we can now all easily have data on the join model and go on to show how to enter that data into the join model but don''t show a recommended way of modifying it later. I''ve checked against a pile of books, too, as well as the AR api and Google''s exhaustive collection of blogs. Neither The Rails Way nor Agile Web Development show an example that I can find. Obviously this is something really simple that I have missed so if someone could please post a link to the place where it is actually demonstrated that would be wonderful. Taking the example from http://blog.hasmanythrough.com/2006/8/19/magic-join-model-creation if you''re unsure what I mean: That automagically creates the join record with the role attribute set to> "author". Pretty nifty, eh? But we can do better. > > class Contribution < ActiveRecord::Base > belongs_to :book > belongs_to :contributor > belongs_to :author, :class_name => "Contributor" > belongs_to :editor, :class_name => "Contributor" > end > class Book < ActiveRecord::Base > has_many :contributions, :dependent => :destroy > has_many :contributors, :through => :contributions, :uniq => true > has_many :authors, :through => :contributions, :source => :author, > :conditions => "contributions.role = ''author''" do > def <<(author) > Contribution.with_scope(:create => {:role => "author"}) { self.concat author } > end > end > has_many :editors, :through => :contributions, :source => :editor, > :conditions => "contributions.role = ''editor''" do > def <<(editor) > Contribution.with_scope(:create => {:role => "editor"}) { self.concat editor } > end > end > end > > Then give this a shot... > > dave = Contributor.create(:name => "Dave") > chad = Contributor.create(:name => "Chad") > awdr = Book.create(:title => "Agile Web Development with Rails") > awdr.authors << dave > awdr.editors << chad > >That''s brilliant (although I suspect it will break now because at some point with_scope got removed from public so I''m not sure what people suggest nowadays). What if you added another field to contributions? Let''s say, for lack of a better example, time_spent. This is how you are supposed to find it, as far as I can tell: dave = Contributor.find_by_name "Dave" book = Book.find_by_title "Agile Web Development with Rails" contribution = Contribution.find_by_book_id_and_author_id book.id, dave.id And then you can now go contribution.time_spent = 9.months But surely there is a way to get that contribution object out of the collection proxy? Something like: contribution = dave.books.proxy_object(dave.books.first) or contribution = dave.books.proxy_objects.first (Yes, I realise this would be essentially the same thing, but the method I showed first strikes me as being very non-rails). So, is there some wonderful resource where this has been demonstrated that I''ve just missed? Cheers, Morgan. -- -------------------------------------------------------------------------- Morgan Grubb - Just Landed General Tel: +34 91 590 2611 morgan.grubb-9pJevV/ekkYyY3YROqfsYA@public.gmane.org -------------------------------------------------------------------------- http://www.justlanded.com - Helping people abroad! 30 countries, in up to 8 languages, more to come... -------------------------------------------------------------------------- --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Morgan Grubb
2008-Jun-16 16:01 UTC
Re: Quick question on updating attributes on the join model in a has_many :through relationship
Is this question too confusing or too obvious to warrant a response from somebody? Morgan. 2008/6/16 Morgan Grubb <morgan.grubb-9pJevV/ekkYyY3YROqfsYA@public.gmane.org>:> The question is this: how are you supposed to do it? > > I''ve seen a lot of blog posts that say that HM:T has beaten HABTM and that > we can now all easily have data on the join model and go on to show how to > enter that data into the join model but don''t show a recommended way of > modifying it later. > > I''ve checked against a pile of books, too, as well as the AR api and > Google''s exhaustive collection of blogs. Neither The Rails Way nor Agile Web > Development show an example that I can find. > > Obviously this is something really simple that I have missed so if someone > could please post a link to the place where it is actually demonstrated that > would be wonderful. >-- -------------------------------------------------------------------------- Morgan Grubb - Just Landed General Tel: +34 91 590 2611 morgan.grubb-9pJevV/ekkYyY3YROqfsYA@public.gmane.org -------------------------------------------------------------------------- http://www.justlanded.com - Helping people abroad! 30 countries, in up to 8 languages, more to come... -------------------------------------------------------------------------- --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Pardee, Roy
2008-Jun-16 17:36 UTC
Re: Quick question on updating attributes on the join model in a has_many :through relationship
Well, with HM:T, you''ve got an actual model to work with--so you can do all the regular things you do w/models--.new them, .update them, etc. In a view, you''d do a form_for & pass in a reference to an instance o your join model. The things you''re joining can be represented via say, collection_select''s modifying the respective <<model name>>_id fields in your join model. If the goal is allowing create/edit on views devoted to one or both of the joined models, you can treat those exactly as if they were just a regular has_many--so, field_for, w/an appropriately engineered name. See the railscasts on "complex forms" for the gory details. HTH, -Roy ________________________________ From: rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org [mailto:rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org] On Behalf Of Morgan Grubb Sent: Monday, June 16, 2008 9:02 AM To: rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org Subject: [Rails] Re: Quick question on updating attributes on the join model in a has_many :through relationship Is this question too confusing or too obvious to warrant a response from somebody? Morgan. 2008/6/16 Morgan Grubb <morgan.grubb-9pJevV/ekkYyY3YROqfsYA@public.gmane.org>: The question is this: how are you supposed to do it? I''ve seen a lot of blog posts that say that HM:T has beaten HABTM and that we can now all easily have data on the join model and go on to show how to enter that data into the join model but don''t show a recommended way of modifying it later. I''ve checked against a pile of books, too, as well as the AR api and Google''s exhaustive collection of blogs. Neither The Rails Way nor Agile Web Development show an example that I can find. Obviously this is something really simple that I have missed so if someone could please post a link to the place where it is actually demonstrated that would be wonderful. -- ------------------------------------------------------------------------ -- Morgan Grubb - Just Landed General Tel: +34 91 590 2611 morgan.grubb-9pJevV/ekkYyY3YROqfsYA@public.gmane.org ------------------------------------------------------------------------ -- http://www.justlanded.com - Helping people abroad! 30 countries, in up to 8 languages, more to come... ------------------------------------------------------------------------ -- --~--~---------~--~----~------------~-------~--~----~ 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@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Morgan Grubb
2008-Jun-17 09:48 UTC
Re: Quick question on updating attributes on the join model in a has_many :through relationship
Thanks for that. The basic answer is that you just have to manually find the join model and then modify that as necessary. Which is what I was doing but which I thought was silly because hey, this is Rails, there has to be an easier way to do it. :) Cheers. 2008/6/16 Pardee, Roy <pardee.r-go57ItdSaco@public.gmane.org>:> Well, with HM:T, you''ve got an actual model to work with--so you can do > all the regular things you do w/models--.new them, .update them, etc. In a > view, you''d do a form_for & pass in a reference to an instance o your join > model. The things you''re joining can be represented via say, > collection_select''s modifying the respective <<model name>>_id fields in > your join model. > > If the goal is allowing create/edit on views devoted to one or both of the > joined models, you can treat those exactly as if they were just a regular > has_many--so, field_for, w/an appropriately engineered name. See the > railscasts on "complex forms" for the gory details. > > HTH, > > -Roy > > ------------------------------ > ** > >-- -------------------------------------------------------------------------- Morgan Grubb - Just Landed General Tel: +34 91 590 2611 morgan.grubb-9pJevV/ekkYyY3YROqfsYA@public.gmane.org -------------------------------------------------------------------------- http://www.justlanded.com - Helping people abroad! 30 countries, in up to 8 languages, more to come... -------------------------------------------------------------------------- --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Pardee, Roy
2008-Jun-17 15:10 UTC
Re: Quick question on updating attributes on the join model in a has_many :through relationship
Well, not necessarily--in those railscasts I mentioned, they show how to use pseudo-attributes on one of the ''parent'' models to create/update/delete associated instances of a join model. For example, here''s a bit of my Project model class (which represents research projects) that manages the associations between projects and research areas: class Project < ActiveRecord::Base has_many :projects_research_areas, :dependent => :delete_all has_many :research_areas, :through => :projects_research_areas def new_research_area_attributes=(raa) raa.each do |ra| projects_research_areas.build(ra) end end def existing_research_area_attributes=(raa) projects_research_areas.each do |ra| attributes = raa[ra.id.to_s] if attributes ra.attributes = attributes ra.save else projects_research_areas.delete(ra) end end end end # class Project Those *_research_area_attributes=() methods get called (as if by magic ;-) when the project controller says e.g., Project.new(params[:project]) and they create/update/delete associated instances of the join model as necessary. You direct a given instance of a join model to either the new_ or existing_ version by setting the first argument to fields_for() to the right string. Check out railscasts 73-75 (IIRC) for the full story. See especially the updated code posted on the episode 75 page. HTH, -Roy ________________________________ From: rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org [mailto:rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org] On Behalf Of Morgan Grubb Sent: Tuesday, June 17, 2008 2:48 AM To: rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org Subject: [Rails] Re: Quick question on updating attributes on the join model in a has_many :through relationship Thanks for that. The basic answer is that you just have to manually find the join model and then modify that as necessary. Which is what I was doing but which I thought was silly because hey, this is Rails, there has to be an easier way to do it. :) Cheers. 2008/6/16 Pardee, Roy <pardee.r-go57ItdSaco@public.gmane.org>: Well, with HM:T, you''ve got an actual model to work with--so you can do all the regular things you do w/models--.new them, .update them, etc. In a view, you''d do a form_for & pass in a reference to an instance o your join model. The things you''re joining can be represented via say, collection_select''s modifying the respective <<model name>>_id fields in your join model. If the goal is allowing create/edit on views devoted to one or both of the joined models, you can treat those exactly as if they were just a regular has_many--so, field_for, w/an appropriately engineered name. See the railscasts on "complex forms" for the gory details. HTH, -Roy ________________________________ -- ------------------------------------------------------------------------ -- Morgan Grubb - Just Landed General Tel: +34 91 590 2611 morgan.grubb-9pJevV/ekkYyY3YROqfsYA@public.gmane.org ------------------------------------------------------------------------ -- http://www.justlanded.com - Helping people abroad! 30 countries, in up to 8 languages, more to come... ------------------------------------------------------------------------ -- --~--~---------~--~----~------------~-------~--~----~ 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@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---