质量分配exception没有找到解释(Rails 3.2.1)

请看这篇文章 。

注意:当前rake任务在设置post对象时保存User和Topic对象,但不保存post或标签。

问题:在我的rake任务(如下所示)中描述这种关系的正确方法是什么,这样它就不会抛出一个无法分配属性的exception?

这是我的步骤:

第1步:创建模型

class Post < ActiveRecord::Base belongs_to :topic, inverse_of: :posts has_and_belongs_to_many :tags attr_accessible :title, :description, :content, :tags_attributes accepts_nested_attributes_for :tags, allow_destroy: true, reject_if: lambda {|attrs| attrs.all? {|key, value| value.blank?}} end class Tag < ActiveRecord::Base has_and_belongs_to_many :posts attr_accessible :tag_name #UPDATE end class Topic < ActiveRecord::Base has_many :posts, inverse_of: :topic attr_accessible :topic_name, :posts_attributes accepts_nested_attributes_for :posts, allow_destroy: true, reject_if: lambda {|attrs| attrs.all? {|key, value| value.blank?}} end 

因此,我的Post模型是Topic一个孩子,Post与Tags有HABTM关系。

第2步:创建rake任务

 namespace :db do desc "Fill database with sample data" task :posts => :environment do Rake::Task['db:reset'].invoke make_users make_topics make_posts end end def make_users puts "making users" + "..." 5.times do |n| name = Faker::Name.name password = "foo" email = "example-#{n+1}@example.com" user = User.create!( codename: name, email: email, password: password, password_confirmation: password) end end def make_topics puts "making topics"+"..." 3.times do t = Faker::Lorem.words(1) topic = Topic.create!(topic_name: t) end end def make_posts puts "making posts" + "..." User.all(limit: 3).each do |user| Topic.all.each do |topic| 10.times do content = Faker::Lorem.paragraphs(3) description = Faker::Lorem.words(10) title = Faker::Lorem.words(4) tag_1 = Faker::Lorem.words(1) tag_2 = Faker::Lorem.words(1) tag_3 = Faker::Lorem.words(1) post = user.posts.create!(title: title, posts_attributes: [{topic_name: @topic}], description: description, content: content, tags_attributes: [{tag_name: tag_1}, {tag_name: tag_2}, {tag_name: tag_3}]) end end end 

结束

第3步:现在运行rake任务

 ... making users... making posts... rake aborted! Can't mass-assign protected attributes: posts_attributes ... ... /lib/tasks/make_posts.rake:45:in `block (3 levels) in make_posts' /lib/tasks/make_posts.rake:38:in `times' /lib/tasks/make_posts.rake:38:in `block (2 levels) in make_posts' /lib/tasks/make_posts.rake:36:in `each' /lib/tasks/make_posts.rake:36:in `block in make_posts' /lib/tasks/make_posts.rake:35:in `each' /lib/tasks/make_posts.rake:35:in `make_posts' /lib/tasks/make_posts.rake:7:in `block (2 levels) in ' ... ... 

既然我无法完成我的rake任务,我进入了控制台,这是错误:

 Topic Load (1.5ms) SELECT "topics".* FROM "topics" LIMIT 1 => # irb(main):007:0> topic.posts_attributes = {"1"=>{tag_name:"hammer time"}} ActiveModel::MassAssignmentSecurity::Error: Can't mass-assign protected attributes: tag_name from /home/rhodee/.rbenv/versions/1.9.3-p0/lib/ruby/gems/1.9.1/gems/activemodel-3.2.1/lib/active_model/mass_assignment_security/sanitizer.rb:48:in `process_removed_attributes' from /home/rhodee/.rbenv/versions/1.9.3-p0/lib/ruby/gems/1.9.1/gems/activemodel-3.2.1/lib/active_model/mass_assignment_security/sanitizer.rb:20:in `debug_protected_attribute_removal' from /home/rhodee/.rbenv/versions/1.9.3-p0/lib/ruby/gems/1.9.1/gems/activemodel-3.2.1/lib/active_model/mass_assignment_security/sanitizer.rb:12:in `sanitize' from /home/rhodee/.rbenv/versions/1.9.3-p0/lib/ruby/gems/1.9.1/gems/activemodel-3.2.1/lib/active_model/mass_assignment_security.rb:228:in `sanitize_for_mass_assignment' from /home/rhodee/.rbenv/versions/1.9.3-p0/lib/ruby/gems/1.9.1/gems/activerecord-3.2.1/lib/active_record/attribute_assignment.rb:75:in `assign_attributes' from /home/rhodee/.rbenv/versions/1.9.3-p0/lib/ruby/gems/1.9.1/gems/activerecord-3.2.1/lib/active_record/base.rb:495:in `initialize' from /home/rhodee/.rbenv/versions/1.9.3-p0/lib/ruby/gems/1.9.1/gems/activerecord-3.2.1/lib/active_record/reflection.rb:183:in `new' from /home/rhodee/.rbenv/versions/1.9.3-p0/lib/ruby/gems/1.9.1/gems/activerecord-3.2.1/lib/active_record/reflection.rb:183:in `build_association' from /home/rhodee/.rbenv/versions/1.9.3-p0/lib/ruby/gems/1.9.1/gems/activerecord-3.2.1/lib/active_record/associations/association.rb:233:in `build_record' from /home/rhodee/.rbenv/versions/1.9.3-p0/lib/ruby/gems/1.9.1/gems/activerecord-3.2.1/lib/active_record/associations/collection_association.rb:112:in `build' from /home/rhodee/.rbenv/versions/1.9.3-p0/lib/ruby/gems/1.9.1/gems/activerecord-3.2.1/lib/active_record/nested_attributes.rb:405:in `block in assign_nested_attributes_for_collection_association' from /home/rhodee/.rbenv/versions/1.9.3-p0/lib/ruby/gems/1.9.1/gems/activerecord-3.2.1/lib/active_record/nested_attributes.rb:400:in `each' from /home/rhodee/.rbenv/versions/1.9.3-p0/lib/ruby/gems/1.9.1/gems/activerecord-3.2.1/lib/active_record/nested_attributes.rb:400:in `assign_nested_attributes_for_collection_association' from /home/rhodee/.rbenv/versions/1.9.3-p0/lib/ruby/gems/1.9.1/gems/activerecord-3.2.1/lib/active_record/nested_attributes.rb:288:in `posts_attributes=' from (irb):7 from /home/rhodee/.rbenv/versions/1.9.3-p0/lib/ruby/gems/1.9.1/gems/railties-3.2.1/lib/rails/commands/console.rb:47:in `start' from /home/rhodee/.rbenv/versions/1.9.3-p0/lib/ruby/gems/1.9.1/gems/railties-3.2.1/lib/rails/commands/console.rb:8:in `start' from /home/rhodee/.rbenv/versions/1.9.3-p0/lib/ruby/gems/1.9.1/gems/railties-3.2.1/lib/rails/commands.rb:41:in `' from script/rails:6:in `require' from script/rails:6:in `'irb(main):008:0> 

为什么要将user.posts.create传递给user.posts.create ? 在我看来,你想要创建一个包含很多post的主题 ,在这种情况下你应该改为使用user.topics.create