在具有activerecord的Rails 5中,只有在当前为零的情况下更新属性的首选方法是什么。
car = Car.first
car.connected_at = Time.zone.now
car.save
OR
car = Car.first
car.update!(connected_at: Time.zone.now)
it should update only if car.connected_at is nil发布于 2018-11-02 22:26:39
您可以简单地检查一下#零?
car = Car.first
car.update_attribute(:connected_at, Time.zone.now) if car.connected_at.nil?这还不够普遍。我想要一些像before_validation之类的东西。我只是不确定哪条路是首选的。
好吧,如果你想进行验证的话,应该是这样的..
before_save :validate_connected_at
private
def validate_connected_at
connected_at = connected_at_was if connected_at_changed? && connected_at_was.present?
end或
before_save :set_connected_at
private
def set_connected_at
connected_at = Time.zone.now if connected_at.nil?
end正如你所看到的,更多的检查,更多的方法。我肯定会选第一个。
但是,如果要添加错误消息,则如下所示
errors.add(:connected_at, 'Already present!')那么,"#{attr}_was“在before_save方法中所有定义的吸引子上都是可用的?
它们一般都是可用的,而不仅仅是在before_save中,例如在控制台中。
car = Car.first
car.connected_at
=> 'some value'
car.connected_at = 'some other value'
car.connected_at
=> 'some other value'
car.connected_at_was
=> 'some value'发布于 2018-11-02 23:39:14
听起来你是在说你想要修改一个特定属性的行为,所以它会悄悄地忽略你。我认为,你为什么要封闭它的本能是合理的,但如果你再多想一想,你可能会认为,如果你在很多地方做这样的事情,那么使用你的对象就会开始变得混乱,特别是对那些不熟悉代码的人来说。
也许你想这样做,因为还有其他代码使用的汽车模型,希望建立连接,但实际上没有完整的图片,所以它尝试的东西,你只想要成功的第一次。最好只在具有全貌的类(如Car模型或服务对象)中处理此类操作。
如果您仍然想控制这个“连接”行为,那么您可以在Car类中完全覆盖attr_writer。不过,我肯定会建议在before_save回调中这样做。
def connected_at=(new_value)
if @connected_at
raise StandardError, 'connected_at has already been set'
end
@connected_at = new_value
end无论您以何种方式分配值,这都是可行的。如果您想知道上面发生了什么,请阅读一下红宝石中的attr_accessor。
发布于 2018-11-04 14:11:42
这是我对你问题的理解。
connected_at是nil时才能更新
类型车< ApplicationRecord before_save :可更新?可更新的?connected_at.blank?端端重点是当false返回before_save时。
https://stackoverflow.com/questions/53126500
复制相似问题