Rails - add a dropdown selection to index with db update on change - ruby-on-rails

I've added dropdown selections to forms before, but am having trouble getting them to work in the index view. I've read the API on this and can't get anything to work.
Basically, I've got a list of all tasks in the index view. I set the default in the db to 'No' in a migration. I want to be able to loop through all the tasks and have a dropdown selection appear with the options no, yes and partly. Then I want to be able to have the db update that task's field with the selection when it is made.
I can't get the dropdown to work - whenever I try using task.select, it says that select is a private method. I apologise, I'm fairly new to rails - any help anyone could give would be fantastic! How do I get the dropdown to work and how do I ensure that the db gets updated when the value is changed?
Thanks!
View code (here's what I have so far) - tasks/index:
<table class="table table-striped table-bordered">
<tr>
<th>Name</th>
<th>Category</th>
<th>Notes</th>
<th>Completed?</th>
<th></th>
<th></th>
<th></th>
</tr>
<% #tasks.each do |task| %>
<tr>
<td><%= task.name %></td>
<td><%= task.category %></td>
<td><%= task.notes %></td>
<td><%= task.select :complete, ['No','Yes','Partly'], :selected => 'No' %></td>
<td><%= link_to 'Show', task %></td>
<td><%= link_to 'Edit', edit_task_path(task) %></td>
<td><%= link_to 'Delete', task, confirm: 'Are you sure?', method: :delete %></td>
</tr>
<% end %>
</table>
UPDATE:
After more research, I've changed the line of code:
<td><%= task.select :complete, ['No','Yes','Partly'], :selected => 'No' %></td>
to:
<% form_for task do |f| %>
<td><%= select :task, :complete, [ ["Yes",2], ["Partly",1], ["No",0]] %></td>
<% end %>
This has stopped throwing up errors when I try and load the page, however, there is nothing where the 'form' should be - and nothing in the source code, these lines are skipped. How can I get this form to appear and how can I get it to change the database when the selection is changed? Thanks!

Suppose that Post::CATEGORIES = ["No", "Yes", "Partly"]
It depends on how you store task.category in your DB.
If it is an integer in (0, 1, 2)
form_for task do |f|
f.select :category, Post::CATEGORIES.map { |c| [c, Post::CATEGORIES.index(c)] }, :selected => task.category, :include_blank => true
end
If it is a string in ("No", "Yes", "Partly")
form_for task do |f|
f.select :category, Post::CATEGORIES, :selected => task.category, :include_blank => true
end
To be able to make a change to your models, you'll of course need to submit the form somehow. You could use one form for all the records with:
One submit button: you'll need to change the form and your update controller to receive multiple tasks
A form per task with multiple submit buttons: your user will need to submit each time he changes the category
Submit using AJAX each time the user changes the category.
Good luck

I think what you're looking for is a form_for and then a f.select. You need to create the form first and then f.select is the drop down. Something like this:
form_for task do |f|
f.select("task", "category", Post::CATEGORIES, {:include_blank => true})
end
replace Post::CATEGORIES with the list of options for the dropdown

Related

Update function Ruby

I want this function, if the status of progress so that it changes on the done exactly at those IDs where the status is for the conditions, at the moment I get an error and secondly, if it worked without errors, then it would change everything, but I need if progress is finished and if you don’t, then on progress
I selected three records through the form using a checkbox ...
in the function, I want that if the status of the record from database is "done", then it should change to "progress", if the status is "progress" in the record, then it should be changed to "done". Now I click on "submit_tag" and I get an error and in any case this code will not work the way I want it, I want everything to be conditional.
I am completely in ruby, help please, maybe the problem is in the syntax
no implicit conversion from nil to integer
def update_me
#iteam = Iteam.find(params[:id])
if #iteam[params[:status]] == 'progress'
Iteam.where(params[:id]).update_all(status: 'DONE')
else
Iteam.where(params[:id]).update_all(status: 'progress')
end
end
index view
<%= form_tag update_me_iteams_path, :method =>'put' do %>
<table>
<tr>
<th>Title</th>
<th>Text</th>
<th>Status</th>
<th></th>
</tr>
<% #iteams.each do |iteam| %>
<tr>
<td><%= iteam.id %></td>
<td><%= iteam.title %></td>
<td><%= iteam.text %></td>
<td><%= iteam.status %></td>
<td><%= link_to 'Show', iteam_path(iteam) %></td>
<td>
<%= check_box_tag "id[]", iteam.id %>
</td>
</tr>
<% end %>
</table>
<%= submit_tag "Edit Checked" %>
<% end %>
Please Use following to find with id:
Iteam.where(id: params[:id])
or you can use the following
Iteam.find(params[:id])

Rails Access Association attributes issue

I have an html table that renders a partial as follows
<tbody id="horse_logs">
<%= render #horse_logs %>
</tbody>
This calls _horse_log.html.erb and iterates through each element in #horse_logs
<tr id="<%= dom_id(horse_log) %>">
<td><%= horse_log.id %></td>
<td><%= horse_log.name %></td>
<td><%= horse_log.boarder.first_name%></td> <!-- This is the association I want to access -->
<td><%= horse_log.arrival_date %></td>
<td><%= horse_log.monthly_boarding_fee %></td>
<td><%= link_to '<i class="link blue large id card icon"></i>'.html_safe, horse_log_path(horse_log)%></td>
<td><%= link_to '<i class="link green large edit icon"></i>'.html_safe, edit_horse_log_path(horse_log), remote: true %></td>
<td><%= link_to '<i class="link red large remove icon"></i>'.html_safe, horse_log_path(horse_log), method: :delete, :data => {:confirm => 'Are you sure?'}, remote: true %></td>
</tr>
The issue is that accessing the boarder association inside the partial gives the following error
undefined method `first_name' for nil:NilClass
So basically the way rails implements this, they seem to be stripping the association data. The association is set up in my models correctly, and I can access the data in all other ways EXCEPT inside the partial.
How can I force rails to include the entire association.
here is my controller method if this helps
def index
#horse_logs = HorseLog.all.paginate(:page => params[:page], :per_page => 9).order("created_at DESC")
#horse_log = HorseLog.new
end
There may be a better way to do this but I would try.
<tbody id="horse_logs">
<% #horse_log.each do |horse_log| %>
<%= render 'horse_logs', horse_log: horse_log %>
<% end %>
</tbody>
If you get the same error, then you will need to make sure that your association is set up correctly.
Does every horse_log have a boarder? If not, you will get this error every time you run this code. you will need to check that hourse_log.boarder isn't nil.
For a quick fix, try this. It will prevent the error and return nil gracefully
<td><%= horse_log.try(&:boarder).try(&:first_name) %></td>

Update a time field dynamically when checking a checkbox in Rails & dynamically updating the DB without using a Submit button

I'm trying to do the following:
1) When a checkbox gets checked, I want the Time of Arrival box to be updated with the time when the checkbox got checked dynamically.
I don't want to be pressing a submit button or anything of that sort, it should be dynamic, via AJAX i guess.
My current code looks like this:
<table border="1">
<tr>
<td><b>Present</b></td>
<td><b>Student ID</b></td>
<td><b>First Name</b></td>
<td><b>Last Name</b></td>
<td><b>Time of Arrival</b></td>
</tr>
<% #register.student_registers.each do |student_register| %>
<tr>
<td><%= check_box_tag "student_registers_ids[#{student_register.id}]", student_register.id, student_register.present?%></td>
<td><%= student_register.student.university_id%></td>
<td><%= student_register.student.first_name.titlecase%></td>
<td><%= student_register.student.last_name.titlecase%></td>
<td><%= student_register.time_of_arrival %></td>
</tr>
<% end %>
</table>
2) The other thing I want to do is to update the record in the database, as soon as the Present checkbox gets checked, without having to press a Submit button. This will be done in the model#show page, not the model#edit page.
Any suggestions?
EDIT:
I changed the code around, but it still isn't working...
<table border="1">
<tr>
<td><b>Present</b></td>
<td><b>Student ID</b></td>
<td><b>First Name</b></td>
<td><b>Last Name</b></td>
<td><b>Time of Arrival</b></td>
</tr>
<% form_tag :remote => true %>
<% #register.student_registers.each do |student_register| %>
<tr>
<td><%= check_box_tag "student_registers_ids[#{student_register.id}]",
student_register.id, student_register.present?,
:disabled => false,
:onclick => 'popup ' %></td>
<td><%= label_tag 'UniversityId', student_register.student.university_id%></td>
<td><%= label_tag 'FirstName', student_register.student.first_name.titlecase%></td>
<td><%= label_tag 'LastName', student_register.student.last_name.titlecase%></td>
<td><%= label_tag student_register.time_of_arrival, nil, :class => 'TimeOfArrival'%> </td>
</tr>
<% end %>
</table>
<%= submit_tag "Save", :confirm => "You sure", :onclick => 'alert("Test")'%>
Please, anybody help....
Here's what I would do:
Designate a common CSS class for all the checkbox inputs (to be used as a jQuery selector later).
Create an empty <span>...</span> element with an id that encodes the student id (e.g., 'toa_1234') in the "Time of arrival" cell.
Use jQuery .change() and $.ajax() to send the message to the server.
Create a corresponding controller or action to process the AJAX POST and return the recorded (server-side) time.
On AJAX success, display the recorded server time and disable the checkbox (so it can't be clicked again).
HTML/ERB:
<td><%= check_box_tag "student_registers_ids[#{student_register.id}]",
student_register.id, false,
:class => 'student_present' %></td>
<td><%= student_register.student.university_id%></td>
<td><%= student_register.student.first_name.titlecase%></td>
<td><%= student_register.student.last_name.titlecase%></td>
<td><%= content_tag :span, student_register.time_of_arrival,
:id => "toa_#{student_register.student.id}" %></td>
JS/CoffeeScript:
$ ->
$('input[type="checkbox"].student_present').change (e) ->
checkbox = $(this)
student_id = checkbox.val()
$.ajax
url: '/register/present'
method: 'POST'
dataType: 'json'
data:
student_id: student_id
success: (data) ->
$("span#toa_#{student_id}").html(data['toa'])
checkbox.attr 'disabled', true
Controller/action:
def present
student_id = params['student_id']
# TODO: mark student present and save in database
recorded_toa = Time.now # TODO replace with actual time
render json: { student_id: student_id, toa: recorded_toa.strftime('%I:%M %P') }
end

Editing Quantity in Cart

So this is another post about updating the quantity in the cart! Any one that I could find seemed to be outdated, so I apologize if this seems repetative.
But I am following along in Agile Web Development with Rails 4th edition book, and they were so kind as to leave editing the quantity as a 'challenge' and not show the answer :D. Now as I'm trying to get it to work I'm having troubles.
Show in my views/cart/show.html.erb I have the following table
<table>
<tr>
<th>Quantity</th>
<th>Product Name</th>
<th>Size</th>
<th>Price</th>
</tr>
<% #cart.line_items.each do |item| %>
<tr>
<td>
<%= form_for 'item', :url => {:controller => 'line_items', :action => 'update', id: item} do |f| %>
<div class="field">
<%= f.number_field :qty, :value => item.qty %>
<%= submit_tag "Update" %>
</div>
<% end %>
</td>
<td><%= item.product.name %></td>
<td><%= item.size %></td>
<td><%= number_to_currency(item.total_price) %></td>
</tr>
<% end %>
<tr>
<td colspan="3">Total Price</td>
<td><%= number_to_currency(#cart.total_price) %></td>
</tr>
</table>
Yet when I click update I get either
Unknown action
The action '29' could not be found for LineItemsController
or
Unknown action
The action '35' could not be found for LineItemsController
even if I completely take out the id field. I can deal with the update function on the controller side and getting it update properly - I want to figure that out on my own but I can't figure out what could possibly be generating these numeric actions and how I can fix it. In short, what is producing this error and how can I fix it? Is it perhaps related to the fact I have a line_item form in a cart view?
do you check the 29 and 35 is either ur id or anything else? try to check with your database for LineItems , and how your controller look like?? and
<%= form_for 'item', :url => {:controller => 'line_items', :action => 'update', id: item} do |f| %>
you trying to update it in ajax way or ? when update the quantity, should it be using ajax if it's not mistaken (the book asked to do in that way right? )
So I got it working - that I did was I tweaked the form header like so
<%= form_for :item, :url => line_items_update_path(id: item.id) do |f| %>
I added the following line to my routes.rb
get "line_items/update"
And added one line to my line_items_controller
def update
#line_item = LineItem.find(params[:id])
#line_item.qty = params[:item][:qty] #added this line here
For those who are having problems!

Rails AJAX - getting a dropdown selection to populate a table

I'm trying to get a selection from a dropdown to populate a table in the same page, using AJAX so that changes appear without a page refresh. I've got as far as working out the code for the remote call, and adding the custom action to the controller, but I don't know how to get the returned information into the table I've got. At the moment, the table is just looping through all the projects, but I want it to only display the info for the one project that is selected.
What would I need to write in a JS (rjs?) file to get it to process the returned information, and what changes would I need to make to the existing table to make sure that it is displaying the correct info?
Dropdown (with AJAX call):
<%= collection_select :id, Project.all, :id, :name, :onchange => remote_function(:url=>{:action => 'populate_projects'}) %>
Controller action:
def populate_projects
#project = Project.find(params[:id])
end
And the existing table:
<table>
<tr>
<th>Name</th>
<th>Category</th>
<th>Budget</th>
<th>Deadline</th>
<th>Company ID</th>
<th></th>
<th></th>
<th></th>
</tr>
<% #projects.each do |project| %>
<tr>
<td><%= project.name %></td>
<td><%= project.category %></td>
<td><%= number_to_currency(project.budget, :unit => "£") %></td>
<td><%= project.deadline.strftime("%A, %d %B %Y") %></td>
<td><%= project.company_id %></td>
<td><%= link_to 'More', project %></td>
<td><%= link_to 'Edit', edit_project_path(project) %></td>
<td><%= link_to 'Delete', project, confirm: 'Are you sure?', method: :delete %></td>
</tr>
<% end %>
</table>
Assume you're using jquery
<%= collection_select :project, :id, Project.all, :id, :name, {}, {:onchange => '$.get("/populate_projects")'} %>
then in your controller
def populate_projects
#project = Project.find(params[:id])
respond_to do |format|
...
format.js { render 'populate_projects', :formats => [:js] }
...
end
end
finally, create populate_projects.js.erb and write any change table content script. #project is available in that script.
Create one partial _project.html.erb and render this partial in index page.
<%= render #projects %>
On change of project just render partial with project object and update page using rjs.
In js(RJS) file you need to call partial HTML file and this file have tables That you shown here in your question.
I hope this helps you.
Thanks.

Resources