before_save如果attribute.present?
before_save if attribute.present?
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
每当用户尝试在没有 date_started
的情况下创建挑战时,我正在努力避免错误 NoMethodError (undefined method '>' for nil:NilClass): app/models/challenge.rb:35:in 'date_started_sets_deadline'
一种方法是在方法中加入条件 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?
将 before_save
语句更改为以下内容:
before_save :date_started_sets_deadline, if: :date_started?
如果您向 if
提供 symbol
,则 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
有关详细信息,请参阅 Using :if and :unless with a Symbol。
另一个答案提到提供要调用的符号,我建议创建您自己的方法作为该符号,以便您可以包含您感兴趣的所有条件,即。
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 中重复逻辑更清晰。
您可以在回调方法中检查条件和更改数据。
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
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
每当用户尝试在没有 date_started
NoMethodError (undefined method '>' for nil:NilClass): app/models/challenge.rb:35:in 'date_started_sets_deadline'
一种方法是在方法中加入条件 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?
将 before_save
语句更改为以下内容:
before_save :date_started_sets_deadline, if: :date_started?
如果您向 if
提供 symbol
,则 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
有关详细信息,请参阅 Using :if and :unless with a Symbol。
另一个答案提到提供要调用的符号,我建议创建您自己的方法作为该符号,以便您可以包含您感兴趣的所有条件,即。
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 中重复逻辑更清晰。
您可以在回调方法中检查条件和更改数据。
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