0
votes

I am trying to do an update_attributes of a nested model and keep running into a mass assignment error. Here are my models:

class Lineup < ActiveRecord::Base

  belongs_to :user
  has_many :piece_lineups
  has_many :pieces, through: :piece_lineups

  accepts_nested_attributes_for :piece_lineups

end

class Piece < ActiveRecord::Base
  attr_accessible :cost, :description, :name, :category

  has_many :piece_lineups
  has_many :lineups, through: :piece_lineups

end

class PieceLineup < ActiveRecord::Base
  attr_accessible :piece

  belongs_to :piece
  belongs_to :lineup

end

User has_one lineup by the way. So I thought that by adding accepts_nested_attributes_for to the lineup model that it would work but it is not. Here's my form:

  - @lineup.piece_lineups.build(:piece => piece)
  = form_for(@lineup) do |f|
    = f.fields_for :piece_lineups do |piece_lineup|
      = piece_lineup.hidden_field(:piece_id, :value => piece.id)
    = f.submit

and my Lineup controller action:

  def update
    @lineup = current_user.lineup
    @lineup.update_attributes(params[:lineup])

and finally, the error:

Can't mass-assign protected attributes: piece_lineups_attributes

What am i missing here? Thanks!

2
I think you're missing accepts_nested_attributes_for :piece in PieceLineup - Benjamin Udink ten Cate
this didn't work:( same error - Matthew Berman

2 Answers

3
votes

accepts_nested_attributes_for creates an attribute writer -- in your case, piece_lineups_attributes= -- for passing attributes to another model. So, you need to add attr_accessible :piece_lineups_attributes to your Lineup model to make it mass-assignable.

UPDATE

There is a better way of going about this.

If you add attr_accessible :piece_ids to your Lineup model, then change your view to

= form_for(@lineup) do |f|
  = f.hidden_field(:piece_ids, :value => piece.id)
  = f.submit

You don't need nested attributes at all.

-1
votes

Mass Assignment usually means passing attributes into the call that creates an object as part of an attributes hash. So add piece_lineup's fields to your list of attr_accessors for that model, OR try this:

@lineup = current_user.lineup
@lineup.piece_id = params[:piece_id]
@lineup.save

Also see:

http://api.rubyonrails.org/classes/ActiveModel/MassAssignmentSecurity/ClassMethods.html