How to ensure a rails f.check_box (not check_box_tag) is initially checked based on active record object attribute?
Having a heck of a time with this; I'm convinced I'm just not getting something completely obvious as I can't imagine this being this difficult intentionally. Everything else works in my form, but upon initial display, the check boxes are not checked when they should be. Here's the relevant erb:
<%= form_for :project, :url=>{:controller=>'projects', :action=>'update_permissions', :id=>@project.id} do |f| %>
<fieldset>
<% @project.contributors.each do |contributor| %>
<%= f.fields_for "contributors[#{contributor.id}]" do |c| %>
<ul id="PermissionsList" class="permissions开发者_运维百科-grid in-line clearfix full">
<li>
<ul class = "clearfix permission-row">
<li class="first">
<%= c.check_box :is_active %><label for="<%= contributor.id %>"><%= contributor.user.whole_name %></label>
</li>
<% @roles.each do |role| %>
<li><%= c.radio_button :role_id, role.id, :id=>"#{contributor.id}-#{role.id}" %><%= label "#{contributor.id}-#{role.id}", role.role_name %></li>
<% end %>
</ul>
<% end %>
</li>
</ul>
<% end %>
</fieldset>
I'm passing the is_checked attribute (for the current contributor) to the check_box helper. This is the proper way to do this correct? Here's what the generated markup looks like:
<ul class="clearfix permission-row">
<li class="first">
<input type="hidden" value="0" name="project[contributors[9]][is_active]"><input type="checkbox" value="1" name="project[contributors[9]][is_active]" id="project_contributors_9__is_active"><label for="9">Bill Hatch</label>
</li>
<li><input type="radio" value="1" name="project[contributors[9]][role_id]" id="9-1" style="display: none;"><label for="9-1_Reviewer" style="display: none;">Reviewer</label></li>
<li><input type="radio" value="2" name="project[contributors[9]][role_id]" id="9-2" style="display: none;"><label for="9-2_Tech. Reviewer" style="display: none;">Tech. reviewer</label></li>
<li><input type="radio" value="3" name="project[contributors[9]][role_id]" id="9-3" style="display: none;"><label for="9-3_Contributor" style="display: none;">Contributor</label></li>
</ul>
The value of the checkbox is 1, as it should be, so I'm a little confused as to why it's not displaying as checked. Like I said, I'm sure I'm just missing something obvious; no way can this be this hard;-)
There are a few things wrong with this form.
First of all, why not use rails to do the iteration for you? Second of all, html ids cannot start with digit. This approach should take care of populating the values correctly, since you're using form builder and not inserting the values by hand.
<%= form_for @project, :url => update_permissions_project_path(@project) do |f|
<fieldset>
<%= f.fields_for :contributors do |c| %>
<ul id="PermissionsList" class="permissions-grid in-line clearfix full">
<li>
<ul class = "clearfix permission-row">
<li class="first">
<%= c.check_box :is_active %>
<%= c.label :is_active, c.object.user.whole_name %>
</li>
<% @roles.each do |role| %>
<li>
<%= c.radio_button :role_id %>
<%= c.label :role_id, role.role_name %>
</li>
<% end %>
</ul>
</li>
</ul>
<% end %>
</fieldset>
<% end %>
The check_box form helper takes more than one argument. You need to pass in a value for "checked_value".
http://apidock.com/rails/ActionView/Helpers/FormHelper/check_box
Something like
<%= c.check_box :is_active, {}, @object.is_active %>
Or, you can update your "form_for" to refer to an object that has values instead of a class name.
Sometimes it's easier to drop to a tag helper, and cheat a little (last parameter is 'checked'):
<%= check_box_tag "project[contributors[#{contributor.id}]][is_active]", '1', true %>
Does this work?
I struggled with this but found I was overcomplicating things. If you are using check_box simply set a default value of true or false for that field in your database. Now my checkbox defaults to checked but will reflect the actual value if set in my model instance.
# For new instances, the onupdate field should default to checked
check_box :onupdate
rails g migration AddDefaultToWatchers
class AddDefaultToWatchers < ActiveRecord::Migration
def change
change_column :watchers, :onupdate, :boolean, :default => true
end
end
Here is how Rails 4 determines whether f.check_box
will be checked when initialized:
def checked?(value)
case value
when TrueClass, FalseClass
value == !!@checked_value
when NilClass
false
when String
value == @checked_value
else
if value.respond_to?(:include?)
value.include?(@checked_value)
else
value.to_i == @checked_value.to_i
end
end
end
suppose check_box here is: check_box(:post, :title)
, then
value is @post.title
@checked_value is the value of check_box's checked_value
argument (by default it's '1'
).
精彩评论