我有一个类别模型,'用例是topcategory,category或subcategory。
class Category < ApplicationRecord
has_many :subcategories, class_name: "Category", foreign_key: "parent_id"
belongs_to :topcategory, class_name: "Category"
has_many :skills
end
class Skill < ApplicationRecord
belongs_to :category
end
1)如何按照此处提到的collection_check_boxes
列出每个类别(层次结构化)相关技能:https://stackoverflow.com/a/44282875/8090895
2)我需要在分层列表中列出这些类别,例如
topcategory1
-Skill1, Skill2, Skill6
-category1
--Skill3, Skill4
--Subcategory1
---Skill7, Skill8
--Subcategory2
---Skill5
-category2
topcategory2
...
我怎么能这样做?
我目前的类别控制器设置是:
@all_categories = Category.includes(:subcategories, :skills)
@topcategories = @all_categories.where("parent_id IS NULL")
@categories = @all_categories.where("parent_id IS NOT NULL")
3)为了创造新技能,我需要一个包含所有类别的结构化列表的下拉列表。我发现只有使用options_from_collection_for_select
的可能性,但在这里我不能自己选择“maingroups”。在我的用例中,我甚至需要所有树实例都可以选择。
我感谢任何帮助。提前感谢您的提示和帮助。如果您需要更多信息,请选择它。
第3部分的Edit1):另一个想法是填写下拉列表,如下所示:
Topcategory1//
Topcategory1//Category1//
Topcategory1//Category1//Subcategory1
Topcategory1//Category1//Subcategory2
Topcategory2//
Topcategory2//Category2//
Topcategory2//Category2//Subcategory3
...
这将是/应该是正常列表,这使得可以选择任何类别元素。顶级和类别多次显示的事实对我来说没问题。我只是不知道,我怎么能填写这样的下拉列表。
答案 0 :(得分:0)
首先为类别创建自加入关联:
class Category < ApplicationRecord
belongs_to :parent, class_name: 'Category',
optional: true
has_many :children, class_name: 'Category',
foreign_key: 'category_id'
end
这允许您根据需要无限地嵌套类别,并将记录保存在单个表中。如果您需要重新组织分类,这一点至关重要。
然后,您可以设置技能和类别之间的关联:
class Skill < ApplicationRecord
belongs_to :category
end
要加入子类别的类别和技能,您可以这样做:
@categories = Category.left_joins(:skills, children: [:skills])
@top_level = @categories.select { |c| c.parent.nil? }
3)为了创造新技能,我需要一个带结构化列表的下拉列表 所有类别。我发现只有使用的可能性
options_from_collection_for_select
但在这里我无法选择 &#34; maingroups&#34;他们自己。在我的用例中,我甚至需要所有的树 实例可以选择。
不幸的是,HTML规范不允许嵌套的<optgroup>
元素。您可以通过缩进选项来伪造嵌套。还有一些javascript选项,如Select2,可以使它更有用。
<select name="person[skill_ids]" multiple="true">
<optgroup label="Programming">
<option value="1">GIT</option>
</optgroup>
<optgroup label=" Programming Languages" class="level-2">
<option value="2"> Ruby</option>
<option value="2"> Python</option>
</optgroup>
</select>
&#13;
使用rails分组集合帮助程序可能不适合您的用例。因此,您可能需要手动创建选项:
<select name="person[skill_ids]">
<%= @top_level.each do |tc| %>
<optgroup label="<%= tc.name %>" class="parent-category">
<%= options_for_select(tc.skills.map { |s| [s.name, s.id] })
</optgroup>
<%= tc.children.each do |subcategory| %>
<optgroup label=" <%= subcategory.name %>" class="subcategory">
<%= options_for_select(subcategory.skills.map { |s| [" #{s.name}", s.id] }) %>
</optgroup>
<% end %>
</optgroup>
<% end %>
</select>
在这里,您还将检查表单对象是否具有该技能,并将所选属性应用于<option>
。