我在Rails 3.2.2应用程序中创建了一个twitter风格的用户关系。我有User
和Relationship
型号。
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
我决定把设计和无所不在的东西留在那里,以防它碰巧是问题的一部分,尽管我对此表示怀疑。
在命令行中,我与两个用户u1
和u2
一起工作。
我运行命令
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
方法,但如果我能让它工作,它似乎很方便。如果你需要更多的信息,请问我。谢谢你的帮助!
follower_id
是Relationship
上的一个字段。当你调用u1.followers.build
时,你正在构建一个没有follower_id
列的User
。由于您使用的是attr_accessible
,因此rails不会让您知道该列不存在,它只是告诉您无权访问它。(这从安全的角度来看是很好的。)
无论如何,看起来你想做的是:
u1.relationships.build(:follower_id => u2.id)
或者
u1.followers << u2
(对于您所展示的代码,我不能100%确定第二种情况将在我的头部类型上工作—您可能需要进一步调整attr_accessible以使第二种方法工作。第一个肯定可以。)