【问题标题】:Show checkboxes instead of text input in ActiveAdmin在 ActiveAdmin 中显示复选框而不是文本输入
【发布时间】:2015-01-23 16:16:48
【问题描述】:

在模型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的每个值

非常感谢

【问题讨论】:

  • 尝试选择:f.input :week_days_checkboxes, as: :select,, multiple: true, collection: [ ['sunday', 1], ['monday', 1], ['tuesday', 1], ['wednesday', 1], ['thursday', 1], ['friday', 1], ['saturday', 1] ]
  • 我想使用使用模型中指定方法的复选框

标签: ruby-on-rails activeadmin formtastic


【解决方案1】:

它不起作用有几个原因:

  1. 在 AR 模型中分配实例变量不会达到您想要的效果。您应该使用self[:column_name]= valuewrite_attribute(:column_name, value)(我认为后者更能揭示意图)。对于阅读,您可以使用self[:column_name]read_attribute 方法。
  2. 当您发布带有复选框或多项选择的表单时,只有选定的值会被发送回服务器(这就是浏览器的工作方式)。这意味着如果您只选择一天,则无论您选择哪一天,数组的值都将始终为['', '1']。基本上,在这种情况下使用统一值不是可行的方法。
  3. week_days_checkboxes 方法返回一个数组数组将不会显示选项列表,因为它代表 而不是选项。您必须明确设置集合。

    f.input :week_days, as: :check_boxes, collection: week_days_for_select
    

    week_days_for_select 返回一个合适的列表。

    当您编辑现有模型时,之前选择的日期不会在复选框列表中被选中。为此,您需要返回与复选框输入值匹配的值列表。

一种解决方案可能是:

在你看来:

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

虽然我认为将所选日期表示为整数并不是您拥有的最佳选择。如果您使用的是 PostgreSQL,AR 4+ 对数组有很好的支持 - 您可以将天数列表保存到数据库中。

【讨论】:

    猜你喜欢
    • 2013-09-14
    • 1970-01-01
    • 1970-01-01
    • 2016-11-04
    • 2013-01-27
    • 1970-01-01
    • 2014-05-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多