2011-02-17 19 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"} 

所以我们走了 - 这一次实际上似乎为我工作。评论欢迎,并希望这可以帮助别人!