Локализация ActiveRecord RecordNotFound

Я пытаюсь локализовать свое приложение rails (веб-сервис). Я установил драгоценный камень «rails-i18n», который отлично работает.

За исключением того, что он не переводит сообщение ActiveRecord::RecordNotFound. В коде рельсов: https://github.com/rails/rails/blob/3-2-stable/activerecord/lib/active_record/relation/finder_methods.rb

raise RecordNotFound, "Couldn't find #{@klass.name} with #{conditions.to_a.collect {|p| p.join(' = ')}.join(', ')}"

Кажется, что сообщение жестко закодировано.

Есть ли какое-либо решение, кроме использования Model.find_by_'attribute'?


person cyrilchampier    schedule 23.10.2013    source источник
comment
ПРИМЕЧАНИЕ: в rails4 find_by_'attribute_name'! устарела, поэтому количество случаев этой ошибки значительно сокращается.   -  person cyrilchampier    schedule 30.12.2013


Ответы (3)


По моей причине достаточно сообщить пользователю более информативное сообщение:

exception.message.match /^Couldn't find (\w+) with (id=([\S]*))?/
msg = t 'activerecord.exceptions.not_found', klass: $1, id: $3

и так как я хотел чешский перевод:

cs:
  activerecord:
    exceptions:
      not_found: "Nelze nalézt %{klass} s id=%{id}"

.. когда что-то жестко закодировано, единственный способ - жестко декодировать это

person Ondřej Želazko    schedule 30.12.2013

Вы можете перехватить исключение RecordNotFound в контроллере приложения и вернуть локализованное сообщение. Таким образом, вы также можете изменить поведение по умолчанию для 404:

class ApplicationController < ActionController::Base

  rescue_from ActiveRecord::RecordNotFound, :with => :not_found

  private

    def not_found
      render :json => { :message => I18n.t('exception.record_not_found') },
             :status => :not_found
    end

end
person lawitschka    schedule 23.10.2013
comment
да, но я потеряю контекстуальность исходного сообщения, в котором отображается имя класса и атрибута! - person cyrilchampier; 23.10.2013
comment
А для чего вам эта информация? ИМХО для пользователя неважно, что не было найдено, а только то, что что-то пошло не так. Если вы хотите регистрировать такие ошибки, вы можете указать, что not_found принимает исключение аргумента. Таким образом, вы можете получить к нему доступ и зарегистрировать его или что-то еще... - person lawitschka; 24.10.2013
comment
Потому что это веб-сервис, и клиенты должны знать, что они делают не так, не обращаясь в нашу поддержку. - person cyrilchampier; 24.10.2013
comment
Вы можете восстановить имя класса — даже локализованное — с помощью controller_name.classify.constantize.model_name.human и получить такие вещи, как идентификатор, из хэша params. Решение Ондрея сломается, как только сообщение по умолчанию будет изменено. - person Janosch; 20.01.2015

Другой способ в конфигурации YAML:

en:
 activerecord:
   exceptions:
     not_found: "%{model_name} not found"

Вы также можете установить форму множественного числа для имен моделей, добавив следующее:

en:
  activerecord:
    models:
      user:
        one: Dude
        other: Dudes
person Vishnu Atrai    schedule 27.07.2015
comment
Вы также можете установить форму множественного числа для имен моделей, добавив следующее: en: activerecord: models: user: one: Dude other: Dudes - person Vishnu Atrai; 27.07.2015