0

Project and tasks have a one-to-many relationship, and project accepts_nested_attributes_for :tasks.

In the form, my task objects look like:

project[tasks][2][assigned_time]
project[tasks][2][due_time]

When the form is submitted I get a hash like:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"...=", "project"=>{"id"=>"1", "tasks"=>{"1"=>{"assigned_time"=>"09:00", "due_time"=>"17:00"}, "2"=>{"assigned_time"=>"09:00", "due_time"=>"17:00"}}

Then I expect them to be saved by just saving the project object:

project = Project.find(params[:id])

respond_to do |format|
  if project.update_attributes(params[:tasks])

But I get:

WARNING: Can't mass-assign protected attributes: id SQL (0.3ms) ROLLBACK Completed in 169ms

ActiveRecord::AssociationTypeMismatch (Task(#2188181260) expected, got Array(#2151973780)):

Any ideas how to fix this?

3 Answers 3

4

In your Projects model, accepts_nested_attributes_for :tasks. This will define @project.tasks_attributes= if you have a has_many :tasks association or @project.task_attributes= if you have a has_one :task association.

In your form, the following:

= form_for @project do |f|
  = f.label :project_attribute
  = f.text_field :project_attribute

  = f.fields_for :tasks do |t|
    = t.label :task_attribute
    = t.text_field :task_attribute

In your projects controller, the following:

def new
  @project = Project.new
  @project.tasks.build #=> if has_many
  @project.build_task  #=> if has_one
end
Sign up to request clarification or add additional context in comments.

Comments

1

I think, you just forget to add task_attributes to attr_accessible list in your Project model:

attr_accessible :tasks_attributes, ...

And also, note, that, maybe you generating wrong form, because in my current application, form with nested attributes uses task_attributes method, not tasks (like in your hash)

3 Comments

Actually I had to define task_attributes=. I don't fully understand it, but it's working. I'm curious for the explanation if anyone knows
Add your Project model to question, please
attr_accessible was deprecated in Rails 4 in favor of Strong Parameters
0

Use form_with instead form_for in view helped me:

<%= form_with model: @book do |f| %>
  <%= f.label :name %>
  <%= f.text_field :name %>

  <%= f.fields_for :items do |ff| %>
    <%= ff.label :item_name %>
    <%= ff.text_field :item_name %>
  <% end %>
<% end %>

My controller:

def new
  @book = Book.new
  @book.items.build
end

def create
  current_user.books << Book.new(book_params)
end

private

def book_params
  params.require(:book).permit!
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.