在保存之前,如果属性存在,则执行操作。

3
before_save :date_started_sets_deadline, if date_started.present?

如果:date_started == nil,我不希望这个before_save运行。我尝试过上面那行代码的各种版本,所以不确定是要更改那个还是方法本身。

def date_started_sets_deadline
  if self.date_started > Date.tomorrow
    self.deadline = self.date_started
  end
end

我试图避免这个错误 NoMethodError (undefined method '>' for nil:NilClass): app/models/challenge.rb:35:in 'date_started_sets_deadline' ,每当用户尝试创建一个没有 date_started 的挑战时。

4个回答

5

before_save 语句更改为以下内容:

before_save :date_started_sets_deadline, if: :date_started?

如果您提供了一个 symbolif,那么 rails 将在实例的上下文中计算它。通过添加 ?, 这是一个自动生成的方法,本质上等同于 date_started.present?

此外,如果在 date_started_sets_deadline 实现中需要 date_started, 我还会明确添加检查,而不仅仅依赖于在回调逻辑上添加 if 条件。

def date_started_sets_deadline
  if self.date_started.present? && (self.date_started > Date.tomorrow)
    self.deadline = self.date_started
  end
end

请参考使用符号的 :if 和 :unless来获取更多信息。


1

一种方法是在方法内部放置一个条件if语句。

def date_started_sets_deadline
  if self.date_started != nil 
    if self.date_started > Date.tomorrow
     self.deadline = self.date_started
    end
  end
end

编辑

尝试这个,我在个人项目上进行了检查。

before_save :date_started_sets_deadline, if: self.date_started.present?


刚刚进行了修改,请让我知道是否有效,使用present?方法。 - Zaid Qureshi
请检查最新的版本,我刚在个人项目中做了类似的事情。 - Zaid Qureshi

1

另一个答案提到提供要调用的符号,我建议创建自己的方法来成为该符号,以便您可以包含所有感兴趣的条件,例如。

before_save :set_deadline, if: :starts_after_tomorrow?

def starts_after_tomorrow?
  date_started? && date_started > Date.tomorrow
end

def set_deadline
  self.deadline = date_started
end

我认为这比在before_save和setter中重复逻辑要干净得多。


0

您可以在回调方法中检查条件并更改数据。

before_save :date_started_sets_deadline

def date_started_sets_deadline
  if date_started.present? && self.date_started > Date.tomorrow
   self.deadline = self.date_started
  end
end

但我认为将这些职责分开是个好主意。例如,您可以将检查移动到另一个方法中。

before_save :set_deadline, if: :set_deadline?

def set_deadline?
  date_started.present? && date_started > Date.tomorrow
end

def set_deadline
  self.deadline = date_started
end

对于简单的条件,很难找到好的方法名称,或者感觉有点过度设计,因此您可以使用procs和lambdas直接在回调定义中进行检查。但是您应该小心使用。

before_save :set_deadline, if: ->() { date_started.present? }

def set_deadline
  self.deadline = date_started if self.date_started > Date.tomorrow
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接