我试图默认选中这一行<%= f.collection_check_boxes :committed, checked, Date::ABBR_DAYNAMES, :downcase, :to_s, %>
在dBt.text "committed"
我尝试了不同的checked&true,但也许我忽略了一些东西。
这是它的Gist

最佳答案

您正在使用form_for,因此f是表单生成器。这意味着它被绑定到初始化它的对象,我们称它为@habit。由于您在表单生成器上调用collection_check_boxes,它将执行类似于@habit.send(:commit)的操作,以查看是否应选中复选框,而当前(显然)不应选中。换句话说,如果您想使用form_,那么您需要在模型本身中表示这个“一切都已检查”的事实。
现在我不确定您的模型层是什么样子的,所以我将讨论几个场景。如果你有这样的关系:

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)

现在,用一个has和一个属于许多人的has来做这件事可能是一种过度的做法,尤其是一周中的几天(这意味着committedday表有7条记录,每天一条,这有点尴尬)。因此,您还可以考虑简单地将一周中的一组天序列化到数据库中,然后确保该列的默认值包含所有这些天。
ERB将类似于您所写的内容:
<%= f.collection_check_boxes :committed, Date::ABBR_DAYNAMES, :downcase, :to_s %>

如果你使用Postgres,你的课程可以很简单:
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

07-28 01:54
查看更多