Rails 中的模型 4 验证不包含的可选关联
Model in Rails 4 validating optional associations when they are not included
我的 Rails 应用程序中有一个事件模型的嵌套表单,允许用户在事件重复发生时为重复(另一个模型)指定字段。创建事件时一切正常,但是当事件不再发生时(因此不想保存关系),它会给我更新事件的错误。我设置了重复周期以验证字段 "frequency" 是否存在。当没有重复出现时,这个字段留空,但表格仍然会退回并说频率需要在那里。帮忙?
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
来自事件控制器
def event_params
params.require(:event).permit(
:name, :start, :duration, :unit, :location, :description, :major,
recurrence_attributes: [ :frequency, :end ])
end
def update
@event = Event.find(params[:id])
if @event.recurrence && !params.has_key?(:has_recurrence)
@event.recurrence.destroy
end
if @event.update(event_params)
redirect_to event_path(@event)
else
render 'edit'
end
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
我的事件控制器中的更新如下...
def update
@event = Event.find(params[:id])
if @event.recurrence && !@has_recurrence
@event.recurrence.destroy
end
if @event.update(event_params)
redirect_to event_path(@event)
else
flash[:notice] = @event.errors
render 'edit'
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 %>
现在,当没有检查重复时,我没有收到验证错误,但重复正在保存到数据库中(除了 event_id 之外的所有内容都是空白的)
您需要条件验证和自定义属性。参见:http://edgeguides.rubyonrails.org/active_record_validations.html#conditional-validation。这样做会将验证代码从您的控制器中取出并返回到它所属的模型中。
基本上与此类似的东西(示例未测试)应该可以工作:
validates :frequency, :presence => true, :if => :has_recurrence
def has_recurrence=( yesorno=false )
@has_recurrence = yesorno
end
def has_recurrence
@has_recurrence ||= false
end
就我个人而言,我会将属性重命名为 has_recurrence?
但这只是样式。
我的 Rails 应用程序中有一个事件模型的嵌套表单,允许用户在事件重复发生时为重复(另一个模型)指定字段。创建事件时一切正常,但是当事件不再发生时(因此不想保存关系),它会给我更新事件的错误。我设置了重复周期以验证字段 "frequency" 是否存在。当没有重复出现时,这个字段留空,但表格仍然会退回并说频率需要在那里。帮忙?
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
来自事件控制器
def event_params
params.require(:event).permit(
:name, :start, :duration, :unit, :location, :description, :major,
recurrence_attributes: [ :frequency, :end ])
end
def update
@event = Event.find(params[:id])
if @event.recurrence && !params.has_key?(:has_recurrence)
@event.recurrence.destroy
end
if @event.update(event_params)
redirect_to event_path(@event)
else
render 'edit'
end
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
我的事件控制器中的更新如下...
def update
@event = Event.find(params[:id])
if @event.recurrence && !@has_recurrence
@event.recurrence.destroy
end
if @event.update(event_params)
redirect_to event_path(@event)
else
flash[:notice] = @event.errors
render 'edit'
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 %>
现在,当没有检查重复时,我没有收到验证错误,但重复正在保存到数据库中(除了 event_id 之外的所有内容都是空白的)
您需要条件验证和自定义属性。参见:http://edgeguides.rubyonrails.org/active_record_validations.html#conditional-validation。这样做会将验证代码从您的控制器中取出并返回到它所属的模型中。
基本上与此类似的东西(示例未测试)应该可以工作:
validates :frequency, :presence => true, :if => :has_recurrence
def has_recurrence=( yesorno=false )
@has_recurrence = yesorno
end
def has_recurrence
@has_recurrence ||= false
end
就我个人而言,我会将属性重命名为 has_recurrence?
但这只是样式。