在 ActiveAdmin 中显示复选框而不是文本输入
Show checkboxes instead of text input in ActiveAdmin
在模型 Code
中有一个名为 week_days
的字段,它可能是这样的 1100110
。
我想在 ActiveAdmin 表单中显示 7 个复选框,而不是经典的输入字段
form do |f|
f.inputs do
f.input :name
f.input :week_days
end
f.actions
end
所以我想在模型中写一个这样的映射器
def week_days_checkboxes
[
['sunday', 1],
['monday', 1],
['tuesday', 1],
['wednesday', 1],
['thursday', 1],
['friday', 1],
['saturday', 1]
]
end
def week_days_checkboxes=(week_days_checkboxes)
@week_days = week_days_checkboxes.reverse.join.to_i(2)
end
然后把表单输入改成这样
f.input :week_days_checkboxes, as: :check_boxes
但它不起作用。我必须做什么?
PS:每对的第二个值应为1或0,基于字段week_days
的每个值
非常感谢
由于以下几个原因它不起作用:
- 在 AR 模型中分配实例变量不会实现您想要的。您应该使用
self[:column_name]= value
或 write_attribute(:column_name, value)
(我认为后者更能揭示意图)。对于阅读,您可以使用 self[:column_name]
或 read_attribute
方法。
- 当您 post 带有复选框或多个 select 离子的表单时,只有 selected 值会被发送回服务器(浏览器就是这样工作的)。这意味着如果你只 select 一天,数组的值将永远是
['', '1']
,不管你是哪一天 select。在这种情况下,基本上使用统一值不是解决问题的方法。
从 week_days_checkboxes
方法返回一个数组数组将不会显示选项列表,因为它表示 值 而不是选项。您必须明确设置集合。
f.input :week_days, as: :check_boxes, collection: week_days_for_select
其中 week_days_for_select
return 是一个合适的列表。
当您编辑现有模型时,先前 selected 的天数将不会 selected 在复选框列表中。为此,您需要 return 一个与复选框输入值匹配的值列表。
一个解决方案可能是:
在您看来:
f.input :week_days, as: :check_boxes, collection: Date::DAYNAMES
然后在您的模型中为 week_days
创建一个包装器,以便它接受一个列表并将其转换为整数,反之亦然。
def week_days
return [] if read_attribute(:week_days).blank?
# first you have to convert the integer to a binary array
w = read_attribute(:week_days)
days_as_binary = Math.log2(w).floor.downto(0).map { |nth_bit| w[nth_bit] }
# alternatively
# days_as_binary = read_attribute(:week_days).to_s(2).split('').map(&:to_i)
# make sure it has an element for every day of the week
padded_binary = [0] * (7 - days_as_binary.size) + days_as_binary
# map the binary array to day names
padded_binary.each_with_index.map do |d, idx|
Date::DAYNAMES[idx] if d == 1
end.compact
end
def week_days=(values)
days = Date::DAYNAMES.map { |d| values.include?(d) ? 1 : 0 }
write_attribute(:week_days, days.join.to_i(2))
end
尽管我认为将 selected 天数表示为整数并不是您的最佳选择。如果您使用的是 PostgreSQL,AR 4+ 对数组有很好的支持——您可以将天数列表保存到数据库中。
在模型 Code
中有一个名为 week_days
的字段,它可能是这样的 1100110
。
我想在 ActiveAdmin 表单中显示 7 个复选框,而不是经典的输入字段
form do |f|
f.inputs do
f.input :name
f.input :week_days
end
f.actions
end
所以我想在模型中写一个这样的映射器
def week_days_checkboxes
[
['sunday', 1],
['monday', 1],
['tuesday', 1],
['wednesday', 1],
['thursday', 1],
['friday', 1],
['saturday', 1]
]
end
def week_days_checkboxes=(week_days_checkboxes)
@week_days = week_days_checkboxes.reverse.join.to_i(2)
end
然后把表单输入改成这样
f.input :week_days_checkboxes, as: :check_boxes
但它不起作用。我必须做什么?
PS:每对的第二个值应为1或0,基于字段week_days
非常感谢
由于以下几个原因它不起作用:
- 在 AR 模型中分配实例变量不会实现您想要的。您应该使用
self[:column_name]= value
或write_attribute(:column_name, value)
(我认为后者更能揭示意图)。对于阅读,您可以使用self[:column_name]
或read_attribute
方法。 - 当您 post 带有复选框或多个 select 离子的表单时,只有 selected 值会被发送回服务器(浏览器就是这样工作的)。这意味着如果你只 select 一天,数组的值将永远是
['', '1']
,不管你是哪一天 select。在这种情况下,基本上使用统一值不是解决问题的方法。 从
week_days_checkboxes
方法返回一个数组数组将不会显示选项列表,因为它表示 值 而不是选项。您必须明确设置集合。f.input :week_days, as: :check_boxes, collection: week_days_for_select
其中
week_days_for_select
return 是一个合适的列表。当您编辑现有模型时,先前 selected 的天数将不会 selected 在复选框列表中。为此,您需要 return 一个与复选框输入值匹配的值列表。
一个解决方案可能是:
在您看来:
f.input :week_days, as: :check_boxes, collection: Date::DAYNAMES
然后在您的模型中为 week_days
创建一个包装器,以便它接受一个列表并将其转换为整数,反之亦然。
def week_days
return [] if read_attribute(:week_days).blank?
# first you have to convert the integer to a binary array
w = read_attribute(:week_days)
days_as_binary = Math.log2(w).floor.downto(0).map { |nth_bit| w[nth_bit] }
# alternatively
# days_as_binary = read_attribute(:week_days).to_s(2).split('').map(&:to_i)
# make sure it has an element for every day of the week
padded_binary = [0] * (7 - days_as_binary.size) + days_as_binary
# map the binary array to day names
padded_binary.each_with_index.map do |d, idx|
Date::DAYNAMES[idx] if d == 1
end.compact
end
def week_days=(values)
days = Date::DAYNAMES.map { |d| values.include?(d) ? 1 : 0 }
write_attribute(:week_days, days.join.to_i(2))
end
尽管我认为将 selected 天数表示为整数并不是您的最佳选择。如果您使用的是 PostgreSQL,AR 4+ 对数组有很好的支持——您可以将天数列表保存到数据库中。