特定场景的模型验证,Rails

问题描述 投票:0回答:1

我使用的日历 gem 使用

start_time
表示日期 (YYYY-MM-DD)。

出于示例目的,我有

Meeting
,它具有
start_time
字符串和
postponed
布尔属性。

@meeting.start_time
必须至少是未来一天(后天),但如果
start_time
,则无法设置新的
@meeting.postponed
(会议日期),仅当
@meeting.postponed == false

此外,如果

@meeting.postponed
,则无法在不设置新的
@meeting.start_time
(即至少未来一天)的情况下取消推迟。

我想要验证,因此在更新会议时(如果

@meeting
之前被推迟),我想取消选择
@meeting.postponed
复选框并在表单中提交新的
@meeting.start_date
,并让它在同一提交中通过。

如果在控制器中,类似:

@meeting.attributes = meeting_params

if @meeting.start_time != "" && @meeting.start_time != nil
  if @meeting.start_time_changed?
    if @meeting.posteponed
      @error = "Can't change the Meeting Date if the Meeting is still postponed."
    else
      if @meeting.start_time.to_date <= Date.today
        @error = "Meeting must be at least one day in the future."
      end
    end
  else
    if @meeting.postponed_changed? && @meeting.postponed == false
      @error = "You can't un postpone the Meeting without setting a new Meeting Date."
    end
  end
else
  @error = "Meeting Date cannot be blank."
end

如何通过验证来做到这一点?

ruby-on-rails validation model
1个回答
0
投票

不要将模型的所有业务逻辑集中到一个疯狂的条件分支树中,而是对每个方面使用单独的验证。我认为你实际上把它复杂化了。

您可以使用

on:
选项控制何时触发验证,编写自定义验证器就像创建方法并使用
validate :method_name
一样简单。如果您想创建更复杂的验证器,请创建一个 validator 类

class Meeting
  validates :start_time, presence: true
  validates :start_time_must_be_in_future, 
    if: :start_time?, # prevents a nil error
    unless: :postponed?,
    on: :create       
  validates :start_time_cannot_change_when_postponed,
    if: :postponed?
    on: :update

  private

  def start_time?
    !start_time.nil?
  end

  def start_time_must_be_in_future
    errors.add(
      :start_time,
      "Meeting must be at least one day in the future."
    ) if start_time.to_date <= Date.today 
  end

  def start_time_cannot_change_when_postponed
    errors.add(
      :start_time,
      "Can't change the Meeting Date if the Meeting is still postponed."
    ) if will_save_change_to_start_date?
  end
end

有诸如 validates_timeiness 之类的宝石可以使时间验证变得不那么繁重。

© www.soinside.com 2019 - 2024. All rights reserved.