I have an issue with my add_item method and have trouble to understand why.
Here is my carts_controller.rb
class CartsController < ApplicationController
def index
#cart_items = CartItem.all
end
def add_item
#cart_item = CartItem.new
produit_id = params[:produit_id]
#cart_item = CartItem.find_or_create_by(params[:produit][:produit_id])
#cart_item.save
binding.pry
end
end
Here is produits/index.html.erb (where the issue comes from)
<div id="produits-column-container">
<% if #produits %>
<% #produits.in_groups_of(4, false).each do |g| %>
<% g.each do |produit| %>
<div id="produits-row-container">
<div id="fiche-produit-container">
<div id="produit-img">
<%= image_tag produit.photo %>
</div>
<div id="produit-nom">
<%= produit.nom %>
</div>
<div id="produit-prix">
<%= number_to_currency(produit.prix, unit: '€', format: "%n%u") %>
</div>
<div id="produit-au-panier">
<%= image_tag('icon/icon-panier') %>
<%= link_to 'Ajouter au panier', carts_add_item_path, method: :post %>
</div>
</div>
</div>
<% end %>
<% end %>
<% end %>
</div>
The error i'm given is :
ArgumentError in CartsController#add_item
wrong number of arguments (given 0, expected 1)
in def add_item(produit_id)
add_item(produit_id) is related to carts_add_item_path
I also give you the routes :
Rails.application.routes.draw do
match "/mon-panier" => 'carts#index', via: :get
post 'carts/add_item' => 'carts#add_item'
resources :categories do
resources :produits
end
resources :order_abonnements, only: [:create, :update, :delete]
get 'livraisons_type/index'
match "/recapitulatif" => 'recapitulatif#index', via: :get
match "/confirmation-carte-cadeau" => 'recapitulatif#confirmation', via: :get
match "/livraison-carte-cadeau" => 'livraison_carte#index', via: :get
match '/activation-carte' => 'code_carte_cadeau#index', via: :get
match "/offrir-une-box-bretonne" => 'cadeau#index', via: :get
resources :order_items, only: [:create, :update, :destroy]
match "/nos-box" => 'nos_box#index', via: :get
get 'categories/index'
devise_for :admin_users, ActiveAdmin::Devise.config
ActiveAdmin.routes(self)
match '/informations-penn-ar-box' => 'informations_penn_ar_box#index', via: :get
match '/livraison-box-bretonne' => 'livraison_box_bretonne#index', via: :get
match '/abonnements' => 'abonnements#index', via: :get
devise_for :users, path: '', path_names: { sign_in: 'connexion', sign_out: 'déconnexion'}
resources :users do
delete 'déconnexion' => 'devise/sessions#destroy'
end
match '/mon-marche-breton' => 'marche_breton#index', via: :get
root 'home#home'
end
And the logs :
Started POST "/carts/add_item" for ::1 at 2017-05-30 09:48:52 +0200
Processing by CartsController#add_item as HTML
Parameters: {"authenticity_token"=>"QrToQUHVxjuV5cUvZYHd7tj457htfZohOkmsvNDnKv79P413xjsSfR/8RVXtdIU7/wcmhcxjkU85N13CqJkG2w=="}
Cart Load (0.3ms) SELECT `carts`.* FROM `carts` WHERE `carts`.`id` = 1 LIMIT 1
Completed 500 Internal Server Error in 27ms (ActiveRecord: 14.9ms)
ArgumentError (wrong number of arguments (given 0, expected 1)):
app/controllers/carts_controller.rb:6:in `add_item'
You need to pass produit_id as a parameter.
So change this line as so...
<%= link_to 'Ajouter au panier',
carts_add_item_path(produit_id: produit.id), method: :post %>
And change your controller method as so...
def add_item
produit_id = params[:produit_id]
...
And change the find_or_create to
#cart_item = CartItem.find_or_create_by(produit_id: produit_id)
This does mean that you can only have one CartItem in your entire application that points to a product... strange design.
There are a lot of things that are wrong with this code, but the simplest thing you could do in order to suppress the error is to change the method signature to:
def add_item
instead of
def add_item(produit_id)
P.S. The controller is not RESTful. It's called CartsController, but in your index action you list the CartItems, not the Carts. The correct name should be CartItemsController. If you rename the controller to CartItemsController, than the index action can stay the same, but the add_item action should better be renamed to simply create. Thus, in your routes you can have:
resources :cart_items, only: [:index, :create]
Also, I am not exactly sure, what is going on in the add_item method - at first you assign a new CartItem to #cart_item, but then you override this assignment with find_or_create_by.... Also, the call to save at the end of the method is redundant, as create will save the record and otherwise no modifications have been made between the find_or_create_by line and the save line.
Related
I have an action controller url generation error with the following:
class ProduitsController < ApplicationController
before_action :set_cart, only: [:create, :destroy]
before_action :set_cart_item, only: [:destroy]
def index
#produits = Produit.order(:nom).to_a
#produits = Produit.all
#categories = Categorie.all.order("categories.created_at DESC")
end
def show
#produit = Produit.find(params[:id])
end
def add_to_cart
if session[:cart_id].blank?
cart = Cart.create(status: 'pending')
session[:cart_id] = cart.id
else
cart = Cart.find(session[:cart_id])
end
produit = Produit.find(params[:id])
cart.cartships.create(produit_id: produit.id, quantite: 1)
redirect_to cart
end
end
Here the index.html.erb
<div id="boutique-right">
<div id="produits-column-container">
<% if #produits %>
<% #produits.in_groups_of(3, false).each do |group| %>
<div id="produits-row-container">
<% group.each do |produit| %>
<div class="boutique-produit">
<div>
<%= image_tag produit.photo %>
</div>
<div>
<p><%= produit.nom %></p>
</div>
<div class="selection-action">
<div>
<%= link_to 'Voir fiche produit', produit_path(#produit) %>
</div>
<div>
<%= number_to_currency(produit.prix, unit: '€', format: '%n%u') %>
</div>
</div>
<div class="marche-quantite-increment-container">
<!-- Increment/decrement method -->
<div>—</div>
<div>1</div>
<div>+</div>
</div>
<div class="add-to-cart-home">
<%= link_to 'Ajouter au panier' %>
</div>
</div>
<% end %>
</div>
<% end %>
<% end %>
</div>
</div>
Then, i have the following error message:
ActionController::UrlGenerationError in Produits#index
No route matches {:action=>"show", :controller=>"produits", :id=>nil} missing required keys: [:id]
Here is routes.rb:
Rails.application.routes.draw do
match "/mon-panier" => 'carts#index', via: :get
resources :carts
resources :produits, only: [:index, :show]
match "/presse" => 'presses#index', via: :get
match "/partenaires" => 'partenaires#index', via: :get
match "/mon-profil" => 'profils#show', via: :get
match "/commandes-produits-breton" => 'commandes#index', via: :ge
match "/paiements" => 'paiements#index', via: :get
resources :categories
resources :order_abonnements, only: [:create, :update, :delete]
get 'livraisons_type/index'
match "/recapitulatif" => 'recapitulatif#index', via: :get
match "/confirmation-carte-cadeau" => 'recapitulatif#confirmation', via: :get
match "/livraison-carte-cadeau" => 'livraison_carte#index', via: :get
match '/activation-carte' => 'code_carte_cadeau#index', via: :get
match "/offrir-une-box-bretonne" => 'cadeau#index', via: :get
match "/nos-box" => 'nos_box#index', via: :get
get 'categories/index'
devise_for :admin_users, ActiveAdmin::Devise.config
ActiveAdmin.routes(self)
match '/informations-penn-ar-box' => 'informations_penn_ar_box#index', via: :get
match '/livraison-box-bretonne' => 'livraison_box_bretonne#index', via: :get
match '/abonnements' => 'abonnements#index', via: :get
devise_for :users, path: '', path_names: { sign_in: 'connexion', sign_out: 'déconnexion'}
resources :users do
delete 'déconnexion' => 'devise/sessions#destroy'
resources :profil
end
root 'home#home'
end
I also can't access the product show view because Rails can't find any product with id=
You are passing #produit to the path helper. Where as you should pass produit
Changing this line in index.html.erb will solve the issue
<%= link_to 'Voir fiche produit', produit_path(#produit) %>
to
<%= link_to 'Voir fiche produit', produit_path(produit) %>
I am new bee in rails and trying to figure out how to pass id using custom controller but it look a blocker to me.
below is code of controller :
class UploadsController < ApplicationController
def index
#upload = Upload.new
#uploadimage = Upload.all
end
def home
end
def destroy
end
end
below is the index.html.erb file
<h1>Upload#index</h1>
<p>Find me in app/views/upload/index.html.erb</p>
<%= form_for(#upload, url: "/uploads/home", :html => {:class => 'dropzone'} ) do |f| %>
<div class="fallback">
<input name="file" type="file" multiple />
</div>
<% end %>
<h3>Uploaded images</h3>
<% #uploadimage.each do |image| %>
<% if !image.nil? %>
<%= image_tag("/images/#{image.name}",style: 'height:100px; width:100px;') %>
<%= link_to "delete #{image.name}", uploads_url(image) %>
<% else %>
<p>No images are present in db</p>
<% end %>
<% end %>
below is routes.rb
Rails.application.routes.draw do
get "uploads", to: "uploads#index", via: :get
get "uploads/:id", to: "uploads#destroy", via: :get
get "uploads/index/:id", to: "uploads#destroy", via: :get
get "uploads/index/", to: "uploads#index", via: :get
root "uploads#index"
end
how to pass id to destroy/home action as i m getting id as dot instead of slash
Why you are using custom routes, if rails providing RESTful routes using resources
Rails.application.routes.draw do
resources :uploads
root "uploads#index"
end
Edited:
Rails.application.routes.draw do
resources :uploads, :controller => "custom_controller"
root "uploads#index"
end
This will manage all 7 action, and check rake routes for path for this all 7 action.
my routes.rb
root 'pages#home'
get 'about', to: 'pages#about'
resources :articles
match ':controller(/:action(/:id))', :via => [:get, :post]
my articles_controller.rb
def delete
#article = Article.find(params[:id])
end
def destroy
article = Article.find(params[:id])
article.destroy
flash[:notice] = "Article destroyed successfully."
redirect_to(:action => 'index')
end
my delete.html.rb
<h2>Delete Article</h2>
<div class="subjects delete">
<h2>Delete Subject</h2>
<%= form_for(:article, :url => {:action => 'destroy', :id => #article.id}) do |f| %>
<p>Are you sure you want to permanently delete this subject?</p>
<p><%= #article.title %></p>
<div class="form-buttons">
<%= submit_tag("Delete Article") %>
</div>
<% end %>
</div>
Now the problem is when i click edit article its redirecting to
http://localhost:3000/articles/7/edit
Show is redirecting to localhost:3000/articles/7
Where as delete is redirecting to localhost:3000/articles/delete/8
and when clicking delete button it says The action '8' could not be found for ArticlesController
Why i dont get redirected to localhost:3000/articles/8/delete
i changed routes.rb to
match ':controller(/:id(/:action))', :via => [:get, :post]
in this delete works but edit doesnt.
You'll be best using the resources directive for the routes:
#config/routes.rb
resources :articles #-> url.com/articles/:id/destroy
resources :pages, only: [], path: "" do
get :about, on: :collection #-> url.com/about
end
root 'pages#home'
The above will provide the correct routes.
Your problem is you're submitting a form to try and change the value. This will not work; you'll need:
#app/views/articles/show.html.erb
<%= button_to "Delete", article, method: :delete, data: { confirm: "Are you sure?" } %>
This will call your posts#destroy controller & fire your code (which seems okay).
My error says that:
Couldn't find Question with 'id'=your_questions"
and
ActiveRecord::RecordNotFound in QuestionsController#show
What should I do to fix it?
def show
#question = Question.find(params[:id])
#answer = Answer.new
end
on the second line it says where the error is.
Edit:
The Index View File
<%= form_for(#question) do |f| %>
<%= render 'common/form_errors', object: #question %>
<p>
<%= f.label :body, "Question" %><br />
<%= f.text_field :body %>
<%= f.submit "Ask a Question" %>
</p>
<% end %>
Rails.application.routes.draw do
get "/" => "main_app#index"
get "/location" => "location#location"
post "/location/index" => "location#index"
get "/location/index" => "location#index"
get "/location/directions" => "location#directions"
root to: 'questions#index'
get '/logout', to: 'sessions#destroy', via: :delete
resources :users, only: [:new, :create]
resources :sessions, only: [:new, :create]
resources :questions, except: [:new] do
resources :answers, only: [:create]
end
get '/register', to: 'users#new'
get '/login', to: 'sessions#new'
get '/logout', to: 'sessions#destroy', via: :delete
get '/questions/:id', to: 'questions#your_questions'
get '/search', to: 'questions#search'
You mention you have this route:
get '/questions/your_questions', to: 'questions#your_questions
If you also have a route like following the restful style, you should also have something like:
get 'questions/:id', to: 'questions#your_questions'
Or a resource call. Anyway, so Rails is actually trying to access your show action passing "your_questions" as the id for the route. Write this route like this:
get '/questions/:id', to: 'questions#show
This means: "If a request using the GET HTTP method follows the url 'questions/:id', then go to controller: questions and its action(method in the controller) called: your_questions" and pass into the params hash the value of id as in the URL.
I have a controller "find_numbers", which I'm using to submit a form to the Twilio API. Before it submits though, I'd like to validate against two form fields, which aren't in the data model for this controller. The fields are :name, and :original_number
So, in my find_numbers model, I added attr_accessor :name, attr_accessor :originial number to run a validates command under it.
After doing that and submitting the form as invalid, I get the error :
Routing Error
No route matches {:controller=>"phone", :action=>"new"}
Try running rake routes for more information on available routes.
I'm not sure why it says there's no roots, but I'm not sure why it's accessing that anyways. I want it to POST to find_numbers
The find_numbers/new template
<%= form_tag("/find_numbers", :method => "post", :id => "new_user" ) do %>
<%= render 'shared/error_messages' %>
<%= label_tag(:name, "What Are You Tracking?") %>
<%= text_field_tag(:name) %>
<%= label_tag(:original_number, "Your Orginal Number") %>
<%= text_field_tag(:original_number) %>
<%= label_tag(:in_postal_code, "Near US postal code (e.g. 94117):") %>
<%= text_field_tag(:in_postal_code) %>
<%= label_tag(:near_number, "Near this other number (e.g. +4156562345)") %>
<%= text_field_tag(:near_number) %>
<%= label_tag(:contains, "Matching this pattern (e.g. 415***EPIC):") %>
<%= text_field_tag(:contains) %>
<%= submit_tag("Search", :class => "btn btn-large btn-primary") %>
<% end %>
here's my find_number model
class FindNumber < ActiveRecord::Base
attr_accessor :name
attr_accessor :original_number
validates :name, presence: true
validates :original_number, presence: true
end
Here's my Find_number controller
class FindNumbersController < ApplicationController
def new
#user = current_user
end
def create
#user = current_user
client = Twilio::REST::Client.new(#user.twilio_account_sid, #user.twilio_auth_token)
search_params = {}
%w[in_postal_code near_number contains].each do |p|
search_params[p] = params[p] unless params[p].nil? || params[p].empty?
end
local_numbers = client.account.available_phone_numbers.get('US').local
#numbers = local_numbers.list(search_params)
unless #numbers.empty?
render 'find_numbers/show'
else
flash.now[:error] = "Sorry, We Couldn't Find Any Numbers That Matched Your Search! Maybe Something Simpler?"
render 'find_numbers/new'
end
end
def show
end
end
Any thoughts on accomplishing this would be greatly appreciated!
Edit
Routes.rb file
Dct::Application.routes.draw do
resources :users
resources :sessions, only: [:new, :create, :destroy]
resources :phones, only: [:new, :create, :destroy]
resources :find_numbers, only: [:new, :create, :destroy]
match '/find_numbers', to: 'find_numbers#new'
match '/signup', to: 'users#new'
match '/login', to: 'sessions#new'
match '/signout', to: 'sessions#destroy', via: :delete
root to: 'static_pages#home'
match '/product_demo', to: 'static_pages#product_demo'
match '/pricing', to: 'plans#index'
match '/contact', to: 'static_pages#contact'
Edit
Here is the server log, of what happened when I hit submit
http://stepanp.com/railserror.jpg
Also, here's the find_numbers/show view
From what you've posted, the only other thing that looks suspicious to me is that you presumably have a PhonesController (plural) since you've declared resources :phones, but the routing error seems to occur because it is looking for a PhoneController (singular).