1

In my blog application, I have a post model (name:string, body:text). I want to allow the user to define a custom_field (the model has name:string). This causes the post form to contain a text_field for that custom_field, and the value of that field should be returned as a param from create or update. The actual data returned is of model custom_field_instance (value:string custom_field:references post:references)

For example, if a user created a custom field with name author, and another custom field with name email then I want the post form to display an author and email text fields, and two custom field instances to be returned with the params (one for author, one for email).

The custom fields show up fine in the form, no problem. The params also look fine when there is a single custom field.

The problem is that only one custom field's params are sent in the params. If there are multiple fields, then only the last one's data is sent.

Suppose I have an author and email custom field, and in the new post form, I set name as 'John Doe' and email as '[email protected]', here is what I get in the params (only one custom field instance, the email one, which is the last one):

Parameters: 
{..., "post"=>{"title"=>"post2", ...}, 
  "custom_field_instances"=>
     {"value"=>"[email protected]", "custom_field_id"=>[email_custom_field_id]}, 
"commit"=>"Create Post"}

Here is what I expect to see in the params (both custom field instances :

Parameters: 
{..., "post"=>{"title"=>"post2", ...}, 
  "custom_field_instances"=> 
     {"value"=>"John Doe", "custom_field_id"=>[author_custom_field_id]},   
     {"value"=>"[email protected]", "custom_field_id"=>[email_custom_field_id]}, 
"commit"=>"Create Post"}

Here is the code that I have so far:

posts_controller.rb:

def new
  @post = Post.new
  @custom_fields = CustomField.all
end

views/posts/new.html.erb:

<%= form_for @post,... %>
...
<% @custom_fields.each do |custom_field| %>
    <% @custom_field_instance = CustomFieldInstance.new %>
    <%= fields_for :custom_field_instances, @custom_field_instance do |custom_field_instance_fields| %>
        <%= custom_field_instance_fields.label custom_field.name %>
        <%= custom_field_instance_fields.text_field :value %>       
        <%= custom_field_instance_fields.hidden_field :custom_field_id, value: custom_field.id %>
    <% end %> <!-- end of fields_for block  -->
  <% end %> <!-- end of custom_fields.each loop  -->
...
<% end %> <!-- end of form_for block  -->

I have also tried without the @custom_field_instance where the fields_for line becomes <%= fields_for :custom_field_instances do |custom_field_instance_fields| %>, but it doesn't change anything (still the last custom field instance is the only one sent in the params).

Update 1: I also tried using accepts_nested_attributes_for, but then the view did not show the custom field text fields, since it seems like nested_attributes are only used for existing instances of the associated model. The changes are:

To the above code, I added accepts_nested_attributes_for :custom_field_instances to item_instance.rb, and in the view code above, replaced fields_for ... with post_form.fields_for ...

0

1 Answer 1

1

Make it as an Array

Not tested.

try1:

<%= custom_field_instance_fields.text_field, name: 'value[]' %>

or

<%= custom_field_instance_fields.text_field, 'value[]' %>

same for hidden field.


try2: ( worked for OP )

use {:multiple => true}


try3:

serialize :name, Array

in your CustomFieldInstance model

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks! try2 - multiple: true worked! try1 - both options did not work, did not try try3. Could you please update the answer to reflect that try2 works, thanks.
It works for new, but in edit, the fields do not get prepopulated. Should I have separate code for new and edit (in edit case, I could, instead of the above, do @post.custom_field_instances.each do ...
ya may be different view, use value field .
Seems like the multiple attribute is not supported in earlier versions of browsers - is there a more rails-y way of doing this to work in older browsers as well?
in rails multiple does 2 things, makes the name attribute to Array and adds multiple to the chosen tag.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.