Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 4, nested attributes, Couldn't find Tag with ID= for Person with ID=

Rails 4: I want to create Person with tags

person = Person.new(:name=>Jon', :tags_attributes=>[{:id=>'15', :name=>'some_tag'}])

My Person model:

class Person < ActiveRecord::Base

  validates :name, presence: true

  belongs_to :user
  has_many :organizations, through: :people_organizations
  has_and_belongs_to_many :tags, join_table: :people_tags

  has_many :phones, as: :phoneable, :dependent => :destroy
  has_many :emails, as: :emaileable, :dependent => :destroy
  has_many :networks, as: :networkable, :dependent => :destroy
  has_many :messengers, as: :messengerable, :dependent => :destroy

  accepts_nested_attributes_for :phones, :emails, :networks, :messengers, allow_destroy: true
  accepts_nested_attributes_for :tags, reject_if: :all_blank

end

My PeopleController:

  def create
    @person = Person.new(person_params)

    respond_to do |format|
      if @person.save(validate: false)
        format.json { render action: 'show', status: :created }
      else
        format.json { render json: @person.errors, status: :unprocessable_entity }
      end
    end
  end

  def person_params
    params.require(:person).permit(:id, :name, :born, :description, 
      phones_attributes:[:id, :number, :_destroy],
      emails_attributes:[:id, :email, :_destroy]
      networks_attributes:[:id, :name, :_destroy],
      messengers_attributes:[:id, :identifier, :_destroy],
      tags_attributes:[:id, :name, :_destroy]
    )
  end

When i create new person, i have error

p = Person.new(:name=>'Jon', :tags_attributes=>[{:id=>'15', :name=>'tag'}])

Couldn't find Tag with ID=15 for Person with ID=

Please tell me what to do to keep the model

like image 426
Viktor Leonets Avatar asked Sep 16 '13 19:09

Viktor Leonets


1 Answers

I got the same problem. I think that rails just don't support creating a new record with an existing nested record. I found no solution for this situation at all. So Try to filter tags_attributes from person_params and then use tag_ids like this:

tag_ids = params[:person][:tags_attributes].map { |tag| tag[:id] }
@person = Person.new(person_params.merge({ tag_ids: tag_ids })
like image 155
AntonTkachov Avatar answered Oct 02 '22 00:10

AntonTkachov