2014-07-22 64 views
1

我在另一个模型控制器中构建模型的实例。所有似乎都正常工作,子实例很好地创建与父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 

回答

2

所以验证协会的存在是有点棘手。在你的情况下,你将mission_id验证器放在子关联上,但是在保存mission之前,rails会在planned_time上运行验证,因此它将失败,因为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还),如果没有任务对象,验证将失败。很好,现在我们知道如果没有其父mission对象存在,我们不能创建planned_time。但是这并没有说明mission要求创建planned_time。如果这是你想要的,那就是解决方案。虽然我仍然想知道你是否真的想要它,你想确保一个mission总是与planned_time一起创建?

+0

好的我现在明白了。谢谢。我想创建一个有或没有计划时间的任务,但计划时间应该始终有一个任务。 – Antoine