使用grouped_collection_select按枚举对模型进行分组

时间:2016-04-26 03:34:29

标签: ruby-on-rails ruby-on-rails-4 enums

说我有两个班级

class Recording
  belongs_to :conversation
end

class Conversation < ActiveRecord::Base
  has_many :recordings

  enum status: [ :active, :archived ]
end

我想选择存储在'Recording'模型上的对话。在这种情况下,如何使用grouped_collection_select对Conversation表格中的所有记录进行分组,activearchived

我能找到的关于grouped_collection_select的所有例子都是指成员调用方法来提供集合;与对现有集合进行分组。

1 个答案:

答案 0 :(得分:2)

grouped_collection_select方法不是满足您需求的最佳工具,因为它确实处理主记录的关联记录,而如果我理解正确,您只想添加所有Conversation记录到选择标记,但按其属性分组,而不是关联。

但是,您可以轻松地手动构建分组选项。我将此代码放入帮助程序中,不要过多地混淆视图模板:

# app/helpers/conversations_helper.rb
module ConversationsHelper

  def grouped_conversations_options_for_select(selected_conversation_id = nil)
    options = {}
    Conversation.statuses.keys.each do |status|
      options[status] = Conversation.with_status(status).pluck(:name, :id)
    end
    grouped_options_for_select(options, selected_conversation_id)
  end

end

# app/view/show.html.erb
<%= select_tag :conversation_id, grouped_conversations_options_for_select(params[:conversation_id]) %>

帮助程序首先构造一个具有以下结构的哈希:

{
  active:   [[ conversation.id, conversation.name ], [...]],
  archived: [[ conversation.id, conversation.name ], [...]],
}

然后可以将此哈希传递给grouped_options_for_selectdemo将其转换为<OPTIONS>标记,包括正确的<OPTGROUP>标记。帮助程序还支持在选择选项中设置当前选定的值。然后将其输出传递给视图模板中的选择标记。

要使助手工作,您还需要将以下范围添加到Conversation模型中:

# app/models/conversation.rb
scope :with_status, ->(status) { where(status: statuses[status]) }