Rails 3.2.1 Routing Error - No route matches - ruby-on-rails

I'm getting the following error:
Routing Error
No route matches {:controller=>"tasks", :action=>"complete", :list_id=>1, :id=>nil}
Try running rake routes for more information on available routes.
This is what I have in my routes.rb file:
resources :lists do
resources :tasks
end
match 'lists/:list_id/tasks/:id/complete' => 'tasks#complete', :as => :complete_task
root :to => 'lists#index'
In my tasks_controller:
attr_accessor :completed
before_filter :find_list
def create
#task = #list.tasks.new(params[:task])
if #task.save
flash[:notice] = "Task created"
redirect_to list_url(#list)
else
flash[:error] = "Could not add task at this time."
redirect_to list_url(#list)
end
end
def complete
#task = #list.tasks.find(params[:id])
#task.completed = true
#task.save
redirect_to list_url(#list)
end
private
def find_list
#list = List.find(params[:list_id])
end
And in show.html.erb (where the error occurs):
<%= button_to "Complete", complete_task_path(#list.id,task.id) %>
Can someone please tell me what I'm doing wrong?

What's causing the problem is that task.id in your show view returns nil, while in your routes:
match 'lists/:list_id/tasks/:id/complete' => 'tasks#complete', :as => :complete_task
Requires a task id in order to match the url pattern.
You can read more about it in this blog post.

Related

Rails button_to No route matches {:action=>"complete", :controller=>"dashboard", :name=>"Order"}

Please help i have tried my best. I really need your help.
So im trying to make a mark order as complete. Now it all works up to the button to mark order as complete. I ran a migration to add.
class AddCompleteToOrder < ActiveRecord::Migration
def change
add_column :orders, :complete, :boolean, default: false
end
end
Then i added a method the order.rb of
def complete!
update(complete: true)
end
Then routes.rb
resources :orders do
post "complete", to: "orders#complete", on: :member
end
Then this is the button
= button_to "Mark as complete", { action: "complete", id: #order.id }
But i dont have a #order.id
but a order does have a #order.name so i changed it to
= button_to "Mark as complete", { action: "complete", name: #order.name }
But then i get the error:
ActionController::UrlGenerationError in Dashboard#dadmin
Showing /Users/jacksharville/Desktop/dancer/app/views/dashboard/dadmin.html.haml where line #87 raised:
No route matches {:action=>"complete", :controller=>"dashboard", :name=>"Order"}
Extracted source (around line #87):
85
86
87
= link_to "Back to Dashboard", :back, :class => 'btn-danger btn'
= button_to "Mark as complete", { action: "complete", name: #order.name }
So clearly im doing the routes.rb wrong but i cant fix it. Please help. Any help greatly appreciated.
routes.rb (full file)
Rails.application.routes.draw do
mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
get 'home/index'
root 'home#index'
#pages
get '/why' => 'pages#why'
get '/trak' => 'pages#trak'
get '/contact' => 'pages#contact'
get '/mydms' => 'pages#mydms'
get '/air' => 'pages#air'
get '/ocean' => 'pages#ocean'
get '/road' => 'pages#road'
get '/courier' => 'pages#courier'
get 'fulfilment' => 'pages#fulfilment'
get 'express' => 'pages#express'
resources :dashboard
get 'dadmin' => 'dashboard#dadmin'
get 'myorders' => 'dashboard#myorders'
get 'label' => 'dashboard#label'
resources "contacts", only: [:new, :create]
devise_for :users
as :user do
get 'users/edit' => 'devise/registrations#edit', :as => 'edit_user_registration'
put 'users' => 'devise/registrations#update', :as => 'user_registration'
end
resources "orders"
get "/confirm" => "confirmations#show"
get 'dconfirmation' => 'orders#confirmation'
resources :orders do
post "complete", to: "orders#complete", on: :member
end
end
orders_controller.rb
class OrdersController < ApplicationController
before_filter :authenticate_user!
def new
#order = Order.new
end
def create
#order = current_user.orders.new(order_params)
#order.email = current_user.email
#order.name = current_user.name
#order.address_line_1 = current_user.address_line_1
#order.address_line_2 = current_user.address_line_2
#order.postcode = current_user.postcode
#order.city = current_user.city
#order.country = current_user.country
if #order.save
redirect_to dconfirmation_path
end
end
def order_params
params.require(:order).
permit(
:email,
:delivery_name,
:company_name,
:delivery_address1,
:delivery_address2,
:delivery_address3,
:delivery_city,
:delivery_postcode,
:delivery_country,
:phone,
:package_contents,
:description_content,
:restricted_items,
:terms_conditions,
:insurance,
:contents_value,
:cf_reference,
:reference_number
)
end
def show
#user = User.find(params[:id])
end
def confirmation
end
def complete!
order = Order.find(params[:id])
order.complete!
# handle response
end
end
dashboard_controller.rb
class DashboardController < ApplicationController
before_filter :authenticate_user!
def index
end
def admindashboard
(current_user.nil?) ? redirect_to(root_path) : (redirect_to(root_path) unless current_user.admin?)
end
def adminuser
(current_user.nil?) ? redirect_to(root_path) : (redirect_to(root_path) unless current_user.admin?)
end
def dadmin
(current_user.nil?) ? redirect_to(root_path) : (redirect_to(root_path) unless current_user.admin?)
# #order = Order.all
#order = Order.order("name").page(params[:page]).per(1)
end
def myorders
#order = current_user.orders.order("name").page(params[:page]).per(1)
end
def show
#user = User.find(params[:id])
end
def label
#order = current_user.orders.order("name").page(params[:page]).per(1)
end
def complete!
order = Order.find(params[:id])
order.complete!
# handle response
end
end
You can specify this additional option in the button_to tag :controller => "order", but the proper way to use button_to tag is to not create a separate hash for options. Instead use it as a button_to("Mark as complete", controller: "order", action: "complete", name: #order.name)
try this
button_to "Mark as complete", { controller: "orders", action: "complete", name: #order.name }, {method: :post}
This link can help: Routing Error - No route matches when using button_to with custom action
rake routes give me:
complete_order POST /order/:id/complete(.:format) orders#complete
You need to move the complete action from DashboardsController to OrdersController, which is where it is defined in the routes file.
Also, you can probably use:
= button_to "Mark as complete", complete_order_path(#order)
The controller action is looking for params[:order_id] so it can find the right order. I am not sure how orders are defined in your view, but you will need to pass an order object to the path.
If by any chance you defined a to_param method in Order class, which defines order's name rather than id as params, you will need to update the complete action to look for an order by name.
But my guess is that it is the default id. So passing the order object to the path should work.

No route matches [GET] "/book/list" part II: The Route Revenge of Rails

I am trying to follow this rails tutorial but I am having a lot of issues due to version mismatches. I followed the instructions exactly and I really understand everything up until now but I can't seem to resolve this routing issue on my own. I read a good deal about routes independently but can't figure out what to do. This question has been posted once before on stackoverflow but that solution does not work for me because of version issues
Error Message:
No route matches [GET] "/book/list"
When trying to access http://localhost:3000/book/list.
Code
route.rb
Rails.application.routes.draw do
resources: :books
end
views>book>list.rhtml
<% if #books.blank? %>
<p>There are not any books currently in the system.</p>
<% else %>
<p>These are the current books in our system</p>
<ul id="books">
<% #books.each do |c| %>
<li><%= link_to c.title, {:action => 'show', :id => c.id} -%></li>
<% end %>
</ul>
<% end %>
<p><%= link_to "Add new Book", {:action => 'new' }%></p>
models>book.rb
class Book < ActiveRecord::Base
belongs_to :subject
validates_presence_of :title
validates_numericality_of :price, :message=>"Error Message"
end
models>subject.rb
class Subject < ActiveRecord::Base
has_many :books
end
controllers>book_controller.rb
class BookController < ApplicationController
def list
#books = Book.find(:all)
end
def show
#book = Book.find(params[:id])
end
def new
#book = Book.new
#subjects = Subject.find(:all)
end
def create
#book = Book.new(params[:book])
if #book.save
redirect_to :action => 'list'
else
#subjects = Subject.find(:all)
render :action => 'new'
end
end
def edit
#book = Book.find(params[:id])
#subjects = Subject.find(:all)
end
def update
#book = Book.find(params[:id])
if #book.update_attributes(params[:book])
redirect_to :action => 'show', :id => #book
else
#subjects = Subject.find(:all)
render :action => 'edit'
end
end
def delete
Book.find(params[:id]).destroy
redirect_to :action => 'list'
end
def show_subjects
#subject = Subject.find(params[:id])
end
end
There are a couple of issues I'm seeing. For one, your controller should be BooksController and not BookController (you'll also need to ensure it's in a file called books_controller.rb). Two, when you do resources :books, Rails will create the following routes
GET /books -> index
GET /books/:id -> show
GET /books/:id/edit -> edit
PUT /books/:id -> update
GET /books/new -> new
POST /books -> create
DELETE /books/:id -> destroy
As you can see, list is not one of the routes created, which is why you're getting that error message.
Extending #BartJedrocha's answer, first of all with your current routes i.e.
resources: :books
your application should not work and give you a Syntax error syntax error, unexpected ':', expecting keyword_end (SyntaxError).
As resources is a method invocation with argument :books.
So your route should be
resources :books ## Notice no : after "resources"
You have defined resources :books in your routes.So your controller Class name should be Plural ie., BooksController not BookController.So is the error.
Change your controller class name to BooksController and your filename to books_controller.rb
OR
update your routes to
resource :book #not singular
Note: I prefer the first way,because it suites the Rails convention
Update
You have to update your routes to like this
resources :books do
collection do
get 'list'
end
end
This will enable Rails to recognize the path /books/list with GET, and route to the list action of BooksController.

Adding a route for a controller action

I am implementing a like system in my rails app using David Celis gem called Recommendable. I've gotten everything to work in the console but I can't get the right routes and I'm getting the "No route matches [GET] "/categories/1/posts/1/like" error.
I have the following in my models:
class Category < ActiveRecord::Base
has_many :posts, :dependent => :destroy
extend FriendlyId
friendly_id :name, use: :slugged
end
class Post < ActiveRecord::Base
belongs_to :category
end
In my Post Controller I have:
class PostsController < ApplicationController
before_filter :authenticate_user!
before_filter :get_category
def like
#post = Post.find(params[:id])
respond_to do |format|
if current_user.like #post
else
flash[:error] = "Something went wrong! Please try again."
redirect_to show_post_path(#category, #post)
end
end
end
end
In my routes I have:
resources :categories do
resources :posts do
put :like, :on => :member
end
end
match 'categories/:category_id/posts/:id', :to => 'posts#show', :as => 'show_post'
Can someone please point at my errors? I can get the PUT to work but I dont know where the GET error is coming from as I am trying to redirect back to the post if an error occurs when the user like's a certain post. Thank you in advance.
EDIT:
In my view I have:
- title "#{#post.class}"
%p#notice= notice
%p
%b Title:
= #post.title
%p
%b Description:
= #post.description
%p
%b Likes:
= #post.liked_by.count
= link_to 'Edit', edit_category_post_path(#post)
\|
= link_to 'Back', category_posts_path
\|
= link_to 'Like', like_category_post_path(#post)
Replace:
= link_to 'Like', like_category_post_path(#post)
with:
= link_to 'Like', like_category_post_path(#category, #post), method: :put
Or, as I like it:
= link_to 'Like', [#category, #post], method: :put
I think your like has to be:
def like
#post = Post.find(params[:id])
respond_to do |format|
format.html do
if current_user.like #post
flash[:notice] = "It's ok, you liked it!"
redirect_to :back
else
flash[:error] = "Something went wrong! Please try again."
redirect_to show_post_path(#category, #post)
end
end
end
end
Your route expects a PUT request, while you're issuing a GET request.
You'll need to either access your route via a button_to with :method => :put so that your app is issuing PUT requests (the correct solution), or change your route to use GET requests (the wrong way to make requests which modify state):
get :like, :on => :member

simple_navigation gem and rails 3.0.9

routes.rb
PASFramework::Application.routes.draw do |map|
resources :users do
collection do
get :index
get :edit
post :update
get :show
end
end
root :to => 'users#index'
end
==================================================================
navigation.rb
# Configures your navigation
SimpleNavigation::Configuration.run do |navigation|
navigation.items do |primary|
primary.item :users, 'Welcome User', root_path do |users|
users.item :edit, 'Edit Profile', edit_users_path
end
end
end
==================================================================
User_controller
class UsersController < ApplicationController
def index
user = current_facebook_user.fetch
#u = User.find_by_facebook_id(user.id)
if #u.nil?
#u = User.find_or_create_by_facebook_id(user.id)
#u.update_attributes( :first_name => current_facebook_user.first_name,
:last_name => current_facebook_user.last_name )
gflash :notice => "Welcome, #{current_facebook_user.name} "
else
gflash :notice => "Welcome back, #{current_facebook_user.first_name} #{current_facebook_user.last_name}"
end
return
rescue Exception
logger.info "Problem"
logger.error($!)
top_redirect_to auth_url
end
def show
end
def edit
user = current_facebook_user.fetch
#user = User.find_all_by_facebook_id(user.id)
end
def update
user = current_facebook_user.fetch
#user = User.find_all_by_facebook_id(user.id)
if #user.update_attributes(:first_name => params[:first_name],
:last_name => params[:last_name])
redirect_to user_path, :notice => t('users.update_success')
else
render :action => 'edit'
end
end
end
==========================================================================
The menu is created really well and thanks for this awesome plugin. But when I click edit user I get an error:
ActionView::Template::Error (No route matches {:action=>"show", :controller=>"users"}):
Can someone help me with that please? Can someone explain me why in routes.rb resources user only is not working instead of the collection thing?
Thanks in advance.
It's because of how you are defining the show route.
resources :users do
collection do
get :index
get :edit
post :update
get :show #this is your problem
end
end
Trying renaming this to a different action. The default show route is getting overridden.
resources :users do
collection do
get :index
get :edit
post :update
get :second_show # of course rename this to a better name
end
end

Confused about Ruby on Rails REST Routing

I am really confused about Ruby on Rails REST routing. Even though I have specified that after the success it should go to the confirm action it goes to the show action and pass the ID=confirm.
def create
#article = Article.new(params[:article])
respond_to do |format|
if #article.save
format.html { redirect_to :action => "confirm" }
else
format.html { render :action => "new" }
end
end
end
The error I get is the following:
ActiveRecord::RecordNotFound in ArticlesController#show
Couldn't find Article with ID=confirm
Rails.root: /Projects/highoncoding
Application Trace | Framework Trace | Full Trace
app/controllers/articles_controller.rb:31:in `show'
UPDATE 1:
Here is my Route.rb file:
resources :articles
get "articles/confirm"
# config/routes.rb
MyApp::Application.routes.draw do
resources :articles do
member do
get 'confirm'
end
end
end
# app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
def create
#article = Article.new(params[:article])
respond_to do |format|
if #article.save
# use a named route here
format.html { redirect_to confirm_article_url(#article) }
else
format.html { render :action => "new" }
end
end
end
end
you'll need to add the route so it looks like
match 'articles/confirm/', :controller => 'article', :action => 'confirm'
resources :articles
you need to have the :id in there or it will think that confirm is an id which is why you are seeing the error ID=confirm. make sure also that this is the first route. (at least before the resources for the articles controller.
You should probably add the confirm route directly in your routes file.
match 'articles/confirm' => 'articles#confirm'
resources only work for create/update/destroy/etc.

Resources