2011-02-17 46 views
0

我已經創建了一個LocalizedString自定義數據類型,用於使用mongo_mapper存儲/顯示翻譯。mongo_mapper用於本地化的自定義數據類型

這適用於一個領域,但只要我介紹另一個領域,他們得到寫在每個領域,只顯示一個值。 to_mongo和from_mongo似乎沒有正常工作。請任何人都可以幫忙嗎?她是代碼:

class LocalizedString 

    attr_accessor :translations 

    def self.from_mongo(value) 

    puts self.inspect 
    @translations ||= if value.is_a?(Hash) 
     value 
     elsif value.nil? 
     {} 
     else 
     { I18n.locale.to_s => value } 
    end 

    @translations[I18n.locale.to_s] 
    end 

    def self.to_mongo(value) 
    puts self.inspect 
    if value.is_a?(Hash) 
     @translations = value 
    else 
     @translations[I18n.locale.to_s] = value 
    end 

    @translations 
    end 
end 

感謝很多 裏克

回答

1

的問題是,您在[以|來自] _mongo方法,@translations是指一類變量,而不是你所期望的實例變量。所以發生的是,每次調用from_mongo時,都會覆蓋該值。

一個固定的版本是這樣的:

class LocalizedString 
    attr_accessor :translations 

    def initialize(translations = {}) 
    @translations = translations 
    end 

    def self.from_mongo(value) 
    if value.is_a?(Hash) 
     LocalizedString.new(value) 
    elsif value.nil? 
     LocalizedString.new() 
    else 
     LocalizedString.new({ I18n.locale.to_s => value }) 
    end 
    end 

    def self.to_mongo(value) 
    value.translations if value.present? 
    end 

end 
+0

我喜歡這種方法比哈希的方法,我在下面顯示更多,但我不能得到它的工作 - 我alwaysend了 to_mongo「:未定義的方法`翻譯」 有什麼想法? – adamnickerson 2011-04-07 12:52:47

1

我發現Jared的反應並沒有對我的工作 - 我會得到在一個EmbeddedDocument使用LocalizedString當翻譯沒有被發現。

我會得到一個類似的問題在裏克的解決方案,其中翻譯是零時使用嵌入式文件。爲了得到一個可行的解決方案,我使用了Rick的解決方案,將翻譯變量更改爲實例變量,以便每個使用LocalizedString的新字段都不會被覆蓋,然後添加一個檢查以確保翻譯不爲零(以及如果是的話創建一​​個新的哈希)。

在所有的LocalizedString解決方案中,這是我第一次能夠使它在EmbeddedDocuments上工作,並且沒有覆蓋問題 - 仍然可能存在其他問題! :)

class LocalizedString 
    attr_accessor :translations 

    def self.from_mongo(value) 

     puts self.inspect 
     translations ||= if value.is_a?(Hash) 
      value 
      elsif value.nil? 
      {} 
      else 
      { I18n.locale.to_s => value } 
     end 

     translations[I18n.locale.to_s] 
     end 

     def self.to_mongo(value) 
     puts self.inspect 
     if value.is_a?(Hash) 
      translations = value 
     else 
      if translations.nil? 
      translations = Hash.new() 
      end 
      translations[I18n.locale.to_s] = value 
     end 

     translations 
     end 

    end 
+0

我跳過槍發佈這個 - 當然,這樣做,一個LocalizedString沒有所有的翻譯,相反,他們都是分開的。所以當你堅持Mongo的時候,你只能得到一個翻譯......回到製圖板! – adamnickerson 2011-04-06 14:36:20

0

我發現this post:這是非常有幫助的。他將HashWithIndifferentAccess擴展爲LocalizedString。我唯一不喜歡的東西是每次設置時都必須明確指定語言環境 - 我希望它更像一個字符串。當然,你不能超載=運算符(至少我不認爲你可以),所以我用< <,並添加了一個to_s方法,它將輸出當前語言環境的字符串....

class LocalizedString < HashWithIndifferentAccess 
    def self.from_mongo(value) 
    LocalizedString.new(value || {}) 
    end 

    def available_locales 
    symbolize_keys.keys 
    end 

    def to_s 
    self[I18n.locale] 
    end 

    def in_current_locale=(value) 
    self[I18n.locale] = value 
    end 

    def << (value) 
    self[I18n.locale] = value 
    end 

,然後我有一個類,如:

class SimpleModel 
    include MongoMapper::Document 

    key :test, LocalizedString 
end 

,可以做的事情一樣

I18n.locale = :en 
    a = SimpleModel.new 
    a.test << "English" 
    I18n.locale = :de 
    a.test << "German" 
    puts a.test # access the translation for the current locale 
    I18n.locale = :en 
    puts a.test # access the translation for the current locale 
    puts a.test[:de] # access a translation explicitly 
    puts a.test[:en] 
    puts a.test.inspect 

,並得到

German 
English 
German 
English 
{"en"=>"English", "de"=>"German"} 

所以我們走了 - 這一次實際上似乎爲我工作。評論歡迎,並希望這可以幫助別人!