如何默认collection_check_boxes勾选?

How to default collection_check_boxes to checked?

我尝试默认选中这一行 <%= f.collection_check_boxes :committed, checked, Date::ABBR_DAYNAMES, :downcase, :to_s, %>

db t.text "committed".

我尝试了 checkedtrue 的变体,但也许我忽略了一些东西。

这是其中的 Gist

您正在使用 form_for,因此 f 是一个表单生成器。这意味着它绑定到您初始化它的对象,我们称它为 @habit。由于您在表单生成器上调用 collection_check_boxes,它会执行类似 @habit.send(:commit) 的操作来咨询是否应该选中该复选框,而目前(显然)它不是。换句话说,如果你想使用 form_for 你需要在模型本身中表示这个 "everything is checked" 事实。

现在我不确定你的模型层是什么样子的,所以我将解决几个场景。如果你有这样的 has_and_belongs_to_many 关系:

class Habit < ActiveRecord::Base
  has_and_belongs_to_many :committed_days
end

class CommittedDay < ActiveRecord::Base
  has_and_belongs_to_many :habits
  # let's assume it has the columns :id and :name
  # also, let's assume the n:m table committed_days_habits exists
end

然后我认为最简单的方法是在控制器本身做这样的事情:

def new
  @habit = Habit.new
  @habit.committed_day_ids = CommittedDay.all.map(&:id)
end

然后在您的 ERB 中执行:

<%= f.collection_check_boxes(:committed_day_ids, CommittedDay.all, :id, :name)

现在,使用“拥有并属于许多”来执行此操作可能有点矫枉过正,尤其是对于星期几(这意味着 CommittedDay table 有 7 条记录,每天一条,这有点尴尬)。因此,您还可以考虑简单地将一组星期几序列化到数据库中,然后确保该列的默认值包含所有这些。

ERB 将与您所写的类似:

<%= f.collection_check_boxes :committed, Date::ABBR_DAYNAMES, :downcase, :to_s %>

如果您使用的是 Postgres,您的 class 可以很简单:

class Habit < ActiveRecord::Base
end

序列化代码将在迁移中:

# downcase is used since in the ERB you are using :downcase for the id method
t.text :committed, default: Date::ABBR_DAYNAMES.map(&:downcase), array: true

如果您不使用 Postgres,您可以使用 Rails 与数据库无关的序列化:

class Habit < ActiveRecord::Base
  serialize :committed, Array
end

然后您的迁移将如下所示:

t.text :committed, default: Date::ABBR_DAYNAMES.map(&:downcase).to_yaml

这里是关于如何将 checked 作为默认值添加到 collection_check_boxes 表单助手的快速回答,因为我花了一些时间才弄明白。把它分成一个块,你可以设置检查并添加类。更多信息,请访问 http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_check_boxes

<%= f.collection_check_boxes(:author_ids, Author.all, :id, :name) do |b| %>
  <%= b.label(class: "check_box") { b.check_box(checked: true, class: "add_margin") + b.text } %>
<% end %>