rails 5 обновляет атрибут, только если он в настоящее время ноль - PullRequest
0 голосов
/ 03 ноября 2018

Какой предпочтительный способ в Rails 5 с activerecord обновлять атрибут, только если он в настоящий момент равен nil.

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

Ответы [ 3 ]

0 голосов
/ 03 ноября 2018

Звучит так, как будто вы говорите, что хотите изменить поведение того или иного атрибута, чтобы он тихо игнорировал вас. Я думаю, что инстинкт, почему вы хотите запечатать это, является разумным, но если вы подумаете об этом немного больше, вы можете подумать, что если вы будете делать такие вещи во многих местах, то использование ваших объектов начнет сбивать с толку, особенно для кого-то, кто плохо знает код.

Возможно, вы хотите сделать это, потому что есть другой код, использующий модель Car, который хочет устанавливать соединения, но на самом деле не имеет полной картины, поэтому он пробует вещи, которые вы хотите выполнить только в первый раз. Гораздо лучше обрабатывать такие операции исключительно внутри класса, который имеет полную картину, такую ​​как модель автомобиля или объект обслуживания.

Если вы все еще действительно хотите контролировать это «связывающее» поведение вне автомобиля, тогда вы можете полностью переопределить attr_writer в классе Car. Я определенно рекомендую делать это с обратным вызовом 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 в ruby.

0 голосов
/ 04 ноября 2018

это мое понимание вашего вопроса.

  • Автомобиль может обновляться, только если connected_at равен nil

    class Car < ApplicationRecord
        before_save :updatable?
    
        def updatable?
            connected_at.blank?
        end
    end
    

Точка возврата false, когда before_save.

0 голосов
/ 03 ноября 2018

Вы можете просто проверить на # ноль?

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

OR

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'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...