Ruby on rails 4 Rails 4中的模型验证未包含的可选关联

Ruby on rails 4 Rails 4中的模型验证未包含的可选关联,ruby-on-rails-4,nested-forms,Ruby On Rails 4,Nested Forms,我的Rails应用程序中有一个事件模型的嵌套表单,允许用户在事件递归时指定重复字段(另一个模型)。创建事件时一切正常,但当事件不再发生时(因此不希望保存关系),更新事件时会出现错误。我已设置重复,以验证字段“频率”是否存在。当没有重复出现时,此字段留空,但表单仍会返回并表示频率需要存在。帮忙 class Event < ActiveRecord::Base has_one :recurrence accepts_nested_attributes_for :recurrence e

我的Rails应用程序中有一个事件模型的嵌套表单,允许用户在事件递归时指定重复字段(另一个模型)。创建事件时一切正常,但当事件不再发生时(因此不希望保存关系),更新事件时会出现错误。我已设置重复,以验证字段“频率”是否存在。当没有重复出现时,此字段留空,但表单仍会返回并表示频率需要存在。帮忙

class Event < ActiveRecord::Base
  has_one :recurrence
  accepts_nested_attributes_for :recurrence
end

class Recurrence < ActiveRecord::Base
  belongs_to :event
  validates :frequency, :presence => true
end
您会注意到,它正在检查是否存在名为“has_recurrence”的参数-这是我在表单中的复选框标记,位于模型之外,用于确定是否应为事件保存定期。如果用户选中该复选框,表单将尝试保存重复,但如果用户不选中该复选框,表单将不会保存重复(至少这是想法)

问题在于,当我提交表单以编辑事件时,如果该事件不是重复发生的,并且未选中“has_recurrence”框,它仍会尝试验证该重复发生,并返回一个验证错误:

Recurrence frequency can't be blank
更新 我已根据以下答案更新了我的重复模型,以有条件地进行验证:

class Recurrence < ActiveRecord::Base
  belongs_to :event

  validates :frequency, :presence => true, :if => :has_recurrence

  def has_recurrence=( yesorno=false )
    @has_recurrence = yesorno
  end

  def has_recurrence
    @has_recurrence ||= false
  end
end
并且该视图包含以下内容以检查是否存在重复:

<div class="form-group">
  <%= check_box_tag "has_recurrence", nil, false %> Is this a recurring event? (must check to save recurrence)
</div>
<%= f.fields_for :recurrence do |builder| %>
  <%= render 'recurrence_fields', f: builder %>
<% end %>

这是一个反复发生的事件吗?(必须选中以保存重复)

现在,当未选中“重复”时,不会出现验证错误,但重复正在保存到数据库中(除事件id外,所有内容均为空)

您需要一个条件验证和一个自定义属性。请参阅:。这样做会将验证代码从控制器中取出并返回到它所属的模型中

基本上类似于此(示例未经测试)的方法应该可以工作:

validates :frequency, :presence => true, :if => :has_recurrence

def has_recurrence=( yesorno=false )
  @has_recurrence = yesorno
end

def has_recurrence
  @has_recurrence ||= false
end

就个人而言,我会将属性重命名为
has\u recurrence?
,但这只是一种风格。

我会尝试一下。您是否有两个has_递归方法作为选项(一个或另一个),或者两者都是必需的?如果您不希望在赋值中使用=语法,您可以在一个方法中完成所有操作。但这并不是惯用的Ruby。您还可以使用
attr\u accessor
meta方法同时生成getter和setter方法,但这意味着您不能像我所做的那样在方法中设置默认值。这真的是一个品味的问题。好的-最后一个问题-我的假设是我需要在我的控制器中设置这个值,就像在@event.has\u recurrence=true,如果参数has\u key?(:has\u recurrence)-这是一个好的假设吗?还是由表单属性自动设置?当我将复选框作为表单生成器的一部分而不是单独的标记时,这终于起作用了
<div class="form-group">
  <%= check_box_tag "has_recurrence", nil, false %> Is this a recurring event? (must check to save recurrence)
</div>
<%= f.fields_for :recurrence do |builder| %>
  <%= render 'recurrence_fields', f: builder %>
<% end %>
validates :frequency, :presence => true, :if => :has_recurrence

def has_recurrence=( yesorno=false )
  @has_recurrence = yesorno
end

def has_recurrence
  @has_recurrence ||= false
end