Rails : Rails 4 열거 형과 함께 i18n을 사용하는 방법


답변:


52

특정 패턴도 찾지 못했기 때문에 간단히 추가했습니다.

en:
  user_status:
    active:   Active
    pending:  Pending...
    archived: Archived

임의의 .yml 파일에. 그런 다음 내 견해 :

I18n.t :"user_status.#{user.status}"

5
나는 비슷한했다,하지만 난 아래에 넣어 {locale}.activerecord.attributes.{model}.{attribute}하고 쓴 t_enum(model, enum, value)열거 번역 레이블 번역에 인접 할 수 있도록 도우미 메서드를
크리스 벡

77

Rails 5부터 모든 모델은 ApplicationRecord.

class User < ApplicationRecord
  enum status: [:active, :pending, :archived]
end

이 수퍼 클래스를 사용하여 열거 형 번역을위한 일반 솔루션을 구현합니다.

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  def self.human_enum_name(enum_name, enum_value)
    I18n.t("activerecord.attributes.#{model_name.i18n_key}.#{enum_name.to_s.pluralize}.#{enum_value}")
  end
end

그런 다음 .yml파일에 번역을 추가 합니다.

en:
  activerecord:
    attributes:
      user:
        statuses:
          active: "Active"
          pending: "Pending"
          archived: "Archived"

마지막으로 번역을 얻으려면 다음을 사용합니다.

User.human_enum_name(:status, :pending)
=> "Pending"

3
드롭 다운에서 이것을 사용하는 방법 (즉, 단일 값을 표시하지 않을 때)을 어떻게 처리 하시겠습니까?
tirdadc

6
@tirdadc 다음과 같은 드롭 다운을 처리 할 수 ​​있습니다 <%= f.select :status, User.statuses.keys.collect { |status| [User.human_enum_name(:status, status), status] } %>..
Repolês 2017-08-10

3
+1 좋은 답변. 뷰 도우미 메서드로 사용하도록 조정했습니다. 이것이 뷰에 대한 우려가 더 많다고 생각 하고 속성 이름을 복수화하지 않기 위해 gist.github.com/abevoelker/fed59c2ec908de15acd27965e4725762 같은 뷰에서 호출합니다human_enum_name(@user, :status)
Abe Voelker

1
Repolês에 따라 드롭 다운을 위해 기본 모델에 다른 클래스 메서드를 추가 할 수도 있습니다 self.human_enum_collection(enum_name). 코드는 send(enum_name.to_s.pluralize).keys.collect { |val| [human_enum_name(enum_name, val), val] }
armchairdj

32

다음은보기입니다.

select_tag :gender, options_for_select(Profile.gender_attributes_for_select)

여기 모델이 있습니다 (실제로이 코드를 도우미 또는 데코레이터로 이동할 수 있습니다)

class Profile < ActiveRecord::Base
  enum gender: {male: 1, female: 2, trans: 3}

  # @return [Array<Array>]
  def self.gender_attributes_for_select
    genders.map do |gender, _|
      [I18n.t("activerecord.attributes.#{model_name.i18n_key}.genders.#{gender}"), gender]
    end
  end
end

다음은 로케일 파일입니다.

en:
  activerecord:
    attributes:
      profile:
        genders:
          male: Male
          female: Female
          trans: Trans

1
그러나이 경우 단일 레코드에 대한 번역을 얻는 방법은 무엇입니까? 때문에 .human_attribute_name('genders.male')하지 작업 할
Stiig

감사합니다, 제 경우에는 매력처럼 작동합니다 !
matiss

나는 이러한 목적을 위해 경량 보석을했습니다 github.com/shlima/translate_enum
악산

30

국제화를 다른 속성과 유사하게 유지하기 위해 여기에서 볼 수 있듯이 중첩 속성 방식을 따랐 습니다 .

수업이있는 경우 User:

class User < ActiveRecord::Base
  enum role: [ :teacher, :coordinator ]
end

그리고 다음 yml과 같이 :

pt-BR:
  activerecord:
    attributes:
      user/role: # You need to nest the values under model_name/attribute_name
        coordinator: Coordenador
        teacher: Professor

