Button event trigger - ruby-on-rails

I am having trouble understanding as how do you trigger specific button event when using Ruby on Rails. For example I have a mini form inside a table as so (View side of MVC):
<%= form_tag do %>
<% if student.floor_pref == '1st' %>
<td><%= select_tag 'room', options_for_select(#first_floor.map { |value| [value,value]}, #selected_room) %></td>
<% end %>
<% if student.floor_pref == '2nd' %>
<td><%= select_tag 'room', options_for_select(#second_floor.map { |value| [value,value]}, #selected_room) %></td>
<% end %>
<% if student.floor_pref == '3rd' %>
<td><%= select_tag 'room', options_for_select(#third_floor.map { |value| [value,value]}, #selected_room) %></td>
<% end %>
<td><%= submit_tag 'Update' %></td>
<% end %>
How do I tell the controller that when the Update button is clicked inside the view to for example execute this code:
a = Student.find(3)
a.room_number = '2105'
a.save

Your button should be triggering a post-back to the server. You need to define an action in your controller, a route to reach that action, and set your forms action attribute to that route. Your action can then update the models and respond with a success or error message.

u should specify a route(a controller action to which the data is to be submitted) in the form tag. refer http://apidock.com/rails/ActionView/Helpers/FormTagHelper/form_tag for more details. considering that ur action is for 'edit' action from students controller and that data is to be posted to 'update', the view can be defined as
<%= form_tag student_path(#student), :method => :put do %>
...
<$= submit_tag 'Update' %>
and in the 'update' method, u can write the code to update student with the received params. I think u need to study basic rails functioning since it will save u time in future. u can refer http://guides.rubyonrails.org/getting_started.html Also, prefer using form_for rather than form_tag.

Related

Generate attendance view/form in rails for all students

I am new to Rails and I am struggling on something which sounds easy but can not get it to work. I have two models Students and Attendances.
Student model:
name lastname classroom_id
Attendance model:
present:boolean absent:boolean halfday:boolean attnd_date:date student_id
Students has_many :attendances and attendance belongs_to :student.
I can make an entry for individual student and take their attendance however I want to generate a view where I show all the students (or show all students for a given classroom) and next to each student name I would like to show the three checkboxes so that I can mark who is present and absent in one go rather than one by one and submit the form.
Any help here is much appreciated. Using Rails 4 and ruby 2.2.0
Thanks
You can make an edit action, where you will find the classroom for which you want to mark attendances.
class AttendancesController < ApplicationController
def edit
#classroom = Classroom.find(<classroom-id>)
end
def update
end
end
In your view edit.html.erb
<%= form_for(#classroom, url: '/attendances/:id', method: :put) do |f| %>
<table>
<%- #classroom.students.each do |student| %>
<tr>
<td><%= student.name %></td>
<td><%= checkbox_tag "attendances[#{student.id}][present]" %></td>
<td><%= checkbox_tag "attendances[#{student.id}][absent]" %></td>
<td><%= checkbox_tag "attendances[#{student.id}][halfday]" %></td>
</tr>
<% end %>
</table>
<%= f.submit %>
<% end %>
This way, when you submit the form, you will receive these params in your update action:
`{ attendances: { '1' => { present: false, absent: true, halfday: false }, '2' => { present: true, absent: false, halfday: false }, ... } }`.
Then you can write logic in your action to save these details to database.
Note: This is kind of pseudo code. Please check the syntax and options for different html tags.
Thanks to #Jagdeep Singh for getting me up and running. I have now made the process more simple so I can get my head around. I just want to get the list of all students and create their attendances.
My view:
<% #students = Student.all %>
<%= form_for(:attendances, url: '/admin/attendances/') do |f| %>
<table>
<%= #today %>
<th>Name</th><th>Present</th><th>Absent</th><th>halfday</th>
<%- #students.each do |student| %>
<tr>
<td><%= student.first_name %></td>
<td><%= check_box_tag "attendances[#{student.id}][present]" %></td>
<td><%= check_box_tag "attendances[#{student.id}][absent]" %></td>
<td><%= check_box_tag "attendances[#{student.id}][halfday]" %></td>
</tr>
<% end %>
</table>
<%= f.submit %>
<% end %>
when I click on create attendance button it just creates just one with record with all default params and.
I am sorry I am still learning but once I get my head around on how I can create attendances for all 10 students i have in one go.

how to stop cache from interfering with application logic

I'm trying to use Rails 4 cache digests in my app, but am finding that it interferes with a lot of application logic. For example, in this code, the links that are supposed to only be revealed where the current_user's id matches #user.id aren't working properly when I have the cache surrounding the code. Those links are visible to anyone who views the page.
<% cache #languages do %>
<% for language in #languages%>
<tr>
<td><%= language.name %> </td>
<% if current_user && current_user.id == #user.id %>
<td><%= link_to "edit", {:controller => 'lawyer_profiles', :action =>'show', :language_id =>"#{language.id}"}, {:class => "editarea #{language.id}"}%></td>
<td><%= link_to "destroy", language, :confirm => 'Are you sure?', :method => :delete %></td>
<% end %>
</tr>
<% end %>
<% end %>
In this code, the cache was interfering with the #question instance variable. For example, due to the presence of the cache, when I clicked on the link to "Add An Answer," it had my answering a different #question than the one I should have been answering, because the cache kept a memory of the instance variable on a page that I had already navigated away from.
<% cache #answers do %>
<% if #answers.empty? %>
<div class="row">
<h5>This question hasn't been answered yet: <% if can? :create, #answer %>
<% if current_user && !current_user.answers.map(&:question_id).include?(#question.id) %>
<%= link_to "Add an answer", new_question_answer_path(#question) %>
<% end %>
<% end %> </h5>
....some code not included
How can I stop the cache from interfering with logic like this?
You'll have to add the logic into the cache key.
So...
cache [#answers, current_user.answers.map...]
This will base the view on what the user's answer is...you may want to break down the rest into more fragment caches in addition to the above.

How to create multi checkboxes and attach them to controller action like Edit or Delete?

I have created a scaffold Phone and index.html.erb shows a simple table with list of phone and edit/delete options. Now i want to add jquery checkboxes so I can do bulk delete or move actions. See attached image here
Can someone give me any idea/pointers on how to do it ?
Edit - this is the index.html.erb file
<% #phones.each do |phone| %>
<tr>
<td><%= phone.model %></td -->
<td><%= phone.type %></td>
</tr>
<% end %>
there is no form here so I am not sure I can use form_tag helpers or am I confusing something ?
Thanks
This would be a starting point, a form with the check boxes.
<%= form_tag(:controller => "phone", :action => "bulk_update", :method => "PUT") %>
<%= check_box_tag(:blackberry) %>
<%= label_tag(:pet_dog, "Blackberry") %>
<%= check_box_tag(:Nokia) %>
<%= label_tag(:pet_cat, "Nokia") %>
<%= submit_tag("Update") %>
<% end %>
Then a controller action called bulk_update and you could delete/update the records based on what has been submitted.
EDIT: You will also want to create a route in routes.rb for this.
Wrap the table in a form helper.
<%= form_tag foo_path do %>
# ...
<% #phones.each do |phone| %>
<tr>
<td><%= check_box_tag "selected[]", phone.id %></td>
<td><%= phone.model %></td>
<td><%= phone.type %></td>
</tr>
<% end %>
# ...
<%= button_tag "Do something" %>
<% end %>
This creates a form, with a checkbox in every row of the table. Replace foo_path with the route helper that you want to use. The value of the selected checkboxes will be passed to your controller action in the array params[:selected], where you can do with them as you wish. The values of each checkbox will be the id for the corresponding phone object.

Link_to another view ruby on rails

I am trying to use the link_to feature to link one view to another.
The view i am calling link_to is app/views/instructors/show.html.erb and that snippet of code looks like this (namely, the second to last line of it)
<% provide(:title, #instructor.login) %>
<% courses = Course.where(:instructor_ID => #instructor.id) %>
<div class="span2">
<h1 align=center ><%= #instructor.login %></h1>
<%= link_to "Add course", new_course_path(:instructor_ID\
=> #instructor.id), :class => "btn" %>
<br>
<br>
<%= link_to "Remove course", delete_course_path(courses), :class => "btn"%>
</div>
The view I am trying to link to is is app/views/courses/show_all.html.erb and looks like this:
<% #courses.each do |course| %>
<tr>
<td><%= course.course_name %></td>
<td><%= course.instructor_ID %></td>
<td><%= link_to 'Show', course %></td>
<td><%= link_to 'Edit', edit_course_path(course) %></td>
<td><%= link_to 'Destroy', course, :method => :delete, :data => { :confirm => 'Are you sure?' } %></td>
</tr>
delete_course_path routes to app/views/courses/show_all.html.erb shown above. When I try the code above, I get the following error:
undefined method `each' for nil:NilClass
At this line:
<% #courses.each do |course| %>
Any ideas what i'm missing in my link_to?
In your show_all action, you should define a #courses instance variables. This is
<% courses = Course.where(:instructor_ID => #instructor.id) %>
not passed to show_all.html.erb.
An instance variables is a variable passed from action of controller to the view corresponding.
I suppose when you show page of instructor, your route will like this: /instructors/:id, so maybe in your show_all action of instructor controller, you need something like:
def show_all
#courses = Course.where(instructor_ID: params[:id])
render 'courses/show_all'
end
This means that #courses is nil. Did you set it in your show_all action of your controller? E.g.
def show_all
#courses = Course.all
end
Also, in your show view, you set courses to a collection of Course objects, but your "Remove course" link looks like you only want to delete one course. Why do you use the delete_course route to link to your show_all view?

I am having trouble with my first project in ruby on rails

Here's my index action in the books controller: http://pastebin.com/XdtGRQKV
Here's the view for the action i just mentioned: http://pastebin.com/nQFy400m
Here's the result without being logged in: http://i.imgur.com/rQoiw.jpg
Here's the result when i'm logged in with the user 'admin': http://i.imgur.com/E1CUr.jpg
So the problem is that, in the view, before line 25 the 'user' variable seems to be empty ( or not loaded), and after line 25 the variable 'user' has the expected values.
I have tried initializing a variable in the index method of the books controller but get exactly the same results.
Thanks in advance!
BTW had to make the links text because of stackoverflow limit.
This:
user = User.find_by_id(session[:user_id])
should be in controller, not in view (MVC!) like this:
#user = User.find_by_id(session[:user_id])
Then in your view, as #Voyta answered, use <%= #user.username %>. Code inside <% %> is evaluated, but not rendered, so if you want to put result in your html, you need to add =.
And all yours if user and if user.admin == 1 would look much better this way:
<% if user %>
<td><%= link_to 'Show', book %></td>
<% if user.admin == 1 %>
<td><%= link_to 'Edit', edit_book_path(book) %></td>
<td><%= link_to 'Delete', book, :confirm => 'Are you sure?', :method => :delete %></td>
<% end
end
%>
If you use if in single line like here:
<%
if user
if user.admin == 1
%>
<%= link_to 'New book', new_book_path %>
<%
end
end
%>
You can write the same like this:
<%= link_to 'New book', new_book_path if user && user.admin == 1 %>
You didn't output user.username. It should be <%= user.username %>, not <% user.username %>

Resources