使用has_one / belongs_to关系,我似乎无法通过批量分配更新嵌套记录。
模型:
class ProductVariation
include Mongoid::Document
has_one :shipping_profile, :inverse_of => :variation
field :quantity
attr_accessible :shipping_profile_attributes
accepts_nested_attributes_for :shipping_profile
end
class ShippingProfile
include Mongoid::Document
belongs_to :variation, :class_name => "ProductVariation"
field :weight, :type => Float
attr_accessible :weight
end
控制器:
@variation = ProductVariation.find(params[:id])
@variation.update_attributes(params[:product_variation])
发布请求:
Parameters:{
"product_variation"=>{
"quantity"=>"13",
"shipping_profile_attributes"=>{
"weight"=>"66",
"id"=>"4dae758ce1607c1d18000074"
}
},
"id"=>"4dae758ce1607c1d18000073"
}
mongo查询:
MONGODB app_development['product_variations'].update({"_id"=>BSON::ObjectId('4dae758ce1607c1d18000073')}, {"$set"=>{"quantity"=>13, "updated_at"=>2011-04-28 06:59:17 UTC}})
如果product_variation没有任何更改的属性,我甚至不会获得mongo更新查询...我在这里缺少什么?
答案 0 :(得分:2)
下面的工作模型和单元测试证明您可以更新子参数并保存到数据库 通过 accepts_nested_attributes_for 和 autosave:true 选项通过父级进行关系。
Mongoid文档说,尝试通过质量分配设置受保护字段会引发错误, 但这已经过时了。 而是将以下消息打印到日志文件中。
WARNING: Can't mass-assign protected attributes: id
您应该在相应的日志文件中仔细查找这些消息,以诊断您的问题。 这将帮助您注意到参数中的运输配置文件具有嵌套ID字段, 这似乎也会导致重量被拒绝,可能还有所有子参数。 将“attr_accessible:id”添加到ShippingProfile模型后,现在可以分配权重。 您还需要将“attr_accessible:quantity”(我已添加:单元测试的id)添加到ProductVariation模型
下一个问题是你需要在has_one关系后附加“autosave:true” 为了让孩子通过父母更新, 否则你将不得不手动保存孩子。
您可能也对 sanitize_for_mass_assignment 感兴趣,可以用来清除ID。
include ActiveModel::MassAssignmentSecurity
p sanitize_for_mass_assignment(params['product_variation'], :default)
单元测试应该使整个主题清晰,我将让控制器工作。 希望这很清楚,并且有所帮助。
class ProductVariation
include Mongoid::Document
has_one :shipping_profile, :inverse_of => :variation, autosave: true
field :quantity
accepts_nested_attributes_for :shipping_profile
attr_accessible :id
attr_accessible :quantity
attr_accessible :shipping_profile_attributes
end
class ShippingProfile
include Mongoid::Document
belongs_to :variation, :class_name => "ProductVariation"
field :weight, :type => Float
attr_accessible :id
attr_accessible :weight
end
测试/单元/ product_varitation_test.rb
require 'test_helper'
class ProductVariationTest < ActiveSupport::TestCase
def setup
ProductVariation.delete_all
ShippingProfile.delete_all
end
test "mass assignment" do
params = {
"product_variation"=>{
"quantity"=>"13",
"shipping_profile_attributes"=>{
"weight"=>"66",
"id"=>"4dae758ce1607c1d18000074"
}
},
"id"=>"4dae758ce1607c1d18000073"
}
product_variation_id = params['id']
shipping_profile_id = params['product_variation']['shipping_profile_attributes']['id']
product_variation = ProductVariation.create("id" => product_variation_id)
shipping_profile = ShippingProfile.create("id" => shipping_profile_id)
product_variation.shipping_profile = shipping_profile
assert_equal(1, ProductVariation.count)
assert_equal(1, ShippingProfile.count)
product_variation.update_attributes(params['product_variation'])
assert_equal('13', ProductVariation.find(product_variation_id)['quantity'])
assert_equal(66.0, ShippingProfile.find(shipping_profile_id)['weight'])
p ProductVariation.find(product_variation_id)
p ShippingProfile.find(shipping_profile_id)
end
end
测试输出
Run options: --name=test_mass_assignment
# Running tests:
#<ProductVariation _id: 4dae758ce1607c1d18000073, _type: nil, quantity: "13">
#<ShippingProfile _id: 4dae758ce1607c1d18000074, _type: nil, variation_id: BSON::ObjectId('4dae758ce1607c1d18000073'), weight: 66.0>
.
Finished tests in 0.014682s, 68.1106 tests/s, 272.4424 assertions/s.
1 tests, 4 assertions, 0 failures, 0 errors, 0 skips
Process finished with exit code 0