所以我的代码库中存在以下问题。
在数据库中,有些数据不能满足验证要求。 (它不对我知道,并且将被修复,但问题仍然是为什么rails像它一样工作)
在save
操作中调用create
将对父对象运行验证并且不会保存任何内容,但是,在update
操作中调用update_attributes
或update
不会,对象将与无效的父级一起保存。
型号:
class RussianDoll < ActiveRecord::Base
validates :name, :description, presence: true
has_and_belongs_to_many :parents,
class_name: 'RussianDoll',
join_table: :russian_dolls_russian_dolls,
foreign_key: :child_id,
association_foreign_key: :parent_id
has_and_belongs_to_many :children,
class_name: 'RussianDoll',
join_table: :russian_dolls_russian_dolls,
foreign_key: :parent_id,
association_foreign_key: :child_id
end
控制器:
class RussianDollsController < ApplicationController
def create
rd_params = russian_doll_params
rd_params[:parents] = RussianDoll.where(id: params[:parent_ids])
@russian_doll = RussianDoll.new(rd_params)
respond_to do |format|
if @russian_doll.save
format.html { render 'foo' }
format.xml { render 'bar' }
else
format.html { render action: 'new' }
format.xml { render xml: @russian_doll.errors }
end
end
end
def update
@russian_doll = RussianDoll.find(params[:id])
rd_params = russian_doll_params
rd_params[:parents] = RussianDoll.where(id: params[:parent_ids])
respond_to do |format|
if @russian_doll.update(rd_params)
format.html { render 'foo' }
format.xml { render 'bar' }
else
format.html { render action: 'edit' }
format.xml { render xml: @russian_doll.errors }
end
end
end
private
def russian_doll_params
params.require(:russian_doll).permit(:name, :description)
end
end
当您尝试创建新的RussianDoll
(name
和description
)时,如果您尝试将其关联的RussianDoll
父级没有description
,则它将无法保存{ {1}}在数据库中设置。
但是,如果您在没有任何父项的情况下创建它,然后尝试通过update
操作添加父项,那么您将能够设置与RussianDoll
条目没有设置description
的关联(无效录入)。
据我所知update
应该运行所有验证,与save
操作相同,但在这种情况下它似乎不会这样做。
为什么save
验证有效,但update
个验证不起作用?
任何帮助表示赞赏!
[编辑]
所以我终于找到了根本原因......
在create
操作中,我们首先在其关联中创建已设置无效父级的@russian_doll
,因此如果我们在对象上运行.valid?
,它将失败。
但是在update
操作中,我们的@russian_doll
首先在数据库中找到,并且在.update(rd_params)
对象本身未被更改之前,因此运行.valid?
将返回true
和update
将设法将已修改的russian_doll
与无效的父级相关联。
还有什么问题,第二次update
被调用时,@russian_doll
会有来自第一个update
的无效父级,但由于某种原因.valid?
仍然存在返回true
,而不是失败。
就像验证仅适用于创建对象的所有嵌套条目...