See Update’s 1 & 2 below for Solution
I’ve been following the tutorial on creating a shopping cart from the book “Agile Web Development with Rails”..They have the chapter I’ve been following here: http://media.pragprog.com/titles/rails4/cart.pdf
In the book they have you create a line_item that get’s passed to a cart and stored in the session by using this line <%= button_to ‘Add to Cart’, line_items_path(product_id: product) %> This in my case would obviously be changed to <%= button_to ”, line_items_path(gear_id: gear), id: ‘rent_it’ %>
If I want to change this so it’s a form that also accepts other parameters how would I do this?
Below is my code that I’ve used and attempted to accomplish this but so far unsuccessfully.
With the below code I get and error that can’t find gear without ‘id’. I’m new to rails and programming in general so I appreciate the help.
UPDATE 1 (I updated my View below as well)
I can now see from my server logs that I’m passing the ID of the Gear in the form. Which is what I was originally trying to do.
Processing by LineItemsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"0QnJShABOV+avPx0AJHxuMmskfwtwFlkpMa6cBhTU3s=", "line_item"=>{"rentstart"=>"", "rentend"=>"", "gear_id"=>"13"}, "commit"=>""}
Cart Load (0.4ms) SELECT `carts`.* FROM `carts` WHERE `carts`.`id` = 18 LIMIT 1
Completed 500 Internal Server Error in 2ms
ActiveRecord::RecordNotFound (Couldn't find Gear without an ID):
app/controllers/line_items_controller.rb:44:in `create'
I’m still getting the error Couldn’t find Gear without an ID. Which are the 2 lines below:
gear = Gear.find(params[:gear_id])
@line_item = @cart.add_gear(gear.id)
What am I missing?
Line Item’s Controller
def create
@cart = current_cart
gear = Gear.find(params[:gear_id])
@line_item = @cart.add_gear(gear.id)
respond_to do |format|
if @line_item.save
format.html { redirect_to @line_item.cart }
format.json { render json: @line_item, status: :created, location: @line_item }
else
format.html { render action: "new" }
format.json { render json: @line_item.errors, status: :unprocessable_entity }
end
end
end
Cart Model
class Cart < ActiveRecord::Base
has_many :line_items, dependent: :destroy
def add_gear(gear_id)
current_item = line_items.find_by_gear_id(gear_id)
if current_item
current_item.quantity += 1
else
current_item = line_items.build(params[:line_item])
end
current_item
end
def total_price
line_items.to_a.sum { |item| item.total_price }
end
end
View from Gear Show Page
<div class="gearside_date_main">
<h3>Rental Date</h3>
<script>
$(function() {
var dates = $( "#rentstart, #rentend" ).datepicker({
defaultDate: "+1w",
changeMonth: true,
numberOfMonths: 1,
onSelect: function( selectedDate ) {
var option = this.id == "rentstart" ? "minDate" : "maxDate",
instance = $( this ).data( "datepicker" ),
date = $.datepicker.parseDate(
instance.settings.dateFormat ||
$.datepicker._defaults.dateFormat,
selectedDate, instance.settings );
dates.not( this ).datepicker( "option", option, date );
}
});
});
</script>
<%= form_for LineItem.new do |f| %>
<%= f.text_field :rentstart, id: 'rentstart' %>
<%= f.text_field :rentend, id: 'rentend' %>
<%= f.hidden_field :gear_id, :value => @gear.id %>
<%= f.submit "", id: 'rent_it' %>
<% end %>
<% end %>
</div>
UPDATE 2
I finally got it working after Murifox’s comments. I didn’t completely understand how the syntax is structured when passing a hash. So after much trial and error it is working. I’m including my updated code below to see the changes that I made. I know when I see answers I’m always looking for the change. I hope this helps someone else….
The View (Gear Show Page
<%= form_for LineItem.new do |f| %>
<%= f.text_field :rentstart, id: 'rentstart' %>
<%= f.text_field :rentend, id: 'rentend' %>
<%= f.hidden_field :gear_id, :value => @gear.id %>
<%= f.submit "", id: 'rent_it' %>
<% end %>
The Controller (Create Action)
def create
@cart = current_cart
gear = Gear.find(params[:line_item][:gear_id])
lineitem = params[:line_item]
@line_item = @cart.add_gear(lineitem, gear.id)
respond_to do |format|
if @line_item.save
format.html { redirect_to @line_item.cart }
format.json { render json: @line_item, status: :created, location: @line_item }
else
format.html { render action: "new" }
format.json { render json: @line_item.errors, status: :unprocessable_entity }
end
end
end
The Cart Model
def add_gear(lineitem, gear_id)
current_item = line_items.find_by_gear_id(gear_id)
if current_item
current_item.quantity += 1
else
current_item = line_items.build(lineitem)
end
current_item
end
Try using