Add to Cart works but nothing in Show#Cart - ruby-on-rails

Here's my cart.rb model
class Cart < ActiveRecord::Base
has_many :tutors
def current_cart
if session[:cart_id]
#current_cart ||= Cart.find(session[:cart_id])
end
if session[:cart_id].nil?
#current_cart = Cart.create!
session[:cart_id] = #current_cart.id
end
#current_cart
end
def add_tutor(tutor_id)
tutor = Tutor.find(tutor_id)
if tutor
self.tutors << tutor
end
save
end
end
And here's my carts_controller.rb
class CartsController < ApplicationController
def show
#cart = current_cart
end
def checkout
#cart = current_cart
name = params[:checkout][:your_name]
email = params[:checkout][:your_email]
message = params[:checkout][:your_hp]
ApplicationMailer.checkout(#cart, name, email, message).deliver
flash[:success] = "We have received your request and will be in touch with you shortly!"
redirect_to root_path
end
def add_to_cart
#cart = current_cart.add_tutor(params[:tutor_id])
if #cart
flash[:success] = "You have successfully added the tutor to your cart!"
redirect_to tutors_path
else
flash[:danger] = "Oops! Something went wrong. Please try again!"
redirect_to root_path
end
end
end
And here's the button for the add to cart function
<%= button_to "Shortlist Tutor", add_to_cart_path(:tutor_id => tutor.id), :method => :post %>
The add to cart function seems to work fine as it redirects me to the correct page and no errors or anything like that seems to show up. In my rails console i can see in the server that there isn't any rollback.
Processing by CartsController#add_to_cart as HTML
Parameters: {"authenticity_token"=>"da3XDg69FSCrEyn39v8Apty4aX40TJH85BeW49x/4R3MElKYxip1w7rpbWRBYj5hhZDAivf7Bxn4FK1dkHyKpg==", "tutor_id"=>"3"}
Cart Load (0.2ms) SELECT "carts".* FROM "carts" WHERE "carts"."id" = ? LIMIT 1 [["id", 12]]
Tutor Load (0.3ms) SELECT "tutors".* FROM "tutors" WHERE "tutors"."id" = ? LIMIT 1 [["id", 3]]
(0.1ms) begin transaction
(0.1ms) commit transaction
(0.1ms) begin transaction
(0.1ms) commit transaction
Thats what i see in the server. I'm really not quite sure why don't i see anything when i go to my carts#show view.
Would appreciate any help that i can get. Thanks!

Check what you are receiving in params[:tutor_id].
Looking at SQL statements that are executed it doesn't look like it is saving at all when invoking add_to_cart. It only carries out a SELECT on carts and tutor.

Related

Ruby: undefined method `name' for nil:NilClass

I'm trying to install this app on Windows 7 https://github.com/cheezy/puppies.
I am not a developer, I am just following below steps to install it:
Ruby Version ruby 2.2.4p230 (2015-12-16 revision 53155) [i386-mingw32] installed on Windows 7
Steps:
Download zip from above link
Inside puppies-master do bundle update and then bundle install.
Then rails s
Launch localhost:3000
It gave error ruby : unsupported parameters: :order. I fixed it by
changing this line
#puppies = Puppy.paginate :page =>params[:page], :order => 'name', :per_page => 4 to this line
#puppies = Puppy.order(:name).paginate(page: params[:page], per_page: 4)
Error was gone and on localhost:3000 it showed me the app launched
But puppies (data) weren't there so I did
bundle && rake db:create && rake db:migrate and then rake db:seed
Refresh the localhost page and all puppies appeared but after I am not able to complete the transaction and on hitting Complete the adoption button it is giving me an error.
undefined method 'name' for nil:NilClass
If you just type undefined method 'name' for nil:NilClass in SOF you will get so many solutions but it seems different then those, because none worked for me.
This is what log says:
Started GET "/orders/new" for 127.0.0.1 at 2017-07-20 10:10:51
Processing by OrdersController#new as HTML
Cart Load (0.0ms) SELECT "carts".* FROM "carts" WHERE "carts"."id" = ? LIMIT 1 [["id", 1]]
CACHE (0.0ms) SELECT "carts".* FROM "carts" WHERE "carts"."id" = ? LIMIT 1 [["id", 1]]
Completed 500 Internal Server Error in 3ms
NoMethodError (undefined method `name' for nil:NilClass):
app/controllers/orders_controller.rb:23:in `new'
Rendered C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-3.2.11/lib/action_dispatch/middleware/templates/rescues/_trace.erb (2.5ms)
Rendered C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-3.2.11/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (0.0ms)
Rendered C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-3.2.11/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (242.5ms)
Started GET "/orders/new" for 127.0.0.1 at 2017-07-20 11:20:21
Processing by OrdersController#new as HTML
Cart Load (0.0ms) SELECT "carts".* FROM "carts" WHERE "carts"."id" = ? LIMIT 1 [["id", 1]]
CACHE (0.0ms) SELECT "carts".* FROM "carts" WHERE "carts"."id" = ? LIMIT 1 [["id", 1]]
Completed 500 Internal Server Error in 3ms
NoMethodError (undefined method `name' for nil:NilClass):
app/controllers/orders_controller.rb:23:in `new'
Rendered C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-3.2.11/lib/action_dispatch/middleware/templates/rescues/_trace.erb (1.0ms)
Rendered C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-3.2.11/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (1.0ms)
Rendered C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-3.2.11/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (252.0ms)
Edit:
orders_controller.rb
class OrdersController < ApplicationController
skip_before_filter :authorize, :only => [:new, :create]
def index
#orders = Order.paginate :page=>params[:page], :order=>'created_at desc',
:per_page => 10
respond_to do |format|
format.html # index.html.erb
end
end
def show
#order = Order.find(params[:id])
respond_to do |format|
format.html # show.html.erb
end
end
def new
#cart = current_cart
if current_cart.adoptions.empty?
redirect_to agency_url, :notice => "Your cart is empty"
return
end
#order = Order.new
respond_to do |format|
format.html # new.html.erb
format.json { render :json => #order }
end
end
def edit
#order = Order.find(params[:id])
end
def create
#order = Order.new(params[:order])
#order.add_adoptions_from_cart(current_cart)
respond_to do |format|
if #order.save
Cart.destroy(session[:cart_id])
session[:cart_id] = nil
format.html { redirect_to(agency_url, :notice => 'Thank you for adopting a puppy!') }
format.json { render :json => #order }
else
format.html { render :action => "new" }
end
end
end
def update
#order = Order.find(params[:id])
respond_to do |format|
if #order.update_attributes(params[:order])
format.html { redirect_to(#order, :notice => 'Order was successfully updated.') }
else
format.html { render :action => "edit" }
end
end
end
def destroy
#order = Order.find(params[:id])
adoption = #order.adoptions.first
adoption.delivered_on = Time.now
adoption.save
respond_to do |format|
format.html { redirect_to(orders_url, :notice => "Please thank #{#order.name} for the order!") }
end
end
end
Edit2:
current_card method --
class ApplicationController < ActionController::Base
before_filter :authorize
protect_from_forgery
private
def current_cart
Cart.find(session[:cart_id])
rescue ActiveRecord::RecordNotFound
cart = Cart.create
session[:cart_id] = cart.id
cart
end
protected
def authorize
unless User.find_by_id(session[:user_id])
redirect_to login_url, :notice => "Please log in"
end
end
end

undefined method `projects' for nil:NilClass

Is my project class is nill or what, can any one explain me this error.
NoMethodError (undefined method projects' for nil:NilClass):
app/controllers/project_controller.rb:8:inindex'
Rendered
/Users/ajaysithagari/.rvm/gems/ruby-2.2.1/gems/actionpack-4.2.3/lib/action_dispatch/middleware/templates/rescues/_source.erb
(6.2ms) Rendered
/Users/ajaysithagari/.rvm/gems/ruby-2.2.1/gems/actionpack-4.2.3/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (3.4ms) Rendered
/Users/ajaysithagari/.rvm/gems/ruby-2.2.1/gems/actionpack-4.2.3/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
(1.0ms) Rendered
/Users/ajaysithagari/.rvm/gems/ruby-2.2.1/gems/actionpack-4.2.3/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb
within rescues/layout (50.0ms) Rendered
/Users/ajaysithagari/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/_markup.html.erb
(0.4ms) Rendered
/Users/ajaysithagari/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/_inner_console_markup.html.erb
within layouts/inlined_string (0.3ms) Rendered
/Users/ajaysithagari/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/_prompt_box_markup.html.erb
within layouts/inlined_string (0.3ms) Rendered
/Users/ajaysithagari/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/style.css.erb
within layouts/inlined_string (0.4ms) Rendered
/Users/ajaysithagari/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/console.js.erb within layouts/javascript (41.3ms) Rendered
/Users/ajaysithagari/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/main.js.erb
within layouts/javascript (0.3ms) Rendered
/Users/ajaysithagari/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/error_page.js.erb within layouts/javascript (0.4ms) Rendered
/Users/ajaysithagari/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/index.html.erb (93.4ms)
Here is my project controller
before_action :confirm_logged_in
before_action :find_company
def index
#projects = #company.projects.sorted
end
def show
#project = Project.find(params[:id])
end
def new
#project = Project.new()
end
def create
#project = Project.new(project_params)
if #project.save
redirect_to(:action => 'index')
else
render('new')
end
end
def edit
#project = Project.find(params[:id])
end
def update
#project = Project.find(params[:id])
if #project.update_attributes(project_params)
redirect_to(:action => 'index')
else
render('new')
end
end
def delete
#project = Project.find(params[:id])
end
def destory
#project = Project.find(params[:id])
#project.destroy
redirect_to(:action => 'index')
end
private
def project_params
params.require(:project).permit(:name, :position, :type_of_project, :description, :no_of_tasks)
end
def find_company
if params[:company_id]
#company = Company.find(params[:company_id])
end
end
end
So actually what iam doing here is before entering in to projects we need to find the company_id and in index #projects = #company.projects.sorted means that company has many projects.
The problem is with the if params in the def find_company. For the index function this is not set.
change def index to:
def index
#projects = Project.sorted
end
UPDATE: made an error I think:
def index
#projects = Project.all.sorted #or leave the call to sorted out completely
end

current_user and destroying comments (refined)

I recently posted a question similar to this but I've narrowed down the problem and wanted to refine the question. Anyway, I have a blog with recipes (equivalent of posts or articles) and comments on those recipes. I've put in my application_controller.rb file the code for current_user:
def current_user
return unless session[:user_id]
#current_user = User.find_by_id(session[:user_id])
end
# Make current_user available in templates as a helper
helper_method :current_user
I tried to make it so that you had to be logged in to delete a comment on an article. That code is in my comments_controller.rb file:
def destroy
#recipe = current_user.recipes.find(params[:recipe_id])
#comment = #recipe.comments.find(params[:id])
#comment.destroy
redirect_to #recipe, notice: 'Comment Deleted'
end
I've narrowed it down to that first line of code within the destroy method. I believe that my application can't associate the recipe with the current_user and so can't save #recipe properly, so the #comment won't delete. Each recipe has a user_id parameterHere's the error, from the server console, when I try to delete a comment with a logged in user:
Started DELETE "/recipes/4/comments/4" for 127.0.0.1 at 2015-02-12 13:42:54 -0500
Processing by CommentsController#destroy as HTML
Parameters: {"authenticity_token"=>"+0pWfNOPJXLOzgUhA//q4ySh5rk01SlKmTRQx0qdDOrvkUOcIzF8GCb5jKwjsDlUvQsxxGTOOtJv6rPjn3jfoA==", "recipe_id"=>"4", "id"=>"4"}
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 6]]
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 6]]
Recipe Load (0.1ms) SELECT "recipes".* FROM "recipes" WHERE "recipes"."user_id" = ? AND "recipes"."id" = ? ORDER BY published_at DESC, title ASC LIMIT 1 [["user_id", 6], ["id", 4]]
Completed 404 Not Found in 50ms
ActiveRecord::RecordNotFound (Couldn't find Recipe with 'id'=4 [WHERE "recipes"."user_id" = ?]):
app/controllers/comments_controller.rb:15:in `destroy'
Anyone have any ideas?
NOTE: when I change the first line of code within the destroy method of my comments_controller to:
#recipe = Recipe.find(params[:recipe_id])
it works. I don't want that to be the code though bc then a non-logged in user can delete comments. AND, that revised code is the same code as a private method i put within my comments_controller:
private
def load_recipe
#recipe = Recipe.find(params[:recipe_id])
end
There is also a before_filter on that method in my comments_controller:
before_filter :load_recipe, :except => :destroy
before_filter :authenticate, :only => :destroy

One to Many Association Object Will Not Save

I set up a has_many belongs_to relationship in my two models and followed Ryan Bates' screencast on how to set up the controller. When I submit my form to create the new object, the nested object does not save for some reason. Here are my models:
class Auction < ActiveRecord::Base
has_many :bids, dependent: :destroy
end
class Bid < ActiveRecord::Base
belongs_to :auction
belongs_to :user
default_scope -> { order(created_at: :desc) }
validates :user_id, presence: true
validates :auction_id, presence: true
end
and my nested object controller:
class BidsController < ApplicationController
def index
#auction = Auction.find(params[:auction_id])
#bids = #auction.bids
end
def new
#auction = Auction.find(params[:auction_id])
#bid = #auction.bids.build
end
def create
#auction = Auction.find(params[:auction_id])
#bid = #auction.bids.create(params[:bid])
#bid.save
if #bid.save
flash[:success] = "Bid has been successfully placed."
else
#bid.errors
render 'new'
end
end
def destroy
#auction = Auction.find(params[:auction_id])
#bid = #auction.bids.find
#bid.destroy
flash[:notice] = "Successfully destroyed Bid."
redirect_to auction_url(#bid.article_id)
end
end
my form:
<h1>Create a New Bid</h1>
<%= form_for ([#auction, #bid]) do |f|%>
<p>
<%= f.submit %>
</p>
<%end%>
and my terminal output:
Started POST "/auctions/1/bids" for 127.0.0.1 at 2014-11-30 17:59:13 -0600
Processing by BidsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"dkZBcab1rgZjtJGF3LAJ//exK6liglZ0Fy4mg7HWEt0=", "commit"=>"Create Bid", "auction_id"=>"1"}
Auction Load (0.1ms) SELECT "auctions".* FROM "auctions" WHERE "auctions"."id" = ? LIMIT 1 [["id", 1]]
(0.0ms) begin transaction
(0.0ms) commit transaction
(0.0ms) begin transaction
(0.0ms) rollback transaction
(0.0ms) begin transaction
(0.0ms) rollback transaction
Thanks for your help.
Your bid object needs a user_id because you have validates :user_id, presence: true in the class definition.
When you call #bid.save in the controller, however, #bid does not have a user_id value, therefore the transaction gets rolled back because of the failing validation.
You should be able to see this by looking at #bid.errors.full_messages in the create action, after you've called #bid.save. (Look up the pry gem if you're not already familiar with it...it would be a perfect tool to let you do this inspection.)
Try replacing your create action with this:
def create
#auction = Auction.find(params[:auction_id])
#bid = #auction.bids.new params[:bid].merge(user_id: current_user.id)
if #bid.save
flash[:success] = "Bid has been successfully placed."
else
flash[:error] = #bid.errors.full_messages.join('. ')
render 'new'
end
end
This assumes that you have access to the current user in the controller as current_user. Devise and other popular auth solutions supply this, or you can do so yourself.
Note also that your original code tries to write #bid to the database 3 separate times, which is twice more than you need to. Here are the offending lines:
def create
...
#bid = #auction.bids.create(params[:bid])
#bid.save
if #bid.save
...
#create instantiates an object and attempts to write it to the database. In my code above, I've replaced #auction.bids.create(params...) with #auction.bids.new(params...). This initializes #bid without trying to persist it to the db.
I also removed the first #bid.save because the line below it if #bid.save will accomplish the same thing.
Finally, your line #bid.errors doesn't do anything useful. I modified it to store the error messages in your flash hash, which you can then use in your view to display the errors to the user.

ruby on rails query

def remove_items
line_items.each do |item|
#ci = Product.find(item.id)
#ci.quantity = #ci.quantity.to_i - 1
end
Hello, I am trying to use the id of the item and then match the id with a product and then minus 1 to the quantity property of that product.
I currently get this error though.
TypeError in OrdersController#create
can't convert nil into String
What is wrong?
Thanks
OrderController#create
Please bear in mind code is scruffy due to being in progress. :)
def create
#order = current_cart.build_order(params[:order])
#order.ip_address = request.remote_ip
#cart = current_cart
if #order.save
if #order.purchase
#order.status = "paid"
#cart.remove_items
#cart.destroy
render :action => "success"
else
#order.status = "failed"
#cart.destroy
render :action => "failure"
end
else
render action: "new"
end
end
I think this is the stack trace
[0m
←[1m←[35mLineItem Load (0.0ms)←[0m SELECT "line_items".* FROM "line_items" WH
ERE "line_items"."cart_id" = 129
←[1m←[36mProduct Load (0.0ms)←[0m ←[1mSELECT "products".* FROM "products" WHE
RE "products"."id" = ? LIMIT 1←[0m [["id", 147]]
Completed 500 Internal Server Error in 5762ms
TypeError (can't convert nil into String):
app/controllers/application_controller.rb:60:in `+'
app/controllers/application_controller.rb:60:in `record_not_found'
According to your comment this should solve the problem:
# application_controller.rb
def record_not_found
flash[:alert] = "Cannot find record number #{params[:id]}. Displaying all records."
redirect_to root_path
end
But if I were you I wouldn't output the params[:id] in the alert message. Just say that the record has not been found, basta.
flash[:alert] = "Cannot find record. Displaying all records."
You can also do this in one line:
redirect_to root_path, alert: "Cannot find record. Displaying all records."
To fix the logic in your remove_items method you need to actually save the object at the end:
def remove_items
line_items.each do |item|
ci = Product.find(item.id)
ci.quantity = ci.quantity.to_i - 1
ci.save
end
end
Looks like you're buding a shopping cart app from scratch. Have you considered using an existing platform, like Spree?
It's a better idea to have the DB decrement all the Products at once:
def remove_items
Product.where(id:line_items.map(&:id)).update_all('quantity = quantity - 1')
end
OR even better:
def remove_items
Product.decrement_counter(:quantity, line_items.map(&:id) )
end
These are faster, avoid errors if the product can not be found, and also avoid a Race Condition if you have multiple processes running concurrently.

Resources