0

Submit_tag not submitting selected ids of the checkbox_tag.

here is the code :

<%= form_tag pattendance_attendances_path, method: :put do %>
  <% if coordinator_signed_in? || admin_signed_in? %>
    <ul class="list-group">
    <li class="list-group-item">
    <%= radio_button_tag "round", 1 , true %> Round 1</li>
    <li class="list-group-item">
    <%= radio_button_tag "round", 2 %> Round 2  </li>
    <li class="list-group-item">
    <%= radio_button_tag "round", 3 %> Round 3  </li>
    <li class="list-group-item">
    <%= radio_button_tag "round", 4 %> Round 4  </li>
    <li class="list-group-item">
    <%= radio_button_tag "round", 5 %> Round 5  </li>
    </li>       
    <li class="list-group-item">
      <%= radio_button_tag "mark_present", "present" , true %> Present <br>
      <%= radio_button_tag "mark_present", "absent" %>Absent 
    </li><br>
    <li class="list-group-item">
    <%= submit_tag "Mark Attendance"%></li>
  </ul>
  <% end %>
  </div>
 <div class="table-responsive">  
 <div class="col-md-8">
 <table class="table table-hover">
 <thead>
 <tr>
  <th>Mark</th>
  <th><%= model_class.human_attribute_name(:team_id) %> ID</th>
  <th><%= model_class.human_attribute_name(:event_id) %> Name</th>
  <th><%= model_class.human_attribute_name(:round) %></th>
  <th><%= model_class.human_attribute_name(:status) %></th>
  <th><%=t '.actions', :default => t("helpers.actions") %></th>
 </tr>
</thead>
<tbody>
 <% @attendances.each do |attendance| %>
  <tr>
    <td><%= check_box_tag "a_ids[]", attendance.id %></td> 
    <td><%= attendance.team_id %></td>
    <td><%= attendance.event_id %></td>
    <td><%= attendance.round %></td>
    <td><%= attendance.status %></td>
    <td>
      <%if admin_signed_in? %>
      <%= link_to t('.edit', :default => t("helpers.links.edit")),
                  edit_attendance_path(attendance), :class => 'btn btn-default btn-xs' %>
      <%= link_to t('.destroy', :default => t("helpers.links.destroy")),
                  attendance_path(attendance),
                  :method => :delete,
                  :data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) },
                  :class => 'btn btn-xs btn-danger' %>

      <%end%>
      <%= link_to t('.show', :default => t("helpers.links.View details")),
                   attendance, :class => 'btn btn-default btn-xs' %>  
       </td>
       </tr>
     <% end %>
     </tbody>
    </table>
     </div>
    </div>  
    <% end %>

Controller Code:

  def pattendance
params[:a_ids]
if params[:mark_present]=="present"
  Attendance.where(id: params[:a_ids]).update_all(status: 'Present', round: params[:round])
else
  Attendance.where(id: params[:a_ids]).update_all(status: 'Absent', round: params[:round])
end    
redirect_to attendances_url
end

The motive behind implementing this method is to mark attendance of all the teams registered in the particular event. The checkboxes are present to select multiple teams. I am selecting "Attendance.ids" because a team can participate in multiple events. So selecting Team IDS can mark attendance for the team in all the events. To make it unique for each event I'm using attendance ids.

After selecting rounds from radio buttons and status(present or absent) and clicking on mark attendance submit_tag it should update the values of the selected checkboxes. BUT Sometimes values are passed and sometimes they are not.

Please tell me what is the problem in this code. It would be really helpful.

Console : I tried to update the round of selected checkbox to "2" and status as "present"

  Parameters: {"utf8"=>"✓", "authenticity_token"=>"2uzivV42tLjwuUd+QyEHvL6tCa8ZCE8xRbgJ5k7ueEcV9oaQt5yLafKmZTiFceZEY9B3wyY52qxL1f0hvqQ47A==", "round"=>"2", "mark_present"=>"present", "commit"=>"Mark Attendance"}

Coordinator Load (0.1ms)
SELECT "coordinators".* FROM "coordinators" WHERE "coordinators"."id" = ? ORDER BY "coordinators"."id" ASC LIMIT 1 [["id", 1]] SQL (0.2ms)
UPDATE "attendances" SET "status" = 'Present', "round" = 1 WHERE "attendances"."id" IS NULL Attendance Load (0.1ms) SELECT "attendances".* FROM "attendances" WHERE "attendances"."id" IS NULL Redirected to http://localhost:3000/attendances Completed 302 Found in 5ms (ActiveRecord: 0.4ms)

