如何在两个不同的列中保存常量的键和值?

时间:2019-01-09 11:29:05

标签: ruby-on-rails

我有一个常量哈希,其中包含语言及其ISO代码。我在管理员视图中使用此常量,管理员可以在其中选择语言并创建类别。我想将语言名称及其ISO保存在两个不同的列中,而无需手动进行。

这是我的常数:

LANGUAGES = {
  'fr': 'Français',
  'en': 'Anglais',
  'es': 'Espagnol',
  'de': 'Allemand',
  'pt': 'Portugais',
  'it': 'Italien',
  'ja': 'Japonais',
  'zh': 'Chinois',
  'ru': 'Russe',
  'ar': 'Arabe'
}.freeze

然后在我的simple_form中进行选择:

= f.input(:source_language, collection: Category::LANGUAGES.map { |iso, name| [name, iso] })

我想将iso保存在名为iso的列中,并将名称保存在名为source_language的列中。

是否有一种简单而优雅的方法来获取所选语言的名称并将其保存在与iso不同的列中?

我应该在控制器中做到与ISO匹配吗?

1 个答案:

答案 0 :(得分:1)

有多种方法可以设置 source_language 属性,具体取决于您的需求。

  • 您是否希望能够独立设置 iso source_language 属性?然后,您可能需要在创建/更新时在控制器中设置 source_language 属性。

    # app/controllers/categories_controller.rb
    LANGUAGES = Category::LANGUAGES.stringify_keys.freeze
    
    def create
      @category = Category.new(category_params)
      @category.source_language = LANGUAGES[@category.iso]
    
      if @category.save
        # ...
      end
    end
    
  • 第一个基于模型的替代方法是简单地创建一个将基于 iso 属性执行此操作的设置器。

    # app/models/category.rb
    def set_source_language
      languages = LANGUAGES.stringify_keys
      self.source_language = languages[iso]          
    end
    

    然后在控制器中,您可以将行@category.source_language = LANGUAGES[@category.iso]从上方更改为@category.set_source_language,并删除控制器LANGUAGES常量。

  • 您可以将上述解决方案与 iso 属性设置器的替代组合。

    # app/models/category.rb
    def iso=(iso)
      super
      set_source_language
    end
    

    在这种情况下,您可以从控制器中完全删除行@category.set_source_language。请记住,在 category_params 方法内不允许使用 source_language

    请记住,这有时可能会产生“意外”结果。如果先设置 iso ,然后再设置 source_language ,则可以将它们彼此分开设置。第一次设置 source_language 后跟 iso 时,将 source_language 值覆盖为一个哈希值。

  • 另一个选择是使用模型回调来确保正确设置 source_language

    # app/models/category.rb
    before_save :set_source_language
    

    这将确保在保存到数据库之前始终正确设置 source_language 。但是,这也会产生“意外”结果。您必须记住,在保存之前,此属性未设置且无法使用(除非您手动调用 Category#set_source_language )。更改 iso 属性后,不会立即更改 source_language ,必须首先调用 Category#set_source_language 或保存实例以设置新的 source_language

    您可以将其与以上几点结合使用,以创建更加凝聚的体验。使用此解决方案时,您还可以从控制器中删除行@category.set_source_language