【发布时间】:2014-05-05 15:57:14
【问题描述】:
尽管我认为正确的参数值在控制器中被列入白名单并传递给模型的构造函数,但模型对象的验证失败。我做错了什么?
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"
}
}
那么为什么在调用保存之后Location.country 值nil,为什么验证失败?
编辑:日志文件(非常简化)pastebin here。似乎正确的值正在作为 SQL 的一部分发送
【问题讨论】:
-
你能把提交表单时生成的日志贴出来吗?
-
@Babar pastebin 添加
-
@outer.location.errors返回什么? -
是的,请检查返回的错误消息
-
当我写下这个问题时,因为我认为问题在于控制器代码中的参数散列正确,因此从我粘贴的代码中简化了父类。没有人立即发现问题这一事实让我有信心考虑其他选择……谢谢!
标签: ruby validation activerecord ruby-on-rails-4