开发者

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').

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