如何使用 SimpleForm 正确存储多个复选框值?

How do I properly store multiple checkboxed values using SimpleForm?

基本上我想在我的表单中创建一个接受复选框的选项(0 到接受的所有值)。

我喜欢枚举结构,因为我获得了在数据库中存储整数的性能速度,但我可以在我的代码中引用该符号。但是,我怀疑当我像复选框一样存储多个值时是否可以使用枚举。

所以我认为它最有效的方式是将它存储为一个字符串,它也是一个数组。所以像这样:

#  refactor_rule           :string           default([]), is an Array

那么我的表格是这样的:

<%= f.input :refactor_rule, collection: ["dry", "concise", "performant"], as: :check_boxes, class: "form-control" %>

这种方法的问题是当我只存储 1 个或 2 个选项(即不是全部)时,属性如下所示:

q.refactor_rule
=> ["", "dry", "concise"]

我讨厌,因为 [0] 处的空值。

所以我的问题如下:

  1. 实现此目标的最高效方法是什么?请注意,我的复选框中的选项是静态的,但该字段需要接受多个而不是 1?
  2. 如何只存储选中的值而不存储空值?
  3. 有什么方法可以利用 Rails 内置枚举功能,即使我正在存储多个值?

你总是可以用这样的东西来 "clean" 你的属性:

q.refactor_rule.reject!(&:empty?)

这将拒绝数组中的所有空元素。介意的!reject! 替换它没有空元素,reject 只是 returns 它。你来电!

如果你真的需要在数据库中存储一个数组,你可以在你的迁移中这样做:

create_table :products do |t|
   t.text :tags, array: true, default: []
end

(来自 Plataformatec 的 this blog post

您应该考虑将布尔值存储为位域。这种方法将多个布尔值(标志)转换为单个整数列,其中每个标志在整数中都有自己的位位置。这当然会对性能产生巨大的积极影响 - 您可以使用 & operator(在 MySQL 中)搜索标志的任意组合,而不是尝试在文本列中搜索子字符串。

看看 flag_shih_tzu or the bitfields 宝石。这两个 gem 都增强了 Active Record,因此所有标志都像模型对象的单独 "virtual" 属性一样,它们提供了方便的方法来搜索这些属性。为此,您可能需要重写 simple_form 表单以使用 3 个单独的复选框而不是一个。