before_save :date_started_sets_deadline, if date_started.present?
如果before_save
,我不希望此:date_started == nil
运行。我已经尝试了上面这一行的各种版本,所以不确定我是否必须改变它或方法本身。
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
答案 0 :(得分:4)
将before_save
语句更改为以下内容:
before_save :date_started_sets_deadline, if: :date_started?
如果您向symbol
提供if
,则rails
会对其进行评估
在实例的上下文中。通过添加?
,它是一个自动生成的方法,与date_started.present?
基本相同。
此外,如果date_started
实现中需要date_started_sets_deadline
,我还会明确添加检查,而不是仅仅依赖于在回调逻辑上添加if
条件。
def date_started_sets_deadline
if self.date_started.present? && (self.date_started > Date.tomorrow)
self.deadline = self.date_started
end
end
有关详细信息,请参阅Using :if and :unless with a Symbol。
答案 1 :(得分:1)
这样做的一种方法是在方法中添加条件。
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?
答案 2 :(得分: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中重复逻辑要清晰得多。
答案 3 :(得分: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