【问题标题】:Enums in Ruby on Rails Form Select Mapping ValuesRuby on Rails 表单中的枚举选择映射值
【发布时间】:2021-10-09 22:39:33
【问题描述】:

我的模型中有一个枚举如下:

 enum construction_type: {
    brick_block: "Brick/Block",
    concrete_slab: "Concrete/Slab",
    wood_steel: "Light Framed Wood/Steel",
    timber_steel: "Heavy Framed Timber/Steel"
  }

在一个表单中,我使用此代码来获取枚举值以放入下拉列表中:

  <%= form.label(:construction_type, class: "form-label") %>
  <% options = options_for_select(Site.construction_types.map {|key, value| [value, Site.construction_types.key(value)]}, form.object.construction_type) %>
  <%= form.select(:construction_type, options, include_blank: true) %>

虽然options_for_select 中的语句在Site.construction_types.values 产生相同的选项时似乎有点矫枉过正,但该字段仅在使用映射方法时在表单上提交无效后才会保持填充。

我发现的一个解决方案是将字符串硬编码为如下形式:

  <%= form.label(:construction_type, class: "form-label") %>
  <%= form.select(:construction_type, ["Brick/Block", "Concrete/Slab", "Light Framed Wood/Steel", "Heavy Framed Timber/Steel"], include_blank: true) %>

但是,我想避免这种解决方案,因为我有第二个表单用于编辑在这个表单中初始化的信息,我必须复制代码。模型中的枚举似乎是跟踪这些值的最佳方式。

我的数据库使用枚举中的值填充我想要的值,但是在我试图显示来自表单的信息的页面上,键出现了。

<li> <strong> <%= t(".construction_type") %> </strong> <%=@site.construction_type if @site.construction_type %> </li>

使用枚举版本,上面的代码产生以下结果: 建筑类型:砖块

与我想要的相反: 建筑类型:砖/块

有没有办法使用枚举方法解决这个问题?

【问题讨论】:

    标签: ruby-on-rails forms drop-down-menu enums


    【解决方案1】:

    模型中的枚举似乎是跟踪 这些值。

    地狱没有。 ActiveRecord::Enum 旨在将整数或任何其他有效存储和索引的类型连接到开发人员可读标签。

    当您将枚举定义为:

    enum construction_type: {
        brick_block: "Brick/Block",
        concrete_slab: "Concrete/Slab",
        wood_steel: "Light Framed Wood/Steel",
        timber_steel: "Heavy Framed Timber/Steel"
      }
    

    您将在数据库中存储"Heavy Framed Timber/Steel" 作为值,这是一个非常糟糕的主意,因为如果您需要更改人类友好的标签,您会要求非规范化问题。不应期望枚举映射发生变化。

    如果您真的想使用 Enum,请使用 I18n 模块来提供人类可读的版本:

    # the name is just an assumption
    class Building < ApplicationRecord
      enum construction_type: {
        brick_block: 0,
        concrete_slab: 1,
        wood_steel: 2,
        timber_steel: 3
      }
    end
    
    module BuildingsHelper
      def construction_type_options
         Building.construction_types.keys do |key|
           [key, t("activerecord.models.buildings.construction_types.#{ key }")]
         end
      end
    end
    

    但一个不那么老套的选择是使用单独的表/模型:

    class Building
      belongs_to :construction_type
    end
    
    class ConstructionType
      has_many :buildings
    end
    
    <%= form_with(model: @buildling) do |form| %>
      <%= form.collection_select :construction_type_id, 
        ConstructionType.all,
        :id,
        :description
      %>
    <% end %>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多