【问题标题】:mongo_mapper custom data types for localization用于本地化的 mongo_mapper 自定义数据类型
【发布时间】:2011-02-17 15:21:34
【问题描述】:

我创建了一个 LocalizedString 自定义数据类型,用于使用 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

非常感谢 瑞克

【问题讨论】:

    标签: ruby-on-rails ruby mongodb mongomapper


    【解决方案1】:

    问题在于,在您的 [to|from]_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
    

    【讨论】:

    • 我更喜欢这种方法,而不是下面展示的哈希方法,但我无法让它发挥作用——我总是以 to_mongo': undefined method `translations' 结尾有什么想法吗?跨度>
    【解决方案2】:

    我发现 jared 的响应对我不起作用——我会发现在 EmbeddedDocument 中使用 LocalizedString 时找不到翻译。

    我会在 rick 的解决方案中遇到类似的问题,即在使用嵌入式文档时翻译为零。为了得到一个可行的解决方案,我采用了 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
    

    【讨论】:

    • 我发了这个帖子——当然,这样一来,一个 LocalizedString 并没有所有的翻译,而是它们都是独立的。因此,当您坚持使用 Mongo 时,您只会得到一个翻译……回到绘图板!
    • OK -- 忽略这一切...看下一个答案。
    【解决方案3】:

    我找到了this post: 这很有帮助。他扩展了 HashWithIndifferentAccess 以作为 LocalizedString 工作。我唯一不喜欢的是每次设置时都必须明确指定语言环境——我希望它更像一个字符串。当然,你不能重载 = 运算符(至少我认为你不能)所以我使用了

    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"}
    

    所以我们开始了——这个实际上似乎对我有用。欢迎评论,希望对大家有所帮助!

    【讨论】:

      猜你喜欢
      • 2010-12-31
      • 2011-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-15
      • 1970-01-01
      • 2017-02-05
      相关资源
      最近更新 更多