attr_accessible中属性时的MassAssignment错误

时间:2013-01-30 01:58:37

标签: ruby-on-rails mass-assignment attr-accessible

我在模型中ActiveModel::MassAssignmentSecurity::Error: Can't mass-assign protected attributes: title时收到attr_accessible :title。请参阅下面的控制台调用的代码和输出:

用户模型

# == Schema Information
#
# Table name: users
#
#  id              :integer          not null, primary key
#  name            :string(255)
#  email           :string(255)
#  created_at      :datetime         not null
#  updated_at      :datetime         not null
#  password_digest :string(255)
#  remember_token  :string(255)
#  admin           :boolean          default(FALSE)
#

class User < ActiveRecord::Base
  attr_accessible :name, :email, :password, :password_confirmation
  has_secure_password

  has_many :cycles, foreign_key: "manager_id"
  has_many :reverse_cycles, foreign_key: "employee_id", class_name: "Cycle"
  has_many :employees, through: :cycles
  has_many :managers, through: :reverse_cycles
  has_many :templates, foreign_key: "creator_id"

  before_save { self.email.downcase! }
  before_save :create_remember_token

  validates :name, presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence:   true,
                    format:     { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }
  validates :password, length: { minimum: 6 }
  validates :password_confirmation, presence: true

  #####  Functions  #####

  def create_cycle_as_employee!(other_user, date = 1.year.from_now)
    rcycle = reverse_cycles.create!(manager_id: other_user.id, ends_on: date)
    # self.reload
    rcycle
  end

  def create_cycle_as_manager!(other_user, date = 1.year.from_now)
    cycle = cycles.create!(employee_id: other_user.id, ends_on: date)
    # self.reload
    cycle
  end

  def create_template!(title)
    puts "made it here"
    templates.create!(title: title)
  end

  def is_employee_of?(other_user)
    cycles.find_by_manager_id(other_user.id)
  end

  def is_manager_of?(other_user)
    cycles.find_by_employee_id(other_user.id)
  end


  private

    def create_remember_token
      self.remember_token = SecureRandom.urlsafe_base64
    end
end

模板模型

class Template < ActiveRecord::Base
  include PublicID

  attr_accessible :title #:creator_id, :deleted, :parent_id, :public_id, :title

  belongs_to :creator, class_name: "User"
  has_many :questions, class_name: "TemplateQuestion"

  validates :title, presence: true
  validates :creator_id, presence: true

  def create_question!(content, type = 0) 
    questions.create!(content: content, type: type)
  end

end

堆栈跟踪

1.9.3-p362 :004 > user.create_template!("test")
   (0.1ms)  begin transaction
   (0.1ms)  rollback transaction
ActiveModel::MassAssignmentSecurity::Error: Can't mass-assign protected attributes: title
  from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activemodel-3.2.    11/lib/active_model/mass_assignment_security/sanitizer.rb:48:in `process_removed_attributes'
  from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activemodel-3.2.    11/lib/active_model/mass_assignment_security/sanitizer.rb:20:in `debug_protected_attribute_removal'
  from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activemodel-3.2.    11/lib/active_model/mass_assignment_security/sanitizer.rb:12:in `sanitize'
  from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activemodel-3.2.11/lib/active_model/mass_assignment_security.    rb:230:in `sanitize_for_mass_assignment'
  from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activerecord-3.2.11/lib/active_record/attribute_assignment.    rb:75:in `assign_attributes'
  from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activerecord-3.2.11/lib/active_record/base.rb:497:in `initialize'
  from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activerecord-3.2.11/lib/active_record/reflection.rb:183:in `new'
  from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activerecord-3.2.11/lib/active_record/reflection.rb:183:in     `build_association'
  from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activerecord-3.2.11/lib/active_record/associations/association.    rb:233:in `build_record'
  from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activerecord-3.2.    11/lib/active_record/associations/collection_association.rb:434:in `block in create_record'
  from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activerecord-3.2.    11/lib/active_record/associations/collection_association.rb:149:in `block in transaction'
  from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activerecord-3.2.    11/lib/active_record/connection_adapters/abstract/database_statements.rb:192:in `transaction'
  from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activerecord-3.2.11/lib/active_record/transactions.rb:208:in     `transaction'
  from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activerecord-3.2.    11/lib/active_record/associations/collection_association.rb:148:in `transaction'
  from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activerecord-3.2.    11/lib/active_record/associations/collection_association.rb:433:in `create_record'
  from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activerecord-3.2.    11/lib/active_record/associations/collection_association.rb:123:in `create!'
  from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activerecord-3.2.    11/lib/active_record/associations/collection_proxy.rb:46:in `create!'
  from /Users/r/Sites/MicroEval/ror/app/models/user.rb:51:in `create_template!'
  from (irb):4
  from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/railties-3.2.11/lib/rails/commands/console.rb:47:in `start'
  from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/railties-3.2.11/lib/rails/commands/console.rb:8:in `start'
  from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/railties-3.2.11/lib/rails/commands.rb:41:in `<top (required)>'
  from script/rails:6:in `require'
  from script/rails:6:in `<main>'1.9.3-p362 :005 > user.create_template!("test")

这么大的问题是,为什么?我错过了什么吗?我检查了错别字,但我假设我要么忽略了某些东西,要么不理解。

1 个答案:

答案 0 :(得分:0)

这里的问题是永远不会达到attr_accessible ...语句。原因是错误的include PublicID,这就是原因:

考虑以下控制台声明:

Template.create(:title => "omg")

它将输出以下堆栈跟踪:

1.9.3-p362 :001 > Template.create(:title => "omg")
TypeError: wrong argument type String (expected Module)
    from /Users/r/Sites/MicroEval/ror/app/models/template.rb:2:in `include'
    from /Users/r/Sites/MicroEval/ror/app/models/template.rb:2:in `<class:Template>'
    from /Users/r/Sites/MicroEval/ror/app/models/template.rb:1:in `<top (required)>'
    from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activesupport-3.2.11/lib/active_support/dependencies.    rb:469:in `load'
    from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activesupport-3.2.11/lib/active_support/dependencies.    rb:469:in `block in load_file'
    from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activesupport-3.2.11/lib/active_support/dependencies.    rb:639:in `new_constants_in'
    from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activesupport-3.2.11/lib/active_support/dependencies.    rb:468:in `load_file'
    from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activesupport-3.2.11/lib/active_support/dependencies.    rb:353:in `require_or_load'
    from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activesupport-3.2.11/lib/active_support/dependencies.    rb:502:in `load_missing_constant'
    from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activesupport-3.2.11/lib/active_support/dependencies.    rb:192:in `block in const_missing'
    from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activesupport-3.2.11/lib/active_support/dependencies.    rb:190:in `each'
    from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/activesupport-3.2.11/lib/active_support/dependencies.    rb:190:in `const_missing'
    from (irb):1
    from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/railties-3.2.11/lib/rails/commands/console.rb:47:in     `start'
    from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/railties-3.2.11/lib/rails/commands/console.rb:8:in     `start'
    from /Users/r/.rvm/gems/ruby-1.9.3-p362@rails3tutorial2ndEd/gems/railties-3.2.11/lib/rails/commands.rb:41:in `<top (    required)>'
    from script/rails:6:in `require'    

正如您所看到include存在错误,这是因为首先不需要正确的模块。

require "publicid"模型的顶部添加一个简单的Template将确保确实可以包含该模块。

另外请注意,该模块位于/lib,其中/指的是应用的根目录。

感谢#rubyonrails IRC频道上的@radar提供答案。