将 Rails Active Record 枚举类型与 Simple_Form 结合使用

问题描述 投票:0回答:9

我声明一个具有

enum
类型的模型,例如:

class Event < ActiveRecord::Base
    enum event_type: { "special_event" => 0,
                       "pto"           => 1,
                       "hospitality"   => 2,
                       "classroom"     => 3
                       }

然后在我的更新视图中,我有一个表单:

<%= simple_form_for @event do |f| %>   
    <%= f.input :event_type, collection: Event.event_types.keys %>  
    ... 
<% end %>

这效果很好,我得到了一个填充了我的枚举类型的选择。 当我在控制器中执行

@event.update(event_params)
时,我可以检查数据库并看到
event_type
字段已更新为正确的整数值。

但是,当我重新访问编辑页面时,选择显示为零值。 如果我通过在表单中添加调试行来检查其值:

<%= f.input :event_type, collection: Event.event_types.keys %>  
<%= debug @event %>

我发现

event_type
的值是正确的:

--- !ruby/object:Event
attributes:
  ...
  event_type: '2'

但是输入选择器仍然是空白的,而不是显示应有的“热情好客”。

任何想法将不胜感激。 :)

ruby-on-rails enums simple-form
9个回答
27
投票

这条线工作得很好。

<%= f.input :event_type, collection: Event.event_types %>

是否必须手动设置所选值? 你的 simple_form 版本是什么?


13
投票

文森特的解决方案给了我错误:

'0' is not a valid 'fieldname'

我必须按照其他 stackoverflow 帖子中的建议添加

keys

<%= f.input :event_type, collection: Event.event_types.keys %>


8
投票

使用 enum_help gem。让你这样做:

<%= f.input :event_type %>

8
投票

我也被这个问题困住了。我需要给我的枚举命名,这样它们在我使用的 Snake_case 中就不会显得那么奇怪。我使用 to_a 获取 ruby 哈希并将其转换为数组,然后使用collect 以我需要的格式返回一个新数组。

collection: Event.event_type.to_a.collect{|c| [c[0].titleize, c[0]]}

希望这能对其他人有所帮助。


2
投票

例如,假设您的模型中有一个像这样的枚举(示例中的模型角色):

enum :work_type, in_person: "in_person", remote: "remote", hybrid: "hybrid"

这在你看来会起作用

= f.input :work_type, as: :select, collection: Role.work_types.collect { |key, value| [key.to_s.titleize, value] }

这将输出以下 HTML:

<select class="form__input" name="role[work_type]" id="role_work_type">
  <option selected="selected" value="in_person">In Person</option>
  <option value="remote">Remote</option>
  <option value="hybrid">Hybrid</option>
</select>

0
投票

感谢您的关注。 我相信我报告的问题是由 event_type 声明不正确引起的。 在我的迁移中,我不小心将 event_type 定义为 String 而不是 Integer:

class CreateEvents < ActiveRecord::Migration
  def change
    create_table :events do |t|
      ...
      t.string :event_type
      ...
    end
  end
end

我认为枚举应该声明为整数才能正常工作。 不幸的是,我没有测试将类型更改为整数是否可以使其工作,因为我实际上最终使用了不同的方法。 我没有使用枚举,而是在模型中定义了事件类型的集合:

class Event < ActiveRecord::Base
  def self.types
    ['Special_Events', "On-Going", 'PTO', "Classroom"]
  end
  ...
end

然后在我的表单中,使用具有以下语法的简单形式:

<%= f.input :event_type, collection: Event.types, input_html: { autocomplete: 'off' }  %>

一切顺利。


0
投票

我使用 draper 作为装饰器,所以我想将单词翻译添加到模型的装饰器中。这是我的代码:

应用程序/装饰器/meter_decorator.rb

class MeterDecorator < Draper::Decorator
  delegate_all

  STATUS_MAPPING = {
    uninitialized: '未安装',
    good: '良好',
    broken: '故障',
    disabled: '禁止'
  }

  def status
    STATUS_MAPPING[object.status.to_sym]
  end
end

视图/米/_form.html.erb

<%= f.input :status, collection: MeterDecorator::STATUS_MAPPING, label_method: :last, value_method: :first, include_blank: false %>

视图/米/index.html.erb

<td><%= meter.decorate.status %></td>

0
投票

<%= f.input :event_type, collection: Event.event_types.transform_keys(&:titleize) %>

只需按原样传递枚举哈希就足够了。但如果你想改变选项,你可以使用 transform_keys


-1
投票

经过更多研究,我提出了以下解决方案:

<%= f.input :event_type, collection: Event.event_types.keys,
            :selected => Event.event_types.keys[@event[:event_type].to_i], 
            input_html: { autocomplete: 'off' }  %>

所以,我必须做两件事:

  • 使用 :selected 设置选择器的值。 这需要使用繁琐的语法 Event.event_types.keys[@event[:event_type].to_i] 来设置选择值。 我很想听听是否有更简单的语法可以使用。 :)
  • 设置自动完成:'off'以防止 Firefox 在页面重新加载时将选择器设置为之前的设置。

欢迎替代、更简单的解决方案!

© www.soinside.com 2019 - 2024. All rights reserved.