I have been using rails professionally for only a month and a half now, but I am continually running into problems with form helpers and accessing multiple objects on a single page. To whit: 1. While text_field and text_area and such all support the :index option, the select helper does not. 2. When appending the text ''[]'' to a helper''s object name, the id is inserted into the brackets --- but only for existing objects. While it is understandably difficult as new objects have no ids, a method must exist somewhere to provide these form helpers with a unique way to communicate their unique data to their responding controllers. One suggestion is to create the option to specify the object attribute that will be used to fill the ''[]''s. The example for which I''m having to work around this is an administrative form to generate promotional contact forms. These forms each have up to 6 questions and each question can have up to 4 answers. Thus in the model, Promo has_many PromoQuestion which has_many PromoAnswer. So I am dealing with having to iterate over three levels of hierarchical data both in the edit form and in the creation form. It does not seem Rails is designed to handle this type of form terribly simply. While I understand that this type of form is possible, its implementation seems far from elegant. 3. Rails hierarchical model objects seem to support the creation of a tree of new objects that can then be saved with @parent.save. But modifying this same tree afterwards does not. Should there not be a way to modify attributes of existing child objects and mark them as "to be saved" so that when @parent.save is called to update the parent, all the child objects are also updated? This does not seem to be the case, as I experienced with the self-same promo example above. Calling @parent.save after modifying @parent.child.attributes = {...} does not save the modifications to the child. Perhaps there are undocumented features of which I am not aware. If this is the case, then my issue becomes one with the documentation. And perhaps I just do not understand the elegant way to perform such tasks as those above. If so, I am eager to learn, and would greatly appreciate being pointed to the appropriate documentation. -- Posted via http://www.ruby-forum.com/.
Stephen Friedman
2006-Apr-24 15:45 UTC
[Rails] Re: Does Rails need more useful form helpers?
I forgot to complete my sugestion in #2 above. If one could set the attribute used with the []s in form helpers, I could, in my example above, use question_number and answer_number to distinguish data for the various child objects regardless of whether they were new objects to be created or existng objects to be updated. This brings up another issue that I feel should have a simple solution. The solution above only works if the question_number AND answer_number are used to identify the answer objects. Currently the [] notation for form helpers does not allow the definition of multiple indices. But this above solution may not even be an acceptable final solution. New objects may not have something as simple as a question_number with which to reference themselves. And yet it seems something is needed to allow the creation of multiple dependent items in a single form. Perhaps some means of creating temporary ids for each new object, saving them to the flash and using those ids to distinguish []-marked attributes for new objects. Another suggestion would be a way to tell a form helper about a hierarchy of objects (or have it intuitively deduce them?). Ideally, it would seem that while the Promo object''s attributes exist in params as promo[title], promo[description] and so forth that its children''s data should exist in params as promo[promo_questions][id][question_text] and promo[promo_questions][id][promo_answers][id][answer_text] (where "id" would be replaced by the actual id of the existing object or an empty string for new objects). This should then be able to be passed to @promo.update_attributes() and @promo.new() alike to create or update all these items in one clean, elegant swoop. And finally, as I said in my previous post, perhaps this elegance exists and I simply do not know about it. Or perhaps this elegance does not exist for some intended purpose or reason. -- Posted via http://www.ruby-forum.com/.
Mark Reginald James
2006-Apr-24 23:35 UTC
[Rails] Re: Does Rails need more useful form helpers?
Stephen Friedman wrote:> 1. While text_field and text_area and such all support the :index > option, the select helper does not.The select and collection_select helpers support the index option in their html_options hash, so you have to do something like: select :object, :method, {}, :index => 3> 2. When appending the text ''[]'' to a helper''s object name, the id is > inserted into the brackets --- but only for existing objects. While it > is understandably difficult as new objects have no ids, a method must > exist somewhere to provide these form helpers with a unique way to > communicate their unique data to their responding controllers. OneI will discuss this in a reply to your follow-up email.> 3. Rails hierarchical model objects seem to support the creation of a > tree of new objects that can then be saved with @parent.save. But > modifying this same tree afterwards does not. Should there not be a way > to modify attributes of existing child objects and mark them as "to be > saved" so that when @parent.save is called to update the parent, all the > child objects are also updated? This does not seem to be the case, as I > experienced with the self-same promo example above. Calling @parent.save > after modifying @parent.child.attributes = {...} does not save the > modifications to the child.I agree that a common method for both creating and updating a tree of AR objects would greatly simplify controller code. I have a plugin half-written that does just that, keeping track of what attributes and associations have been changed, so that a save of the parent object does all the work. -- We develop, watch us RoR, in numbers too big to ignore.
Mark Reginald James
2006-Apr-25 00:08 UTC
[Rails] Re: Does Rails need more useful form helpers?
Stephen Friedman wrote:> I forgot to complete my sugestion in #2 above. If one could set the > attribute used with the []s in form helpers, I could, in my example > above, use question_number and answer_number to distinguish data for the > various child objects regardless of whether they were new objects to be > created or existng objects to be updated.Yes, you can use the :index option to uniquely number or name both new and existing objects.> This brings up another issue that I feel should have a simple solution. > The solution above only works if the question_number AND answer_number > are used to identify the answer objects. Currently the [] notation for > form helpers does not allow the definition of multiple indices.In order to use multiple indices you have to either use the _tag versions of the form helpers, or set the name explicitly: <% @promo.questions.each_with_index |@q, qnum| do prefix = "promo[promo_questions][#{qnum}]" %> <%= text_field :q, :question_text, :name => prefix + ''[question_text]'' %> <% @q.answers.each_with_index |@a, anum| do %> <%= text_field :a, :answer_text, :name => prefix + "[answer_text][#{anum}]" %> <% end end %>> But this above solution may not even be an acceptable final solution. > New objects may not have something as simple as a question_number with > which to reference themselves. And yet it seems something is needed to > allow the creation of multiple dependent items in a single form. Perhaps > some means of creating temporary ids for each new object, saving them to > the flash and using those ids to distinguish []-marked attributes for > new objects.A common synthetic reference id like a question number is probably better than using the id attribute for existing objects combined with a unique temporary id for new object. Existing object ids can either be determined from their synthetic ids, or placed in the form as hidden fields.> Another suggestion would be a way to tell a form helper about a > hierarchy of objects (or have it intuitively deduce them?). Ideally, it > would seem that while the Promo object''s attributes exist in params as > promo[title], promo[description] and so forth that its children''s data > should exist in params as promo[promo_questions][id][question_text] and > promo[promo_questions][id][promo_answers][id][answer_text] (where "id" > would be replaced by the actual id of the existing object or an empty > string for new objects). This should then be able to be passed to > @promo.update_attributes() and @promo.new() alike to create or update > all these items in one clean, elegant swoop.An update_attributes method that worked hierarchically like this would be nice. -- We develop, watch us RoR, in numbers too big to ignore.
Stephen Friedman
2006-Apr-25 16:09 UTC
[Rails] Re: Does Rails need more useful form helpers?
My apologies about the :index option for select''s. I thought I tried that but I guess I didn''t.> In order to use multiple indices you have to either use the _tag > versions of the form helpers, or set the name explicitly: > > <% @promo.questions.each_with_index |@q, qnum| do > prefix = "promo[promo_questions][#{qnum}]" %> > <%= text_field :q, :question_text, :name => prefix + ''[question_text]'' > %> > <% @q.answers.each_with_index |@a, anum| do %> > <%= text_field :a, :answer_text, :name => prefix + > "[answer_text][#{anum}]" %> > <% end > end %>You agree, I assume, that this is an ugly approach not worthy of the elegance of rails. In my opinion, it would make for much cleaner rails applications if rails understood multiple indices (e.g.: :index => [question_number, answer_number]) or naturally handled hierarchical data. Or both.> A common synthetic reference id like a question number is probably > better than using the id attribute for existing objects combined with a > unique temporary id for new object. Existing object ids can either > be determined from their synthetic ids, or placed in the form as > hidden fields.It was an off-the-cuff thought. I agree, two sets of ids is not a good idea. I was worried that if synthetic reference ids became the primary method of handling these situations, applications would eventually crop up where such an id could not be synthesized. However, I''m not sure what that situation would be. Collections of new objects being generated all at once need to be referenced somehow, I presume.> An update_attributes method that worked hierarchically like this would > be nice.I agree. I think this is the best solution so far. Personally, I''d like to see it work with both update_attributes() and new(). Perhaps rails can use array index 0 to signify new items to be added, since this will never be a database record id. All new object data can be placed into an array underneath this index while existing objects to be modified would remain under array indices matching their ids. I think this solution both covers a generic scope of applications and has the elegance I''ve come to expect from rails. Are there any problems with this solution I haven''t thought of? -- Posted via http://www.ruby-forum.com/.