당신이 사용할 수있는:

User.human_attribute_name("role.#{@user.role}")

1
이 시각적으로 호소하고 있지만,의 레일 규칙 나누기 activerecord.attributes.<fieldname>되는 label형태 헬퍼 번역
크리스 벡

5
: @ChrisBeck는 이것이 레일 국제화 설명서에 설명 된 규칙은 다음과 나타납니다 guides.rubyonrails.org/...
danblaker

내 경험상 이것은 role키 를 사용하지 않고 작동 합니다. 당신은 둥지 수 coordinatorteacher직접 아래 user.
Ryan Crispin Heneise

7

모델:

enum stage: { starting: 1, course: 2, ending: 3 }

def self.i18n_stages(hash = {})
  stages.keys.each { |key| hash[I18n.t("checkpoint_stages.#{key}")] = key }
  hash
end

장소:

checkpoint_stages:
    starting: Saída
    course: Percurso
    ending: Chegada

그리고보기 (.slim)에서 :

= f.input_field :stage, collection: Checkpoint.i18n_stages, as: :radio_buttons

6

user3647358의 답변을 자세히 설명하면 속성 이름을 번역 할 때 익숙한 것과 매우 유사하게 수행 할 수 있습니다.

로케일 파일 :

en:
  activerecord:
    attributes:
      profile:
        genders:
          male: Male
          female: Female
          trans: Trans

I18n # t를 호출하여 번역 :

profile = Profile.first
I18n.t(profile.gender, scope: [:activerecord, :attributes, :profile, :genders])

4

이러한 목적으로 TranslateEnum gem을 사용해보십시오.

class Post < ActiveRecord::Base
  enum status: { published: 0, archive: 1 }
  translate_enum :status
end


Post.translated_status(:published)
Post.translated_statuses

@post = Post.new(status: :published)
@post.translated_status 

1
이 보석도 사용합니다. 우리가 평가 한 모든 옵션 중에서 가장 깨끗한 접근 방식을 가지고 있으며 잘 유지되고 있습니다.
cseelus

3

나는 이것을 위해 보석을 만들었습니다.

http://rubygems.org/gems/translated_attribute_value

gemfile에 추가하세요 :

gem 'translated_attribute_value'

사용자에 대한 상태 필드가있는 경우 :

pt-BR:
  activerecord:
    attributes:
      user:
        status_translation:
          value1: 'Translation for value1'
          value2: 'Translation for value2'

그리고 당신의 관점에서 다음과 같이 부를 수 있습니다.

user.status_translated

활성 레코드, mongoid 또는 getter / setter가있는 다른 클래스에서 작동합니다.

https://github.com/viniciusoyama/translated_attribute_value


3

RepolêsAliaksandr 의 답변을 결합하여 Rails 5의 경우 enum 속성에서 단일 값 또는 값 모음을 번역 할 수있는 두 가지 메서드를 빌드 할 수 있습니다.

.yml파일에 번역을 설정 합니다.

en:
  activerecord:
    attributes:
      user:
        statuses:
          active: "Active"
          pending: "Pending"
          archived: "Archived"

ApplicationRecord모든 모델이 상속 하는 클래스에서 단일 값에 대한 변환을 처리하는 메서드와이를 호출하여 배열을 처리하는 다른 값을 정의합니다.

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  def self.translate_enum_name(enum_name, enum_value)
    I18n.t("activerecord.attributes.#{model_name.i18n_key}.#{enum_name.to_s.pluralize}.#{enum_value}")
  end

  def self.translate_enum_collection(enum_name)
    enum_values = self.send(enum_name.to_s.pluralize).keys
    enum_values.map do |enum_value|
      self.translate_enum_name enum_name, enum_value
    end
  end
end 

뷰에서 단일 값을 번역 할 수 있습니다.

<p>User Status: <%= User.translate_enum_name :status, @user.status %></p>

또는 열거 형 값의 전체 컬렉션 :

<%= f.select(:status, User.translate_enum_collection :status) %>

2

enum_help gem을 사용 해보세요 . 설명에서 :

