Quin
Quin

Reputation: 523

Is there a way to get the `id` of a nested_form field helper element?

I am trying to create the for attribute for a label in a nested form (Using nested_form). Is there a way to get the id of a corresponding f.checkbox?

HAML:

= label_tag '???', "Set as On",  class: primary_btn
= f.check_box :is_on

Additional Information: The current Model structure is like Post has many Images with field is_on

So I would like to create a nested field group like:

  <label class="primary_btn" for="post_images_attributes_0_is_on">Set as primary</label>
  <input id="post_images_attributes_0_is_on" name="post[images_attributes][0][is_on]" style="display:none;" type="checkbox" value="1">

Upvotes: 2

Views: 1117

Answers (1)

max
max

Reputation: 101831

The trick is to use fields_for. It gives you a "scoped" form builder instance which creates inputs for the nested fields.

= form_for (:post) do |f| 
    # ... a bunch of fields
    = f.fields_for :images do |builder|
        = builder.label :is_on, "Set as primary"
        = builder.check_box :is_on

However your solution has some real gotchas:

  • Every time you change the primary image you need to update all the post.images to ensure that only one image has the is_on flag.
  • You need to do primary_image = post.images.where(is_on: true)
  • It won't work if the image can belong to many posts.

A better solution is create a special relation to the primary image on Post.

class Post < ActiveRecord::Base
  has_many :images
  has_one :primary_image, class_name: 'Image'
end

This would store the primary image as an integer in posts.primary_image_id instead of as a boolean flag on images.

We can use collection_select to get select tag to display the primary image attribute.

= form_for (@post) do |f| 
    # ... a bunch of fields
    = f.fields_for :images do |builder|
        # ...
  = f.collection_select(:primary_image, @post.images, :id, :name)

This admittedly is not really optimal from a user experience perspective. A solution which requires javascript would be to have a hidden field for :primary_image and update its value when the user clicks the checkbox. If you are unsure how to do this please create a new question since its out of the scope of your original question.

Upvotes: 2

Related Questions