Adam
Adam

Reputation: 339

Rails nested association & multiple collection_select

I'm fairly new to rails and I'm having some issues updating my association tables when using multiple select.

I have three tables, portrait portrait_tags and tags

(The tags stores the names of my tag names (traditional, inspirational, community etc))

My desired outcome is that the 'multiple select field' will add the tags to the portrait_tag table based on the Tag.all tag_id value. Currently this seems to insert only one field and the tag_id in the portrait_tag table is NULL, then when I return to the edit page the multiple select is duplicated.

Params

  Parameters: {"utf8"=>"✓", "authenticity_token"=>"j+Obhq9u+mvOKYnj4+TAGy+be8s3AbZlMvuyKiot5iyKqjMyFAcs23PjbQjOTjwl6aRBx1M5lmYRZzTjOeDTJA==", "portrait"=>{"portrait_tags_attributes"=>{"0"=>{"tag_id"=>["", "1", "2"]}}}, "commit"=>"Save changes", "id"=>"72"}

Tag.rb

class Tag < ActiveRecord::Base

  has_many :portraits, through: :portrait_tags
  accepts_nested_attributes_for :portraits

end

Portrait.rb

class Portrait < ActiveRecord::Base

    has_many :portrait_tags
    has_many :tags, through: :portrait_tags

    accepts_nested_attributes_for :portrait_tags

end

Portrait_tag.rb

class PortraitTag < ActiveRecord::Base

  belongs_to :portrait
  belongs_to :tag

end

Edit.html.haml

%h1 Edit Portrait
= form_for [:admin, @portraits], :html => { :method => :put } do |f|

  - if flash[:system].present?
    - flash[:system].each do |e|
      %div= e

  - if flash[:notice].present?
    %div= flash[:notice]

  = f.fields_for :portrait_tags do |a|
    = a.collection_select :tag_id, Tag.all, :id, :name, {}, {multiple: true}

  = f.submit "Save changes", class: "btn btn-primary"

PortraitController

class Admin::PortraitsController < ApplicationController

    def edit
       @portraits = Portrait.where(artist_id: 33, id: params[:id]).take
       @portraits.portrait_tags.build

    end

    def update

      @portrait = Portrait.where(artist_id: 33, id: params[:id]).take


      if @portrait.update(portrait_params)

        p portrait_params

      else
        flash[:system] = @portrait.errors.full_messages
        p @portrait.errors.full_messages

        render :edit
      end

    end

    private
      def portrait_params
        # Permit our attributes
        params.require(:portrait).permit(:id, portrait_tags_attributes: [:id, :tag_id => [] ])

      end



end

portrait_tags table

+----+-------------+--------+
| id | portrait_id | tag_id |
+----+-------------+--------+

portraits table

+----+-----------+--------------+
| id | artist_id | artist_image |
+----+-----------+--------------+

tags table

+----+-----------+--------------------+
| id |   name    |   portrait_tag_id  |
+----+-----------+--------------------+

Upvotes: 0

Views: 787

Answers (1)

Atul Shukla
Atul Shukla

Reputation: 171

<%= collection_select(:portrait_tag, :tag_ids, 
              Tag.all(:order=>"name ASC"), 
              :id, :name, {:selected => @portraits.tag_ids, :include_blank => true}, {:multiple => true}) %>

Hope this will work for you.

Upvotes: 2

Related Questions