Должен ли я предотвратить редактирование записи с использованием фильтра в моем контроллере или обратного вызова в моей модели? - PullRequest
3 голосов
/ 11 февраля 2011

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

Я всегда реализовывал это в контроллере, например, так (псевдо-код):

def ProductsController < ApplicationController
  before_filter require_product_not_sold, :only => [ :write_off ]

private
  def require_product_not_sold
    if @product.sold?
      redirect_to @product, :error => "You can't write off a product that has been sold"
    end
  end
end

Меня просто поразило, что я тоже могу сделать это в модели.Примерно так:

def Product < ActiveRecord::Base
  before_update :require_product_not_sold

private
  def require_product_not_sold
    if self.written_off_changed?
      # Add an error, fail validation etc. Prevent the model from saving
    end
  end
end

Также учтите, что может быть несколько разных событий, которые требуют, чтобы продукт не был продан, чтобы иметь место.

Мне нравится подход контроллера - вы можете установитьзначимые флеш-сообщения вместо добавления ошибок валидации.Но кажется, что этот код должен быть в модели (например, если я хотел использовать модель вне моего приложения Rails).

  1. Я делаю это неправильно?
  2. Что такоепреимущества обработки этого в моей модели?
  3. Каковы недостатки обработки этого в моей модели?
  4. Если я обращаюсь с этим в модели, я действительно должен использовать validates вместообратный звонок?Какой самый чистый способ справиться с этим?

Спасибо за ваши идеи:)

1 Ответ

2 голосов
/ 11 февраля 2011

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

Но в этом случае вы хотите предотвратить действие до того, как пользователь даже получит доступ к модели. Использование проверки модели в этом случае означает, что вы опоздали, и пользователь уже пошел дальше, чем он должен, имея доступ и пытаясь списать продукт, который никогда не должен был быть доступным на основании его проданного статуса.

Так что я думаю, что идеальный ответ - «оба». Модель «должна» знать, как защитить себя, в качестве резервной копии и на случай, если она когда-либо будет использоваться извне.

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

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

Это то, что вы рассматривали?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...