Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to default collection_check_boxes to checked?

I have this line that I'm trying to default to checked <%= f.collection_check_boxes :committed, checked, Date::ABBR_DAYNAMES, :downcase, :to_s, %>

In db t.text "committed".

I tried variations of checked & true, but maybe I overlooked something.

Here's the Gist of it.

like image 646
AnthonyGalli.com Avatar asked Aug 01 '15 20:08

AnthonyGalli.com


2 Answers

Here is a quick answer on how to add checked as the default to the collection_check_boxes form helper since it took me some time to figure it out. Break it into a block and you can set checked and add classes. More info at 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 %>
like image 153
Steve Carey Avatar answered Nov 03 '22 00:11

Steve Carey


You are using a form_for, so that f is a form builder. This means that it is bound to the object you initialized it with, let's call it @habit. Since you're calling collection_check_boxes on the form builder, it will do something like @habit.send(:commit) to consult whether or not it should have the check box checked, and currently (apparently) it is not. In other words, if you want to use form_for you need to have this "everything is checked" fact represented in the model itself.

Now I am not sure what your model layer looks like, so I'll address a few scenarios. If you have a has_and_belongs_to_many relationship like this:

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

Then I think the easiest way is in the controller itself do something like this:

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

And in your ERB do:

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

Now, it might be an overkill to do this with a has-and-belongs-to-many, especially with days of week (it means the CommittedDay table has 7 records, one for each day, which is kinda awkward). So you could also consider simply serializing an array of days of week into the db, and then just make sure the default for that column contains all of them.

The ERB will be similar to what you wrote:

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

If you're using Postgres your class can be simply:

class Habit < ActiveRecord::Base
end

And the serialization code would be in the migration:

# 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

If you are not using Postgres, you can use Rails serialization which is DB agnostic:

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

And then your migration would look like this:

t.text :committed, default: Date::ABBR_DAYNAMES.map(&:downcase).to_yaml
like image 23
AmitA Avatar answered Nov 03 '22 00:11

AmitA