ActiveRecord :: Enum 기능이 I18n 및 simple_form에서 잘 작동하도록 도와주세요.


2

여기 t_enum내가 사용 하는 도우미 방법이 있습니다.

<%= t_enum(@user, :status) %>

enum_helper.rb :

module EnumHelper

  def t_enum(inst, enum)
    value = inst.send(enum);
    t_enum_class(inst.class, enum, value)
  end

  def t_enum_class(klass, enum, value)
    unless value.blank?
      I18n.t("activerecord.enums.#{klass.to_s.demodulize.underscore}.#{enum}.#{value}")
    end
  end

end

user.rb :

class User < ActiveRecord::Base
  enum status: [:active, :pending, :archived]
end 

en.yml :

en:
  activerecord:
    enums:
      user:
        status:
          active:   "Active"
          pending:  "Pending..."
          archived: "Archived"

2

모델:

class User < ActiveRecord::Base
  enum role: [:master, :apprentice]
end

로케일 파일 :

en:
  activerecord:
    attributes:
      user:
        master: Master
        apprentice: Apprentice

용법:

User.human_attribute_name(:master) # => Master
User.human_attribute_name(:apprentice) # => Apprentice

@user.role그것이 주요 문제이기 때문에 어떻습니까 ?
Code-MonKy

가장 솔직하고 깨끗하며 우아한 방법입니다.
Fabian Winkler

5
AnyModel.human_attribute_name (: i_dont_exist) => "나는 존재하지 말아"
Shiyason

1

나는 application_helper에서 간단한 도우미를 선호합니다.

  def translate_enum(object, enum_name)
    I18n.t("activerecord.attributes.#{object.model_name.i18n_key}.#{enum_name.to_s.pluralize}.#{object.send(enum_name)}")
  end

그런 다음 내 YML 파일에서 :

fr:
  activerecord:
    attributes:
      my_model:
        my_enum_plural:
          pending:  "En cours"
          accepted: "Accepté"
          refused:  "Refusé"

0

또 다른 방법은 모델의 관심사를 사용하여 좀 더 편리하다는 것입니다.

우려 사항 :

module EnumTranslation
  extend ActiveSupport::Concern

  def t_enum(enum)
    I18n.t "activerecord.attributes.#{self.class.name.underscore}.enums.#{enum}.#{self.send(enum)}"
  end
end

YML :

fr:
    activerecord:
      attributes:
        campaign:
          title: Titre
          short_description: Description courte
          enums:
            status:
              failed: "Echec"

보기 :

<% @campaigns.each do |c| %>
  <%= c.t_enum("status") %>
<% end %>

모델에 관심을 추가하는 것을 잊지 마십시오.

class Campaign < ActiveRecord::Base
  include EnumTranslation

  enum status: [:designed, :created, :active, :failed, :success]
end

0

도우미를 추가하기 만하면됩니다.

def my_something_list
  modes = 'activerecord.attributes.mymodel.my_somethings'
  I18n.t(modes).map {|k, v| [v, k]}
end

평소대로 설정합니다.

en:
  activerecord:
    attributes:
      mymodel:
        my_somethings:
           my_enum_value: "My enum Value!"

그런 다음 선택 항목과 함께 사용하십시오. my_something_list


0
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  def self.enum(definitions)
    defind_i18n_text(definitions) if definitions.delete(:_human)
    super(definitions)
  end

  def self.defind_i18n_text(definitions)
    scope = i18n_scope
    definitions.each do |name, values|
      next if name.to_s.start_with?('_')
      define_singleton_method("human_#{name.to_s.tableize}") do
        p values
        values.map { |key, _value| [key, I18n.t("#{scope}.enums.#{model_name.i18n_key}.#{name}.#{key}")] }.to_h
      end

      define_method("human_#{name}") do
        I18n.t("#{scope}.enums.#{model_name.i18n_key}.#{name}.#{send(name)}")
      end
    end
  end
end


en:
  activerecord:
    enums:
      mymodel:
        my_somethings:
           my_enum_value: "My enum Value!"

enum status: [:unread, :down], _human: true
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.