I have following models
class User < ActiveRecord::Base
has_many :project_users, dependent: :destroy
has_many :projects, through: :project_users
end
class ProjectUser < ActiveRecord::Base
belongs_to :user
belongs_to :project
has_many :participants
has_many :tasks, through: :participants
end
class Task < ActiveRecord::Base
belongs_to :project
has_many :participants
has_many :project_users, through: :participants
accepts_nested_attributes_for :participants
end
class Participant < ActiveRecord::Base
belongs_to :project_user
belongs_to :task
end
So the flow should go like this: 1. User creates the project 2. User adds users to project via the join model ProjectUser 3. User creates a task for the project and selects those users from ProjectUsers, who will participate in the task. So I put an accepts_nested_attributes_for method and tried to build the nested form.
In my controller:
def new
@task = Task.new
@task.participants.build
end
def task_params
params.require(:task).permit(:project_id, :project_phase_id, :priority_id, :title, :due_date, :estimation, :responsible_id, :description, :participant_ids => [])#, :participants_attributes => [:project_user_id, :task_id])
end
participants_attributes is commented
In my view:
= f.association :participants, as: :select
Actual HTML generated:
<input name="task[participant_ids][]" type="hidden" value="">
<select class="select optional form-control" id="task_participant_ids" multiple="multiple" name="task[participant_ids][]">
<option value="57">AlexandeR MazeiN</option>
<option value="59">Firenze</option>
<option value="58">Vasily Strekotkin</option>
</select>
I add options via ajax, value = ProjectUser.id I Have to do it like so, because I dont know which ProjectUsers there will be unless a concrete project for a task is selected.
Error I am getting:
Started POST "/tasks" for 127.0.0.1 at 2014-04-11 13:18:24 +0300 User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = 6 ORDER BY "users"."id" ASC LIMIT 1 Processing by TasksController#create as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"aXuk9ZuDvFZce+sbIQLRhWZlVjitMvySaJ7CwWfdmaQ=", "task"=>{"project_id"=>"20", "priority_id"=>"4", "project_phase_id"=>"40", "title"=>"Skepta", "due_date"=>"", "estimation"=>"8", "responsible_id"=>"6", "participant_ids"=>["", "57", "58"], "description"=>""}, "commit"=>"Create Task"} Team Load (0.4ms) SELECT "teams".* FROM "teams" WHERE "teams"."id" = $1 LIMIT 1 [["id", 3]] Participant Load (0.5ms) SELECT "participants".* FROM "participants" WHERE "participants"."id" IN (57, 58) Completed 404 Not Found in 7ms ActiveRecord::RecordNotFound - Couldn't find all Participants with IDs (57, 58) (found 0 results, but was looking for 2):
Your param
hash has the IDs from ProjectUser
as participant_ids
, so when it queries the database it is looking for Participant
models with these IDs. You need to set these as project_user_id
inside of a list of participants, something like this:
participants: [ { project_user_id: 57 }, { project_user_id: 58 } ]
I'm not super familiar with build
, but something along these lines should allow AR to properly construct the associations.