It didn't pass the selected checkbox values after clicking on submit button. The values don't update when I go back from show page to index page. But after refreshing it works consistently

7
  • You can't use checked="checked" in a Ruby context. All you're doing is creating a local variable named checked which has the value of "checked". Commented Mar 7, 2016 at 14:51
  • Thanks pointing it out. But this can solve my problem ? Commented Mar 7, 2016 at 14:52
  • actually it is an attribute which pre-selects the radio buttons when the form loads, now all the radio buttons are not pre-selected. Commented Mar 7, 2016 at 14:55
  • No, you are wrong. That isn't how Ruby works. The 3rd argument to radio_button_tag is a boolean which indicates whether the field is checked. You're using checked="checked" which works purely by coincidence. The correct way to check the radio tag by default is to simply use radio_button_tag "round", 1, true. Commented Mar 7, 2016 at 15:01
  • Thanks I've changed my code but still there is some problem :| submit button is not working properly everytime :( Commented Mar 7, 2016 at 15:05

3 Answers 3

1

I'll give you some points for creativity - but there is a much simpler way to accomplish creating / updating multiple associations at once.

First make sure you have the modeling down:

class Event < ActiveRecord::Base
  has_many :registrations, dependent: :destroy
  has_many :teams, through: :registrations
  has_many :rounds, dependent: :destroy
  has_many :attendences, through: :rounds
  validates_uniqueness_of :name
end

class Team < ActiveRecord::Base
  has_many :registrations, dependent: :destroy
  has_many :events, through: :registrations
  has_many :attendences, dependent: :destroy
  has_many :rounds, through: :attendences

  validates_uniqueness_of :name
end

# Many To Many Join model between Event and Team
class Registration < ActiveRecord::Base
  belongs_to :event
  belongs_to :team
end

class Round < ActiveRecord::Base
  belongs_to :event
  has_many :attendences, dependent: :destroy
  has_many :attending_teams, through: :attendences, source: :team
end

class Attendence < ActiveRecord::Base
  belongs_to :team
  belongs_to :round
  has_one :event, through: :round
end

You'll notice here that we are using a table for "rounds" - if you are modeling a domain such as a conference you definatly want a table to store each sub event (class, talk etc). You don't want to use a weak implicit linking in your attendences table!

Armed with this creating a form for a round which lets you set which lets you set which teams have participated is a breeze:

<%= form_for(@round) |f| %>
  <div class="field">
    <% f.label(:attending_teams_ids) %>
    <% f.collection_check_boxes(:attending_teams_ids, @round.event.teams, :id, :name) %>
  </div> 
  <% f.submit %>
<% end %>

Rails has many useful helpers like collection_check_boxes for creating inputs from an association.

If you needed to update multiple Rounds at once you would use accepts_nested_attributes together with fields_for. However this is a pretty advanced topic and whole tutorial in itself so I'll leave it up to you to read a few tutorials and figure it out.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot for designing it for me , I really appreciate it. :) I will implement this code but I have to make the above code work as well. I am not able to figure out the problem.
0

I think the problem is that check_box_tags don't send any value when not checked, so unless you check at least one check box in the attendances group, you won't get anything in the a_ids parameter in the controller.

For this to work, you'd need to reset the a_ids param to a blank value if no check box checked. I.e. add something like this in your controller:

 def pattendance
   params[:a_ids] ||= []
   ...
 end

See also the "small gotcha" section in this SO question.

14 Comments

Thanks for your reply. The link you have provided performs a different task. In that application the user wants to remove categories (which are already checked) by removing the checks from them. Here my case is completely different. Though I tried to implement this code but it didn't help at all. :(
The link should have further explained the Rails behavior when using multiple check_box_tags with an array param - that the param is totally undefined in the controller when no check_box is checked. I can see nothing wrong with your code, I even took the code and tested it and the behavior was consistent - I got the error you describe only when NO check box was checked. So are you claiming that you get the a_ids param nil even if you HAVE checked a check box? If so, the error must come from somewhere else, I think.
Thanks for testing my code. If you have encountered consistent behavior then what can be the problem in mine ? -_- Yeah I am also thinking now that error can be from somewhere else but how can it be ?
The values don't update when I go back from show page to index page. But after refreshing it works consistently.
Sorry, can you clarify the last comment? Are you using the back browser button (in that case no wonder you see historical, not updated, data)? And also, what have the show and index actions have in common with the edit form you posted in the Q? I have to say, I am confused.
|
0

I solved this problem by moving my JS to onReady as turbolinks was caching the page.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.