Editing Quantity in Cart - ruby-on-rails

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!

Related

Create/New DB record for each generated set of fields

I have got a problem with saving multiple record.
This script wil load a list of instruments that belong to a department through a join table.
This form will make a new record for another join table, the problem is when I'f got 4 instruments it only will save the last instrument.
Image generated list
Can anybody help me out to solve this problem or point me into the right direction ??
<%= form_for(:joindaylisting) do |j| %>
<% #instrumentslist.each do |instrument| %>
<tr class="<%= cycle('odd', 'even') %>">
<td>
<% j.label(:instrument_id, "#{instrument.name}") %>
<%= link_to("#{instrument.name}", {:controller => 'instruments', :action => 'show_instruction', :instrument_id => instrument.id}, :onclick=>"window.open('height=670, width=675');return false;") %>
</td>
<%= j.hidden_field(:instrument_id, :value => instrument.id) %>
<td></td>
<% j.label(:ammountdesinfection, "") %>
<td><%= j.text_field(:ammountdesinfection) %></td>
<% j.label(:ammountinstruments, "") %>
<td><%= j.text_field(:ammountinstruments) %></td>
<% j.label(:ammountrelease, "") %>
<td><%= j.text_field(:ammountrelease) %></td>
<% j.label(:notes, "") %>
<td><%= j.text_area(:notes) %></td>
</tr>
<% j.label(:department_id) %>
<%= j.hidden_field(:department_id, :value => #department.id) %>
<% end %>
<% end %>
Only the last one is saved because the fields have the same name and the last one overrides all other values. See the params you are getting on the receiving controller.
You probably want/need to configure departments to accepts_nested_attributes_for :instruments and a form for the department object with fields_for: instruments. I've highlighted keywords that my help you get the information you want, the Rails Guides is a good place to start.

Rails - How to make Will-Paginate links show up BELOW the table?

I just came across the will-paginate gem. I'm trying to separate records into multiple pages. I managed to make some progress, but I ran into a problem.
The Pagination Tab (that shows the page numbers) appears above the table. It is also uncentered. How can I have the tab appear below the table.
This is how it currently looks
<= Previous 1 2 Next =>
Table Data
How I would like it to look
Table Data
<= Previous 1 2 Next =>
Here is my code
<tbody>
<% g = Game.where(console: #title.split(' ').first(2).join(' ')).order(title: :asc).paginate(:page => params[:page], :per_page => 2) %>
<% g.each do |game| %>
<tr>
<td> <%= link_to "#{game.title}", game %></td>
<td> <%= game.genre %></td>
<td> <%= game.release_date %></td>
<td> <%= game.rating %></td>
<% if signed_in? && current_user.admin? %>
<div>
<td id = 'actions'><%= link_to 'Show', game, class: 'action' %></td>
<td id = 'actions'><%= link_to 'Edit', edit_game_path(game), class: 'action' %></td>
<td id = 'actions'><%= link_to 'Delete', game, method: :delete, class: 'action' %></td>
</div>
<% end %>
</tr>
<%= will_paginate g %>
<% end %>
</tbody>
I even put will_paginate at the end of my code block.
Your markup is invalid. Your call to will_paginate is inside of the table, in between tags.
If you want it to show up below, above, or anywhere else, just put the call to pagination there.
<%= will_paginate collection %>
You really should be instantiating instance variables in your controller. This line should not be in your view.
<% g = Game.where(console: # ...
This way you solve the restriction of where to place your pagination call, and you write more idiomatic Rails code.
If you must go down this road, and I strongly discourage you, just do load your collection above the table.
<% g = Game.where(console: #title.split(' ').first(2).join(' ')).order(title: :asc).paginate(:page => params[:page], :per_page => 2) %>
Then, below that, render the pagination since the variable g now exists:
<%= will_paginate g %>
Then render your table.

Get id of an object to pass into form_for

I am trying to find my time sheet id to pass into a form_for
here is my controller
def show
#time_id = current_user.time_sheets.find(params[:id])
if current_user
#current = current_user.time_sheets
else
redirect_to new_user_session_path, notice: 'You are not logged in.'
end
end
This is my form_for in my view:
<%= form_for(:entry, :url => {:controller => Entry, :action => 'create'}) do |f| %>
<table summary="Subject form fields">
<tr>
<th>Customer</th>
<td><%= f.text_field(:customer_name) %></td>
</tr>
<tr>
<th>Order Number</th>
<td><%= f.text_field(:order_number) %></td>
</tr>
<tr>
<th>Time In</th>
<td><%= f.text_field(:time_in) %></td>
</tr>
<tr>
<th>Time Out</th>
<td><%= f.text_field(:time_out) %></td>
</tr>
<tr>
<th>Time Sheet ID</th>
<td><%= f.hidden_field :time_sheet_id, value: #time_id.id %></td>
</tr>
</table>
<div class="form-buttons">
<%= submit_tag("Add Entry") %>
</div>
<% end %>
What needs to happen is that the timesheet id needs to get passed into the form_for so the entry can have the timesheet id.
I have user, timesheets and entries. user has_many time sheets, timesheets belongs to users and users have many time sheets. Entry belongs to timesheet.
I am getting this error "Couldn't find TimeSheet without an ID"
You should use "Nested Resources", eg. see here: Rails 3: How to create a new nested resource?
You could use form_for([#timesheet, #entry]) to pass the id of the timesheet without using a hidden field. If you do this, the :url param also become obsolete.
Try adding:
<%= #time_id.id %>
to output your variable and make sure it's exactly what you think it is. If #time_id is a timesheet, you should probably rename that variable to #time_sheet.

Rails RuntimeError: "Called id for nil". Rails is telling me that the instance variable I'm passing in through params[:id] is null [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
EDIT2: [SOLVED] The "create" method in the controller file does not "end" until after the "edit" method. I can't answer my own question until 8 hours afterwards, however.
EDIT: It's been brought to my attention that this may be a problem with my routes.rb file. Which is just below.
routes.rb
SimpleCms::Application.routes.draw do
root :to => "subjects#list"
match ':controller(/:action(/:id))(.:format)'
end
Essentially this is an #instance_variable issue. More specifically an #instance_variable[:id => nil] problem. Somehow I'm passing a nil (null) :id (primary key) value to rails but the edit button which I'm clicking on (the last file in this list is the list.html.erb file which contains the button that takes you to edit.html.erb) is supposed to be passing the :id value corresponding to the given subject on the list page.
So here is the error message from the browser first of all:
RuntimeError in Subjects#edit
Showing C:/Users/davo/Desktop/RailsProjects/simple_cms/app/views/subjects/edit.html.erb where line #6 raised:
Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
Extracted source (around line #6):
3: <div class="subject edit">
4: <h2>Update Subject</h2>
5:
6: <%= form_for(:subject, :url => {:action => 'update', :id => #subject.id}) do |f| %>
7:
8: <table summary="Subject form fields">
9: <tr>
Rails.root: C:/Users/davo/Desktop/RailsProjects/simple_cms
Application Trace | Framework Trace | Full Trace
app/views/subjects/edit.html.erb:6:in `_app_views_subjects_edit_html_erb__829468061_51428148'
Request
Parameters:
{"id"=>"1"}
Here is the controller ("subjects_controller.rb") so you can see the instance variable stuff. The edit and update methods are on the bottom
**All the other methods which call params[:id] are working. It's possible that there is nothing wrong with the controller and that it's just the view. In particular, on that view, the #subject versus :subject versus subjects.method stuff...there seems to be something wrong with that syntax.
class SubjectsController < ApplicationController
def list
#subjects = Subject.order("subjects.position ASC")
end
def index
list
render('list')
end
def show
#subject = Subject.find(params[:id])
end
def new
#subject = Subject.new(:name => 'default')
end
def create
#instantiate a new object using form params
#subject = Subject.new(params[:subject])
#save the subject
if #subject.save
redirect_to(:action => 'list')
#if save succeeds redirect to list action
else
#if save fails, redisplay form
render('new')
end
def edit
#subject = Subject.find(params[:id])
end
#passing an #instancevariable inside of a {hash}...is there anything odd about that?
#I'm just trying to inspire you guys -->
#
#I have a hunch that the :syntax/#syntax/#{etc} involving params, :id and
#:subject could be the root of this issue...just a hunch
#
def update
#Find object using form parameters
#subject = Subject.find(params[:id])
#Update the object
if #subject.update_attributes(params[:subject])
redirect_to(:action => 'show', :id => #subject.id)
else
render('edit')
end
end
end
end
Lastly, here is edit.html.erb
<%= link_to("<< Back to List", {:action => 'list'}, :class => 'back-link') %>
<div class="subject edit">
<h2>Update Subject</h2>
<%= form_for(:subject, :url => {:action => 'update', :id => #subject.id}) do |f| %>
<table summary="Subject form fields">
<tr>
<th>Name</th>
<td><%= f.text_field(:name) %></td>
</tr>
<tr>
<th>Position</th>
<td><%= f.text_field(:position) %></td>
</tr>
<tr>
<th>Visible</th>
<td><%= f.text_field(:visible) %></td>
</tr>
</table>
<tr>
<td><%= f.submit 'Update Subject' %></td>
</tr>
<% end %>
</div>
EDIT:
here is the list.html.erb file, which contains the link that points to the edit.html.erb file, which, currently, does not open and displays the error message.
<html>
<div class="subject list">
<h2>Subjects</h2>
<!--- header row with all the different attributes --->
<table class="listing" summary="Subject list">
<tr class="header">
<th>#</th>
<th>Subject</th>
<th>Visible</th>
<th>Pages</th>
<th>Actions</th>
</tr>
<!-- this is the beginning of a loop, that ends way down there -->
<% #subjects.each do |subject| %>
<tr>
<td><%= subject.position %></td>
<td><%= subject.name %></td>
<td class="center"><%= subject.visible ? 'Yes' : 'No' %></td>
<td class="center"><%= subject.pages.size %></td>
<td class="actions">
<%= link_to("Show", {:action => 'show', :id => subject.id}, :class => 'action show') %>
<%= link_to("Edit", {:action => 'edit', :id => subject.id}, :class => 'action edit') %>
<%= link_to("Delete", '#', :class => 'action delete') %>
</td>
<% end %>
</tr>
</table>
<%= button_to "Create New Subject", {:action => 'new'}, {:class => "buttonTo"} %>
</div>
</html>
EDIT:
- Let me know if you need to see a particular model.rb file. In my models folder I have "subject.rb", "section.rb", "section_edit.rb", "page.rb" and "admin_user.rb" if you need to see any of those. I'm kind of stumped on this one so maybe they'd be useful. They all contain a bunch of schema (has_many, belongs_to, etc) instructions and a few custom console calls.
= form_for(#subject, :as => :subject, .....
#subject is not nil, because find raises exception if no record have been found
I made a typo when doing the some of the def/end syntax in the controller. I think it was 'def create', I didn't end it.

Rails forms helper: dealing with complex forms and params (it's my first day with rails)

Learning rails and something smells a little funny.
I have the following form for updating quantities in a shopping cart.
<% form_for(:cart, #cart.items, :url => { :action => "update_cart" }) do |f| %>
<table>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Price</th>
</tr>
<% for item in #cart.items %>
<% f.fields_for item, :index => item.id do |item_form| %>
<tr>
<td><%=h item.title %></td>
<td><%=item_form.text_field :quantity, :size => 2 %>
<span># <%=h number_to_currency(item.item_price) %></span></td>
<td><%=h number_to_currency(item.line_price) %></td>
</tr>
<% end %>
<% end %>
<tr>
<td colspan="2">Total:</td>
<td><%=h number_to_currency(#cart.total_price) %></td>
</tr>
</table>
<%=submit_tag 'Update Cart' %>
<% end %>
In my update_cart action, I iterate through the existing cart items and set the new quantity:
def update_cart
#cart = find_cart
#cart.items.each do |item|
quantity = params[:cart][:cart_item][item.id.to_s][:quantity].to_i
#cart.update_quantity_for(item, quantity)
end
redirect_to :action => 'cart'
end
I dont have a REST interface controller for carts or cart items. Is there a better way to deal with this deep params data structure? The expression params[:cart][:cart_item][item.id.to_s][:quantity].to_i strikes me as dangerous for invalid form data.
The correct way to do this is the use the "accepts_nested_attributes" attribute in the cart model. Then you can just use CartController's update method to save your items. (http://railscasts.com/episodes/196-nested-model-form-part-1)
Also, your total price should probably be a method defined in the Cart model.

Resources