Rails: Как я могу называть `self.save` в моей модели и сохранять ее в базе данных?

Я пытаюсь сохранить модельную логику в своей модели, но я не могу заставить ее выполнять модификации сам по себе и сохранять их в базе данных.

В моем контроллере:

@article.perform_some_calulcations!

В моей модели:

def perform_some_calculations!
  self.foo.gsub!(/regexp/, 'string')
  self.save
end

Если я отбрасываю операторы debugger в свой метод и после моего вызова к нему в контроллере, @article.foo имеет правильное значение. Однако, когда я продолжаю, он не сохраняется в базе данных, и webrick не сообщает никаких операторов UPDATE.

Что пойдет не так? Я не знаю, должен ли я когда-либо делать это раньше, но верно ли это возможно?

Ответ 1

Ваша проблема заключалась в том, что если вы измените атрибут "на месте", это означает: без присвоения ему нового значения, тогда Rails будет думать, что нет ничего нового для сохранения, поэтому он "оптимизирует" сохранение.

Каждый атрибут записи вашего атрибута будет устанавливать флаг, поэтому метод сохранения будет знать, что он должен проверить, действительно ли текущее значение отличается от значения, считанного из базы данных. Вот почему self.foo = self.foo.gsub(/regexp/, 'string') работает (обратите внимание, что восклицательный знак здесь не нужен).

Если вам нужно изменить атрибут "на месте", например, с помощью gsub! или replace, используйте:

def perform_some_calculations!
  foo_will_change!
  self.foo.gsub!(/regexp/, 'string')
  self.save
end

Ответ 2

Ваши атрибуты могут быть защищены. Проверьте свой журнал. Если это так, то

self.save! 

или

self.save(false)

попробуйте снять восклицательный знак с вашего определения.


self.foo = self.foo.gsub!(/regexp/, 'string')