Должен ли метод модели вызывать саму себя? - PullRequest
11 голосов
/ 09 октября 2010

Допустим, у нас есть метод внутри модели, который

  1. должен вызываться только для сохраненных записей.
  2. может обновить саму модель и, следовательно, модель должна быть сохранена сноваafterwords

Если вызовы "save" происходят внутри самого метода, как показано в следующем коде

def result
  save! if new_record?

  # do some funky stuff here that may also change the model state
  # ...
  # And calculate the return value
  search_result = "foo" # Let's say "foo" is the value we calculated

  save! if changed?
  search_result # return
end

Или внешний наблюдатель (контроллер) должен отвечать за вызов save при необходимости

Ответы [ 3 ]

4 голосов
/ 19 февраля 2013

Определенно бывают моменты, когда модели необходимо сохраняться.Но стоит подумать, является ли save лучшим методом для вашего приложения.

В текущем примере у нас есть модель, которая обрабатывает файл асинхронно в долговременном методе (мы вращаемсяпроцесс отключен с помощью sidekiq.) Внутри метода постоянный атрибут регулярно обновляется, поэтому информация о состоянии доступна для других запросов.

Мы используем update_column вместо save, потому что

  1. Нам не нужны или не нужны служебные данные обратных вызовов AR, и мы особенно хотим пропустить проверку, чтобы убедиться, что обновление происходит надежно и немедленно.
  2. Нам нужно обновить только один атрибут.Использование update_column избавляет от необходимости определять, нужно ли сохранять (или не сохранять) какие-либо другие атрибуты.

Внутри модели такие методы, как

  • update_column
  • save (: validate => false) (предоставлено, тот же метод, но разные параметры)
  • touch

и т. Д. Часто может быть более подходящим способом сохранения изменений, чем обычный save .

4 голосов
/ 09 октября 2010

Если ваш метод действительно, действительно должен все это делать, пусть будет так.

Однако я бы пояснил, посмотрев на метод, почему вы это делаете (комментарии могут быть хорошими здесь)и определенно сделает это bang_method!, так что любому, кто его призовет, станет ясно, что этот метод может связываться с объектом столько, сколько ему хочется.имя метода result (которое, я знаю, вероятно, не ваше настоящее имя метода) в некоторой степени подразумевает, что вы просто извлекаете данные, и немного больше.Возможно, load_result! было бы более уместным, чтобы было яснее, что вы не просто обращаетесь к атрибуту, но фактически выполняете тяжелые операции для его получения.

2 голосов
/ 09 октября 2010

Когда программа сохраняет данные в файле?

a) Только когда это требуется пользователю (прямо или косвенно)?- это случай контроллера

б) Только когда программа достигает части своей корректности и целостности данных?- это пример модели

c) Оба.

Я бы проголосовал за (c).Я надеюсь, что это различение немного исправляет ситуацию.

Кроме того, с точки зрения объектно-ориентированного проектирования метод save () принадлежит публичному контракту своего класса;это может быть вызвано любым.Учитывая это, класс отвечает за свой публичный контракт и, при необходимости, объект может вызывать свои собственные методы по своему желанию.

...