在模型 Rails 3.2.2 中没有设置 attr_accessible 的质量分配

Posted

技术标签:

【中文标题】在模型 Rails 3.2.2 中没有设置 attr_accessible 的质量分配【英文标题】:No Mass assignment with attr_accessible set in model Rails 3.2.2 【发布时间】:2013-05-25 01:03:26 【问题描述】:

我在我的 Rails 3.2.2 应用程序中创建了一个 twitter 样式来跟踪用户之间的关系。我有UserRelationship 模型。

class Relationship < ActiveRecord::Base
  belongs_to :user
  belongs_to :follower, :class_name => 'User'

  attr_accessible :follower, :follower_id, :status
end

class User < ActiveRecord::Base
  has_many :authentications, class_name: 'UserAuthentication'
  has_many :relationships
  has_many :followers, :through => :relationships
  has_many :following, :through => :relationships, :foreign_key => 'follower_id', :source => :follower

  # Include default devise modules. Others available are:
  # :token_authenticatable, :confirmable,
  # :lockable, :timeoutable and :omniauthable
  devise :omniauthable, :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :password_confirmation, :remember_me
end

我决定把设计和omniauth的东西留在那儿,以防它碰巧是问题的一部分,尽管我对此表示怀疑。

在命令行中,我与两个用户 u1u2 一起工作。

我运行命令

u1.followers.build(:follower_id=>u2.id)

并收到此错误

ActiveModel::MassAssignmentSecurity::Error: Can't mass-assign protected attributes: follower_id
    from /Users/bradleyp/.rvm/gems/ruby-1.9.2-p290/gems/activemodel-3.2.2/lib/active_model/mass_assignment_security/sanitizer.rb:48:in `process_removed_attributes'
    from /Users/bradleyp/.rvm/gems/ruby-1.9.2-p290/gems/activemodel-3.2.2/lib/active_model/mass_assignment_security/sanitizer.rb:20:in `debug_protected_attribute_removal'
    from /Users/bradleyp/.rvm/gems/ruby-1.9.2-p290/gems/activemodel-3.2.2/lib/active_model/mass_assignment_security/sanitizer.rb:12:in `sanitize'
    from /Users/bradleyp/.rvm/gems/ruby-1.9.2-p290/gems/activemodel-3.2.2/lib/active_model/mass_assignment_security.rb:228:in `sanitize_for_mass_assignment'
    from /Users/bradleyp/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.2/lib/active_record/attribute_assignment.rb:75:in `assign_attributes'
    from /Users/bradleyp/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.2/lib/active_record/base.rb:495:in `initialize'
    from /Users/bradleyp/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.2/lib/active_record/reflection.rb:183:in `new'
    from /Users/bradleyp/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.2/lib/active_record/reflection.rb:183:in `build_association'
    from /Users/bradleyp/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.2/lib/active_record/associations/association.rb:233:in `build_record'
    from /Users/bradleyp/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.2/lib/active_record/associations/has_many_through_association.rb:91:in `build_record'
    from /Users/bradleyp/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.2/lib/active_record/associations/collection_association.rb:112:in `build'
    from /Users/bradleyp/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.2/lib/active_record/associations/collection_proxy.rb:46:in `build'
    from (irb):29
    from /Users/bradleyp/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.2.2/lib/rails/commands/console.rb:47:in `start'
    from /Users/bradleyp/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.2.2/lib/rails/commands/console.rb:8:in `start'
    from /Users/bradleyp/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.2.2/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'

这是我第一次在关联上使用build 方法,但如果我能让它工作似乎很方便。如果您需要更多信息,请询问。感谢您的帮助!

【问题讨论】:

attr_accessible 不是保护属性的好方法。 strong_parameters 现在是推荐的方法。 【参考方案1】:

follower_idRelationship 上的一个字段。当您调用u1.followers.build 时,您正在构建一个没有follower_id 列的User。由于您使用的是attr_accessible,rails 不会让您知道该列不存在,它只是告诉您您无权访问它。 (从安全角度来看,这很好。)

不管怎样,看起来你想做的:

u1.relationships.build(:follower_id => u2.id)

或许

u1.followers << u2

(使用您展示的代码,我不能 100% 确定第二种情况是否会影响我的思维类型——您可能需要进一步调整您的 attr_accessible 以使第二种方法起作用。第一种肯定会起作用,不过。)

【讨论】:

以上是关于在模型 Rails 3.2.2 中没有设置 attr_accessible 的质量分配的主要内容,如果未能解决你的问题,请参考以下文章

Ruby on Rails 生成模型

Rails 4:在没有命名空间模型的子路径中组织 Rails 模型?

初识ATT&CK模型

初识ATT&CK模型

初识ATT&CK模型

初识att&ack框架