对模型对象的验证失败,尽管我认为正确的参数值在控制器中列入白名单并传递给模型的构造函数。我做错了什么?
OuterModel
has_one Location
通过locatable
。后者是使用accepts_nested_attributes_for
创建的,仅验证:country
属性:
(编辑:我发现了错误,它被代码隐藏了,我最初在代码中省略了这些以简化。请参阅下面的答案)
class OuterModel < Parent
has_one :location, as: locatable
accepts_nested_attributes_for :location
end
class Parent < ActiveRecord::Base
after_create :create_location
end
class Location < ActiveRecord::Base
belongs_to :locatable, polymorphic: true
validates :country, inclusion: {in: ["US", "CA"]}
end
控制器:
class OuterModelsController < ApplicationController
def create
@outer = OuterModel.new(outer_params)
if @outer.save
byebug #debug here
redirect_to outer_path(@outer)
end
end
def outer_params
params.require(:outer).permit(:name, :type,
location_attributes: [:country, :state, :city])
end
end
使用byebug我看到@outer.save
调用已满足,但由于验证错误,嵌套的位置对象未被保留:
(byebug) @outer.persisted? #true
(byebug) @outer.location.persisted? #false
(byebug) @outer.location.valid? #false
(byebug) @outer.location.country #nil
(byebug) @outer.id #6372
(byebug) @outer.location.errors
<ActiveModel::Errors:0x007f1f33c1eae0
@base=#<Location id: nil, city: nil, country: nil, state: nil, locatable_id: 6732, locatable_type: "OuterModel", created_at: nil, updated_at: nil>,
@messages={:country=>["is not included in the list"]}>
但是,控制器outer_params方法似乎正在向OuterModel.new
发送正确的哈希:
{"name"=>"A name",
"type"=>"OuterModel",
"location_attributes"=>{
"city"=>"South Deionview", "country"=>"US", "state"=>"IL"
}
}
为什么调用save之后Location.country
值为nil
,为什么验证失败?
编辑:logfile(简化)pastebin here。似乎正确的值是作为SQL
的一部分发送的答案 0 :(得分:0)
答案在于OuterModel的父级,它具有after_create
钩子来创建位置。将父类添加到上面的源中。
最初由accepts_nested_attributes_for
正确创建了Location对象(根据日志记录中的所有证据),但是after_create挂钩将其替换为验证失败的空Location对象。