我在另一个模型控制器中构建模型的实例。所有似乎工作正常,子实例使用父ID很好地创建,但只要我在此资源中添加parent_id的验证,实例就不再有效。知道我错过了什么吗?
任务模型:
class Mission < ActiveRecord::Base
has_many :planned_times
validates :code, presence: true, uniqueness: { case_sensitive: false }
validates :days_sold, presence: true
end
PlannedTime模型:
class PlannedTime < ActiveRecord::Base
belongs_to :mission
validates :date, presence: true
validates :mission_id, presence: true # this is the validation which causes problem
end
任务控制员:
class MissionsController < ApplicationController
def create
@mission = Mission.new(mission_params)
week_nums = params[:weeks].split(/[\s]*[,;\-:\/+][\s]*/).uniq
year = params[:year].to_i
week_nums.each do |week_num|
date = Date.commercial(params[:year].to_i,week_num.to_i)
@mission.planned_times.build(date: date)
end
if @mission.save
flash.now[:success] = "Mission added"
end
end
private
def mission_params
params.require(:mission).permit(:code, :days_sold)
end
end
答案 0 :(得分:2)
因此验证关联的存在有点棘手。在您的情况下,您将mission_id
验证程序放在子关联上,但rails会在保存planned_time
之前在mission
上运行验证,因此它会失败,因为mission_id
仍然是nil
。此外,通过在planned_time
上进行验证,它意味着如果您从未mission.planned_items.build
,则验证将无法运行,因为相关的planned_time
不存在并且因此不能运行其验证。
只需对代码或验证逻辑进行最少的更改,就可以使其工作如下:
class PlannedTime < ActiveRecord::Base
belongs_to :mission
validates :mission_id, presence: { if: ->(p) { p.mission.nil? } }
end
此部分presence: { if: ->(p) { p.mission.nil? } }
将检查是否存在mission
对象(尽管还没有id
),如果没有任务对象,则验证将失败。非常好,现在我们知道如果没有父planned_time
个对象,我们就无法创建mission
。但这并没有说明mission
需要创建planned_time
。如果这是你想要的,那就是解决方案。虽然我想知道你是否真的想要它,但要确保mission
始终与planned_time
一起创建?