Решения, основанные на ошибках валидации ActiveRecord - PullRequest
0 голосов
/ 09 ноября 2011

Я очень плохо знаком с рельсами, и мне интересно, что лучший способ сделать это:

У меня есть контроллер, создающий запись в базе данных.

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

Проверка моделей, которую я хочу обнаружить:

validates_uniqueness_of :title

Мой контроллер делает это:

fcs = Entity.create(:title => text)

Когда вышеупомянутая ошибка не удается, у меня есть коллекция ошибок ActiveModel для работы.

Как мне надежно установить флаг впрограммно указать, что заголовок был взят?

До сих пор я рассмотрел

fcs.errors.messages.has_key?(:title)

Но это вернет истину, если заголовок потерпел неудачу по какой-то другой причине.Поэтому мне нужно что-то более похожее на:

fcs.errors.messages[:title]==["has already been taken"]

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

Так кто-нибудь знает, как это сделатьс RoR?

Спасибо за любой совет

edit: Пример использования предложенного флага "is_title_duplicated":

if(! fcs.errors.empty?)
      json['success']=false
      json['errors']=fcs.errors.full_messages
      json['title_was_duplicate'] = is_title_duplicated
      render :json => json

...

Ответы [ 2 ]

2 голосов
/ 09 ноября 2011

Я рекомендую добавить метод в класс вашей модели для определения уникальности.

class Entity < ActiveRecord::Base
  def unique_title?
    Entity.where(:title => title).count > 0
  end
end

Конечно, это будет означать, что вы выполняете этот запрос дважды (один раз для validates_uniqueness_of и один раз для unique_title?). Я предпочитаю удобочитаемость, а не производительность. Если производительность не приемлема, у вас все еще есть варианты. Вы можете повторно использовать unique_title? в своей собственной проверке и кэшировать результат.

class Entity < ActiveRecord::Base
  validate :title_must_be_unique

  def unique_title?
    # you may want to unset @unique_title when title changes
    if @unique_title.nil?
      @unique_title = Entity.where(:title => title).count > 0
    end
    @unique_title
  end

  private

  def title_must_be_unique
    unless unique_title?
      errors.add(:title, I18n.t("whatever-the-key-is-for-uniqueness-errors"))
    end
  end
end
1 голос
/ 09 ноября 2011

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

Если вы просто хотите установить сообщение об ошибке, вам не нужно это делать.Rails автоматически установит fsc.erros в качестве хэша, который выглядит как {: title => «title уже занят»}.Вы можете указать это сообщение, передав: сообщение для проверки.

Кроме того, вы можете интернационализировать сообщения с помощью l18n.Просто отредактируйте файл yaml, как описано здесь: http://guides.rubyonrails.org/i18n.html#configure-the-i18n-module

...