update_attriubtes meets "Can't mass-assign protected attributes" problem

hi all:   I have met the "Can't mass-assign protected attributes: " problem.   I have two models. one is province

class Province < ActiveRecord::Base   attr_accessible :name   has_many :cities   accepts_nested_attributes_for :cities end

and another is city class City < ActiveRecord::Base   attr_accessible :name,:province_id   belongs_to :province   has_many :districts end

when I created the city instant by @city=City.new(params[:city]). It works but when I updated it using: @city=City.find(params[:id]) flash[:notice]="error cannot update information of the city" if @city.update_attributes(params[:city])

I got "Can't mass-assign protected attributes: province_id"

I image that the reason new works is that you are not assigning provice_id using update_attributes. Is the code for class City that you posted above copied and pasted from the source or did you re-type it? Can you copy/paste the full error message please and also the bit from development.log for the failing action. Also the code for that action from the controller.

Also check that you have not accidentally left any files in the model folder that should not be there - a copy of an old version of city.rb for example.

Colin

following is my code copied from my codes:

cities_controller and it is in app/controller/admin folder:

#–encoding: UTF-8

class Admin::CitiesController < ApplicationController

respond_to :html, :json

def index

@provinces=Province.all

respond_with [:admin,@provinces]

end

def new

@city=City.new

respond_with [:admin,@city]

end

def edit

@city=City.find(params[:id])

respond_with [:admin,@city]

end

def update

@city=Province.find(params[:id])

flash[:notice]=‘已更新’ if @city.update_attributes(params[:city])

respond_with([:admin,@city])

end

def create

@city=City.new(params[:city])

flash[:notice]=‘已保存’ if @city.save

respond_with [:admin,@city]

end

def destroy

@city=City.find(params[:id])

@city.destroy

flash[:notice]=‘已删除’

respond_with [:admin,@city]

end

def show

redirect_to :action=> ‘index’

end

end

the models:

class City < ActiveRecord::Base

attr_accessible :name,:province_id

belongs_to :province

has_many :districts

end

class Province < ActiveRecord::Base

attr_accessible :name

has_many :cities

accepts_nested_attributes_for :cities

end

and the error message:

Started PUT “/admin/cities/3” for 10.0.2.2 at 2013-04-07 09:05:38 +0800

Processing by Admin::CitiesController#update as HTML

Parameters: {“utf8”=>“✓”, “authenticity_token”=>“K+tQCFj1wM04nN9ZophjVUd3B6k3sQr0immjMJNWb/o=”, “city”=>{“province_id”=>“3”, “name”=>“石家庄”}, “commit”=>“提交”, “id”=>“3”}

Province Load (0.3ms) SELECT “provinces”.* FROM “provinces” WHERE “provinces”.“id” = ? LIMIT 1 [[“id”, “3”]]

(0.2ms) begin transaction

(0.1ms) rollback transaction

Completed 500 Internal Server Error in 5ms

ActiveModel::MassAssignmentSecurity::Error (Can’t mass-assign protected attributes: province_id):

app/controllers/admin/cities_controller.rb:23:in `update’

and I have double checked the models folder, there is no useless file. I have used sunspot and sunspot_solr for the other model. does it have some thing with this problem?

actually this problem is not big problem for me since the city only has two attributes. but I want to know what make it since I cannot google a problem as same as this one.

thanks colin

kang

Shouldn’t you have attr_accessible AFTER the has_many association DSL message call?

Julian

I find the problem that I made mistake in controller since I just copied codes from province_controller and replace every province with city. but in update method, I miss replacing the Province with City. thus the problem happens. the error message led me to wrong direction.

thanks you all