रेल 4 सक्रिय रिकॉर्ड एनम महान हैं, लेकिन i18n के साथ अनुवाद करने के लिए सही पैटर्न क्या है?
रेल 4 सक्रिय रिकॉर्ड एनम महान हैं, लेकिन i18n के साथ अनुवाद करने के लिए सही पैटर्न क्या है?
जवाबों:
रेल 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"
<%= f.select :status, User.statuses.keys.collect { |status| [User.human_enum_name(:status, status), status] } %>
।
human_enum_name(@user, :status)
self.human_enum_collection(enum_name)
:। कोड होगा send(enum_name.to_s.pluralize).keys.collect { |val| [human_enum_name(enum_name, val), val] }
यहाँ एक दृश्य है:
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
.human_attribute_name('genders.male')
काम नहीं करते
अंतर्राष्ट्रीयकरण को किसी भी अन्य विशेषता के समान रखने के लिए मैंने नेस्टेड विशेषता तरीके का पालन किया जैसा कि आप यहां देख सकते हैं ।
यदि आपके पास एक वर्ग है 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}")
activerecord.attributes.<fieldname>
होने की रेल परंपरा को तोड़ता हैlabel
role
कुंजी का उपयोग किए बिना काम करता है । आप घोंसला बना सकते हैं coordinator
और teacher
सीधे नीचे user
।
नमूना:
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
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])
इन उद्देश्यों के लिए TranslateEnum रत्न का उपयोग करने का प्रयास करें
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
मैंने इसके लिए एक मणि बनाई है।
http://rubygems.org/gems/translated_attribute_value
अपने रत्न में जोड़ें:
gem 'translated_attribute_value'
यदि आपके पास उपयोगकर्ता के लिए एक स्थिति फ़ील्ड है:
pt-BR:
activerecord:
attributes:
user:
status_translation:
value1: 'Translation for value1'
value2: 'Translation for value2'
और आपके विचार में आप इस तरह से कॉल कर सकते हैं:
user.status_translated
यह सक्रिय रिकॉर्ड के साथ काम करता है, मैन्गॉइड या किसी अन्य वर्ग के साथ गेट्टर / सेटर के साथ काम करता है:
रेपोलस और अलीकसैंडर के जवाबों को जोड़ते हुए , रेल्स 5 के लिए, हम 2 तरीके बना सकते हैं, जो आपको किसी एकल मान या किसी एनम विशेषता से मानों के संग्रह का अनुवाद करने की अनुमति देते हैं।
अपनी .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) %>
एक 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"
आदर्श:
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
, क्योंकि यह मुख्य मुद्दा है।
मैं 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é"
अभी तक एक और तरीका है, मैं इसे मॉडल में एक चिंता का उपयोग करके थोड़ा अधिक सुविधाजनक पाता हूं
चिंता :
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
आप बस एक सहायक जोड़ सकते हैं:
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
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
{locale}.activerecord.attributes.{model}.{attribute}
और एकt_enum(model, enum, value)
सहायक विधि लिखी ताकि एनुम अनुवाद लेबल अनुवाद के निकट हो जाए