2014-11-27 3 views
0

구현해야 할 기능에 대한 딜레마가 있습니다. 우리 앱 (0 < n < +infinity)에서 n 개의 언어를 지원하고 싶습니다. Rails 다중 경로 정보를 DataBase에 저장 (최종 사용자가 번역)

우리는 아래의 솔루션을 가기로 결정 :

module TranslatedAttributes 

    def use_translated_attributes 
    has_many :translated_attributes, as: :owner 
    accepts_nested_attributes_for :translated_attributes 

    define_method :translate_attribute do |attribute, locale = I18n.locale| 
     TranslatedAttribute.where(attribute_name: attribute.to_s, owner_type: self.class.model_name, owner_id: self.id, locale: locale.to_s).first.try(:translation) 
    end 
    end 
end 

사용자가 예를 들어 제품 모델의 예를 들어 X 번역 (들)을 정의 할 수 있어야한다. 또한 사용자 프로필에 설정된 사용자의 로켈에 따라 번역 된 버전의 속성이 표시됩니다.

예 :보기에서

Product 
    id: 12 
TranslatedAttribute 
    attribute_name: 'name' 
    owner_id: 12 
    owner_type: 'Product' 
    locale: 'en' 
    translation: 'Magnificent shiny shoes' 
TranslatedAttribute 
    attribute_name: 'name' 
    owner_id: 12 
    owner_type: 'Product' 
    locale: 'fr' 
    translation: 'Magnifiques chaussures brillantes' 

, 다음과 같이 호출 할 것이다 :

product.translate_attribute(:name) 
# or we will eventually define_method for each attribute to be translated 
# so we could use the following 
# product.name 

이 이미 테스트, 작동합니다.

문제는입니다. 많은 수의 레코드를로드하려고 할 때 문제가 있습니다. 각 레코드는 표시 할 적절한 변환을 알기 위해 DB를 쿼리해야합니다.

제 질문은입니다. 어떻게 캐시를 처리합니까?

또 다른 질문은 내가 볼 수있는 다른 문제가 있습니까? 또한 fields_for으로 번역 양식을 작성하려면 accepts_nested_attributes_for :translated_attributes을 생각했습니다. 이런 식으로 처리하는 것은 나쁜 생각이라고 생각합니까?

고마워요!

답변

2

이 기능을 구현하기 위해 globalize3 gem과 같은 것을 사용할 수 있습니다.

1

첫 번째 최적화에서는 translate_attribute에 대한 첫 번째 호출에서 Product 인스턴스의 원하는 로캘 [1]에있는 모든 번역을 가져와 인스턴스 변수에 캐시 할 수 있습니다.

이렇게하면 번역 요청 수가 Product 인스턴스별로 하나만 줄어 듭니다.

빠른 예 :

define_method :translate_attribute do |attribute, locale = I18n.locale| 
    locale = locale.to_s 
    @attributes_translations_cache ||= {} 
    @attributes_translations_cache[locale] ||= Hash[ 
    self.translated_attributes 
     .where(locale: locale) 
     .map do |translated_attribute| 
      [translated_attribute.name, translated_attribute.translation] 
     end 
    ] 
    @attributes_translations_cache[locale][attribute] 
end 

나는 그것이 또한 join 또는 적어도 include 어떤 방법으로 제품에 대한 번역이 가능해야한다고 생각하지만, 나는 아직이 아이디어에 많은 생각을 부여하지 않았습니다. 나는이 대답을 업데이트하려고 노력할 것이다.

[1] 이것은 주어진 페이지에서 단일 로캘 만 사용한다고 가정하지만 동시에 모든 로캘이나 로캘과 특성의 조합을 가져올 수도 있습니다.