Ruby 在 Rails 上,从 select_tag (acts_as_nested_set) 中排除值
Ruby on Rails , exclude values from select_tag (acts_as_nested_set)
我有一个 select 标签,它也使用 Select2
以下拉方式显示一些类别
<%= category.select :parent_id, nested_set_options(Category, @category) {|i| if !(i.depth >= 2)
"#{i.root.name if !i.parent_id.nil? } #{'>' unless !i.parent_id} #{i.name}"
end
} , {include_blank:true} , class: 'select2 form-control'%>
此 select 是在您决定将其嵌套在父类别下时创建新类别时的提示。
我使用此代码的原因是因为我只想让管理员选择嵌套到 depth=3
所以只有 Parent -> Kid -> GrandKid
代码运行良好,但当决定不显示某个值时,我得到一个白色 space(小很多),但用户仍然可以选择它。
有什么办法可以排除那些不属于这种情况的值吗?
解决这个问题的代码是对 GoGoCarl 的伟大答案的解释,只是因为我有一个小问题 reject_if
所以我把整个事情都扭转了过来,结果是这样的:
<%= category.select :parent_id, nested_set_options(Category, @category) {|i|
if !(i.depth >= 2)
"#{i.root.name if !i.parent_id.nil? } #{'>' unless !i.parent_id} #{i.name}"
end
}.select { |i|
!i[0].nil? || !i[0].blank?
} , {include_blank:true , include_hidden:false} , class: 'select2 form-control'%>
需要花点时间,但可以做到。
首先,select 助手几乎只需要一个数组数组,所以类似于:
[ ["Apples", 1], ["Oranges", 2], ["Bananas", 3] ]
最后,如果返回 nested_set_options
。因此,最终,您可以操纵 nested_set_options
返回的 Array of Arrays 以满足您的需要。示例(为清楚起见添加了空格和缩进):
<%= category.select :parent_id,
nested_set_options(Category, @category) { |i|
if !(i.depth >= 2)
"#{i.root.name if !i.parent_id.nil? } #{'>' unless !i.parent_id} #{i.name}"
end
}.reject_if { |i|
i[0].nil? || i[0].strip.blank?
},
{include_blank:true},
class: 'select2 form-control'%>
这里的关键是检查Array of Arrays,看显示文本(每个Array的第一个元素)是否为空白。因为您实际上是将 " "
作为字符串返回,所以此检查会删除空格,然后查看生成的字符串是否为空。如果是这样,它会删除该元素。最终的 Array 将只包含那些显示包含一些非空白字符的元素。
您甚至可以进一步扩展它以添加管理用户检查,并在用户是管理员的情况下拒绝某些选项。
或者,您也可以考虑覆盖 Category
的 move_possible?
方法。但是,我认为您的业务逻辑太复杂,无法走这条路,并且可能会在您的模型中引入一些反模式。但是,这是一个选项,也可以完成任务。
希望对您有所帮助!
我有一个 select 标签,它也使用 Select2
以下拉方式显示一些类别<%= category.select :parent_id, nested_set_options(Category, @category) {|i| if !(i.depth >= 2)
"#{i.root.name if !i.parent_id.nil? } #{'>' unless !i.parent_id} #{i.name}"
end
} , {include_blank:true} , class: 'select2 form-control'%>
此 select 是在您决定将其嵌套在父类别下时创建新类别时的提示。
我使用此代码的原因是因为我只想让管理员选择嵌套到 depth=3
所以只有 Parent -> Kid -> GrandKid
代码运行良好,但当决定不显示某个值时,我得到一个白色 space(小很多),但用户仍然可以选择它。
有什么办法可以排除那些不属于这种情况的值吗?
解决这个问题的代码是对 GoGoCarl 的伟大答案的解释,只是因为我有一个小问题 reject_if
所以我把整个事情都扭转了过来,结果是这样的:
<%= category.select :parent_id, nested_set_options(Category, @category) {|i|
if !(i.depth >= 2)
"#{i.root.name if !i.parent_id.nil? } #{'>' unless !i.parent_id} #{i.name}"
end
}.select { |i|
!i[0].nil? || !i[0].blank?
} , {include_blank:true , include_hidden:false} , class: 'select2 form-control'%>
需要花点时间,但可以做到。
首先,select 助手几乎只需要一个数组数组,所以类似于:
[ ["Apples", 1], ["Oranges", 2], ["Bananas", 3] ]
最后,如果返回 nested_set_options
。因此,最终,您可以操纵 nested_set_options
返回的 Array of Arrays 以满足您的需要。示例(为清楚起见添加了空格和缩进):
<%= category.select :parent_id,
nested_set_options(Category, @category) { |i|
if !(i.depth >= 2)
"#{i.root.name if !i.parent_id.nil? } #{'>' unless !i.parent_id} #{i.name}"
end
}.reject_if { |i|
i[0].nil? || i[0].strip.blank?
},
{include_blank:true},
class: 'select2 form-control'%>
这里的关键是检查Array of Arrays,看显示文本(每个Array的第一个元素)是否为空白。因为您实际上是将 " "
作为字符串返回,所以此检查会删除空格,然后查看生成的字符串是否为空。如果是这样,它会删除该元素。最终的 Array 将只包含那些显示包含一些非空白字符的元素。
您甚至可以进一步扩展它以添加管理用户检查,并在用户是管理员的情况下拒绝某些选项。
或者,您也可以考虑覆盖 Category
的 move_possible?
方法。但是,我认为您的业务逻辑太复杂,无法走这条路,并且可能会在您的模型中引入一些反模式。但是,这是一个选项,也可以完成任务。
希望对您有所帮助!