Hi all, I cannot find a clean way to create/edit an object that ''belongs_to'' another one, just by using form fields. I always need to explicitely unassemble it, store the master id in a hidden field, and then refetch the master from its id, and put it back in the object. To summarize: I want to create a new member, for a given project @project= ... @member = Member.new (:project => @project) => in the view, if I have a form with project<%= text_field ''member'', ''project'' %><br> login <%= text_field ''member'', ''name'' %><br> it doesn''t work: - the project fields contains/shows #<Project:0x248aa50> - when I submit the form, I get the error : "Project expected, got String" Is there a nice Rails idioms to solve this problem? Alain -- Posted via http://www.ruby-forum.com/.
On 12/16/05, Alain Ravet <alainravet-spam2004-/E1597aS9LQAvxtiuMwx3w@public.gmane.org> wrote:> > Hi all, > > I cannot find a clean way to create/edit an object that ''belongs_to'' > another one, just by using form fields. > I always need to explicitely unassemble it, store the master id in a > hidden field, and then refetch the master from its id, and put it back > in the object. > > To summarize: > I want to create a new member, for a given project > > @project= ... > @member = Member.new (:project => @project) > > => in the view, if I have a form with > > project<%= text_field ''member'', ''project'' %><br> > login <%= text_field ''member'', ''name'' %><br> > > it doesn''t work: > - the project fields contains/shows > #<Project:0x248aa50> > - when I submit the form, I get the error : > "Project expected, got String" > > Is there a nice Rails idioms to solve this problem? > > > Alain > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >You could try using the session for it. I keep both ids ( session[:project_id] or session[:project][:id] ) and whole objects ( session[:project] ) inside it. Disclaimer: I am running a low-medium load public site and I have NOT profiled memory use yet. -- ------------------------------ Joyeux Noël ------------------------------ Peter Fitzgibbons _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Alain Ravet wrote:> Hi all, > > I cannot find a clean way to create/edit an object that ''belongs_to'' > another one, just by using form fields. > I always need to explicitely unassemble it, store the master id in a > hidden field, and then refetch the master from its id, and put it back > in the object. > > To summarize: > I want to create a new member, for a given project > > @project= ... > @member = Member.new (:project => @project) > > => in the view, if I have a form with > > project<%= text_field ''member'', ''project'' %><br> > login <%= text_field ''member'', ''name'' %><br> > > it doesn''t work: > - the project fields contains/shows > #<Project:0x248aa50> > - when I submit the form, I get the error : > "Project expected, got String" > > Is there a nice Rails idioms to solve this problem?The technique demonstrated in the 15 minute Rails movie, at the point where comments are added to blog posts, is to put the parent object''s ID in the URL that the child details will be submitted to: In the view of a specific post, app/views/blog/show.rhtml, which also shows the existing comments, this form is used to add a new comment: <%= form_tag :action => ''comment'', :id => @post %> <%= text_area "comment", "body" %><br/> <%= submit_tag "Comment!"%> </form> and the new comment is handled by this action in the controller: def comment Post.find(params[:id]).comments.create(params[:comment]) flash[:notice] = "Added your comment." redirect_to :action => "show", :id => params[:id] end regards Justin
Justin > The technique demonstrated in the 15 minute Rails movie, > is to put the parent object''s ID in the URL parameter I know, and that''s what I do, but it''s not nice. What if an object belongs_to 5 other entities: def new ... m = Member.new (:project => project, :section => section, :branch => branch, etc...) And what if this object already exist, and you just want to edit it? It''s not very comfortable, having to 1/dismantle all the parts linked to foreign keys, 2/ship their IDs(in the url), <form action here> 3/collect the parts + the foreign keys id, and then 4/ fetch the foreign object and rebuild the main object before 5/saving. I wonder if there isn''t a Rails idiom to solve that problem? Alain -- Posted via http://www.ruby-forum.com/.
Alain Ravet wrote:> > The technique demonstrated in the 15 minute Rails movie, > > is to put the parent object''s ID in the URL parameter > > I know, and that''s what I do, but it''s not nice.OK - your previous post said that you were using a hidden field.> What if an object belongs_to 5 other entities: > def new > ... > m = Member.new (:project => project, > :section => section, :branch => branch, > etc...) > And what if this object already exist, and you just want to edit it? > > It''s not very comfortable, having to > 1/dismantle all the parts linked to foreign keys, > 2/ship their IDs(in the url), > <form action here> > 3/collect the parts + the foreign keys id, and then > 4/ fetch the foreign object and rebuild the main object > before > 5/saving.Your earlier question was just about members of projects (which in general would be many-to-many, so you might be editing a Membership rather than a Member). I''m not clear on whether, in your expanded example, it''s the Member or the Project that has section and branch - or the Membership? Which relationships are genuine "belongs to" (strict containment) relationships, and which are just references?> I wonder if there isn''t a Rails idiom to solve that problem?I don''t claim any particular expertise, but this is my take: Passing the id in the URL is appropriate when you have navigated from a parent to a new child. Other references from the child would normally be set up by controls in the child form (e.g. select lists, checkboxes...). If you are editing an existing object, and there are relationships that aren''t being changed (e.g. if it isn''t changing its parent) then you don''t need to pass those IDs around. You have a copy of the object, either in the session or in the database, and you can leave those attributes unchanged. For relationships that *are* changeable, there should be controls on the child form. I agree that would be nice if there were standard examples covering the various relationship types and user interaction styles, and especially if scaffolding could be extended to cover some of this. regards Justin
Justin >> > is to put the parent object''s ID in the URL parameter >> I know, and that''s what I do, but it''s not nice. > > OK - your previous post said that you were using a hidden field. I''ve tried many techniques, where I each time explicitely manipulated the belonged_to/foreign_key related object/id. >> 3/collect the parts + the foreign keys id, and then >> 4/ fetch the foreign object and rebuild the main object >> before 5/saving. > > Your earlier question was just about members of projects Actually, I''m letting one member edit his info, but the project is fixed in advance. member = Member.new (:project => the_project) > Which relationships are genuine "belongs to" (strict containment) > relationships, and which are just references? For example, add a new ''Employee'' to a a given ''Company'', and give him a default work "Address". => The data sent to the form is e = Employe.new (:company => the_company, :address => the_company.address) In the db, the ''employees'' table has 2 foreign keys : company_id, and address_id. My problem is that when it comes to creating an ''employee'' in a form, I have to EXPLICITELY manipulate its ''address'' and ''company'' ids/foreign keys after the submit, even though I already set those 2 values in an earlier step (see above). ( manipulate the fk == extract them, send them to the form, store them in hidden fields as numerical values, and after the submit perform multiple XXX.find( fk) to retrieve the employee previously known address and company, and stuff them back in the employee object. I''m just wondering/asking is there is a Rails idiom for this case, that would make my life simpler and the code shorter/clearer. Alain -- Posted via http://www.ruby-forum.com/.
Alain Ravet wrote:> Justin > >> > is to put the parent object''s ID in the URL parameter > >> I know, and that''s what I do, but it''s not nice. > > > > OK - your previous post said that you were using a hidden field. > > I''ve tried many techniques, where I each time explicitely manipulated > the belonged_to/foreign_key related object/id. > > > >> 3/collect the parts + the foreign keys id, and then > >> 4/ fetch the foreign object and rebuild the main object > >> before 5/saving. > > > > Your earlier question was just about members of projects > > Actually, I''m letting one member edit his info, but the project is fixed > in advance. > member = Member.new (:project => the_project) > > > > Which relationships are genuine "belongs to" (strict containment) > > relationships, and which are just references? > > > For example, add a new ''Employee'' to a a given ''Company'', and give him a > default work "Address". > > => The data sent to the form is > e = Employe.new (:company => the_company, :address => > the_company.address) > > In the db, the ''employees'' table has 2 foreign keys : company_id, and > address_id. > My problem is that when it comes to creating an ''employee'' in a form, I > have to EXPLICITELY manipulate its ''address'' and ''company'' ids/foreign > keys after the submit, even though I already set those 2 values in an > earlier step (see above). > > ( manipulate the fk == extract them, send them to the form, store them > in hidden fields as numerical values, and after the submit perform > multiple XXX.find( fk) to retrieve the employee previously known address > and company, and stuff them back in the employee object. > > I''m just wondering/asking is there is a Rails idiom for this case, that > would make my life simpler and the code shorter/clearer.So long as there is no risk that the company or company address has been deleted by another user, you don''t need to do those finds - you can just set the IDs using the accessors for company_id and address_id. An alternative approach would be to hold the Employee/Company/Address combination in the session, so that when the form is submitted you could - get the Employee out of the session - apply the changes - save it - clear the session attribute regards Justin