Kiril Kirilov
Kiril Kirilov

Reputation: 11257

Rails: submit form with nested attributes throws 'couldn't find entity with id=xxx'

I got the following model classes:

class Movie < ActiveRecord::Base
  has_and_belongs_to_many :actors
  accepts_nested_attributes_for :actors, :allow_destroy => true
  ...
end

and

class Actor < ActiveRecord::Base
  has_and_belongs_to_many :movies
  ...
end

movies/_form.html.haml view contains the nested form for actors:

...
= form_for @movie do |movie_form|
  = movie_form.fields_for :actors do |actor_form|
    = actor_form.text_field :id, "Id"
    = link_to_remove_fields "remove", actor_form
  = link_to_add_fields movie_form :actors
...
  = movie_form.submit 'Save'

link_to_remove_fields and link_to_add_fields are helper methods performing javascript calls, adding new fields for new actors or removing actors.

The controller:

   class MovieController < ApplicationController

     #POST form
     def create
       @movie = Movie.new(params[:movie])
       ...
     end

     #GET nearly empty form with one field for actor
     def new
       @movie = Movie.new
       1.times {@movie.actors.build}

       respond_to do |format|
         format.html
         format.json { render json: @movie }
       end
     end
   end

The problem: When 'Save' is pressed (with only one actor with id=718, for example) and the form is submitted, the @movie = Movie.new(params[:movie]) line of the controller throws the following error:

Couldn't find Actor with ID=718 for Movie with ID=

I'm sure that there is entity with id=718 in the Actor database.

Upvotes: 2

Views: 895

Answers (2)

Frederick Cheung
Frederick Cheung

Reputation: 84152

The easiest thing if you are trying to associating existing actors to a new movie is not to use accepts_nested_attributes at all.

One of the things you get with your actors associations is a actor_ids, which return the ids of the associated actors, or allows you to set the list of associated actors.

To submit an array via a rails form, the name of the input must end with [], for example if you have an input with name movie[actor_ids][] and value 1, then you'll get

{'movie' => {'actor_ids' => ['1']}}

in your controller. If you want to submit a second actor, just create another input with the same name movie[actor_ids][]. You could also use a select box with the multiple attribute set, but they can be a bit unfriendly for users especially when there are more than just a few options to pick from.

Upvotes: 2

RobHeaton
RobHeaton

Reputation: 1390

Unfortunately you can't use accepts_nested_attributes_for with has_and_belongs_to_many (see Trying to use accepts_nested_attributes_for and has_and_belongs_to_many but the join table is not being populated for example). You would probably be able to build something similar with a network of has_many :x through: :ys though.

Upvotes: 1

Related Questions