Question

Question on mass assignment through nested attributes using mongoid.

Example:

require 'mongoid'
require 'mongo'

class Company
  include Mongoid::Document

  has_many :workers,as: :workable, autosave: true
  accepts_nested_attributes_for :workers
end

class Worker
  include Mongoid::Document
  field :hours, type: Integer, default: 0
  belongs_to :workable, polymorphic: true
end

class Manager < Worker
  include Mongoid::Document
  field :order
  #attr_accessible :order
  attr_accessor :order

  validates_presence_of :order
end

Mongoid.configure do |config|
  config.master = Mongo::Connection.new.db("mydb")
end
connection = Mongo::Connection.new
connection.drop_database("mydb")
database = connection.db("mydb")

params = {"company" => {"workers_attributes" => {"0" => {"_type" => "Manager","hours" => 50, "order" => "fishing"}}}}
company = Company.create!(params["company"])
company.workers.each do |worker|
  puts "worker = #{worker.attributes}"
end

This outputs the following:

worker = {"_id"=>BSON::ObjectId('4e8c126b1d41c85333000002'), "hours"=>50, "_type"=>"Manager", "workable_id"=>BSON::ObjectId('4e8c126b1d41c85333000001'), "workable_type"=>"Company"}

If the commented out line

attr_accessible :order 

is commented in I instead get the following:

WARNING: Can't mass-assign protected attributes: _type, hours
worker = {"_id"=>BSON::ObjectId('4e8c12c41d41c85352000002'), "hours"=>0, "_type"=>"Manager", "workable_id"=>BSON::ObjectId('4e8c12c41d41c85352000001'), "workable_type"=>"Company"}

Notice how the hours value is not updated from the default.

Question, why does commenting in attr_accessible mess up my document's persistence. Also I am new to rails and I do not fully understand attr_accessible but I know I need it to fill in fields through my view. How can I get my document to persist using the attr_accessible line commented in?

Thanks

Was it helpful?

Solution

First of all check the API docs for your explanation on attr_accessible here. That should provide you with a more thorough understanding.

Secondly, you are using attr_accessor for order which you do not need because it is a database field.

Lastly, you need to set attr_accessible :workers_attributes on your company model. This allows the :workers_attributes hash that is created by the accepts_nested_attributes_for to be persisted through mass assignment.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top