<Ruby on Rails> Routes - ruby-on-rails

I'm a beginner in ruby on rails and was following an online tutorial. I got lost immediately on routes. Every time I try to go to my url 'pages/help' an error is displaying in the browser "The action 'show' could not be found for PagesController". I have a ruby partitions named _header that contains these codes:
<header>
<%= link_to logo, root_path %>
<ul class="nav nav-tabs">
<li class="active">
<%= link_to "Home |", root_path %>
</li>
<li><%= link_to "Help |", pages_help_path %></li>
<li><%= link_to "Sign In", '#'%></li>
</ul>
</header>
And when I try to click the "Help" link the error occurs.
My routes.rb contains just these codes:
BakeShop::Application.routes.draw do
resources :pages
root :to => 'pages#home'
#match '/help', :to => 'pages#help'
get "pages/help"
end
and i have a PagesController with only these codes:
class PagesController < ApplicationController
def home
end
def help
end
end
and when I run 'rake routes' the lists contained are:
pages GET /pages(.:format) pages#index
POST /pages(.:format) pages#create
new_page GET /pages/new(.:format) pages#new
edit_page GET /pages/:id/edit(.:format) pages#edit
page GET /pages/:id(.:format) pages#show
PATCH /pages/:id(.:format) pages#update
PUT /pages/:id(.:format) pages#update
DELETE /pages/:id(.:format) pages#destroy
root GET / pages#home
pages_help GET /pages/help(.:format) pages#help
And I certainly have home.html.erb and help.html.erb created in my views folder. And the twist is that when I create a 'show.html.erb' in my views folder and create an action in my pages controller named 'show', the error disappears and links to .
So what I'm saying is, can anyone explain this? Why is rails looking for 'show' action, and not 'help' action, that I didn't define

One thing to understand about routes in Rails is that the order of routes specified is very important. In your config/routes.rb file you have routes specified in the following order:
resources :pages
root :to => 'pages#home'
get "pages/help"
So, what this does is, matches the routes defined with resources :pages first. As you can see in the output of rake routes, Rails generated the following routes for that specific line i.e. resources :pages:
pages GET /pages(.:format) pages#index
POST /pages(.:format) pages#create
new_page GET /pages/new(.:format) pages#new
edit_page GET /pages/:id/edit(.:format) pages#edit
page GET /pages/:id(.:format) pages#show
PATCH /pages/:id(.:format) pages#update
PUT /pages/:id(.:format) pages#update
DELETE /pages/:id(.:format) pages#destroy
Also note that pages_help GET /pages/help(.:format) pages#help is at the bottom of that list. So what is happening is when you navigate to /pages/help, Rails finds the first GET request that matches that pattern, in this case:
page GET /pages/:id(.:format) pages#show
And since you don't have the show action defined, it's throwing that error "The action 'show' could not be found for PagesController".
So, to solve you specific problem without the show action and show.html.erb, you can rearrange the config/routes.rb as follows:
BakeShop::Application.routes.draw do
get "pages/help" # Move this line before resources :pages
resources :pages
root :to => 'pages#home'
end
Moving get "pages/help" will ensure that for your url /pages/help this route will match and your help.html.erb will be rendered.
Update:
How it matched pages/show?
# In the comments below where .format is used think of various extensions just as html, js, json, xml etc but not required.
pages GET /pages(.:format) pages#index
# Matches /pages, /pages.format
new_page GET /pages/new(.:format) pages#new
# Matches /pages/new, /pages/new.format
edit_page GET /pages/:id/edit(.:format) pages#edit
# Matches /pages/1/edit, /pages/1/edit.format or pages/anything/edit.format. Note that the edit in the end is required here,the only variable here is id and format
page GET /pages/:id(.:format) pages#show
# Matches /pages/1, /pages/anything, /pages/1.format, /pages/anything.format. In the question /pages/help matches.

You have to enable the default root in your routes.rb.
Update routes.rb:-
BakeShop::Application.routes.draw do
resources :pages
root :to => 'pages#home'
#match '/help', :to => 'pages#help'
get "pages/help" #this is not required
match ':controller(/:action(/:id(.:format)))'
end

The problem here is that the route for the show action (page_path) and the route for your pages_help_path conflict. If you simply move the line get "pages/help" before the line resources :pages it will work as you intend.
Routes.rb:
BakeShop::Application.routes.draw do
get "pages/help"
resources :pages
root :to => 'pages#home'
end

Related

I am working on An Ruby on Rails app

I am working an an Rails app. The problem I am have is when I cycle between my about and contact pages. I always get the error
No route matches [GET] "/pages/pages/about"
or
No route matches [GET] "/pages/pages/contact"
I'm trying to change the routes my nav bar partial the tag href to "/about" but the same error occur. it ask me to use the command rake routes and it shows
$ rake routes
restaurants GET /restaurants(.:format) restaurants#index
POST /restaurants(.:format) restaurants#create
new_restaurant GET /restaurants/new(.:format) restaurants#new
edit_restaurant GET /restaurants/:id/edit(.:format) restaurants#edit
restaurant GET /restaurants/:id(.:format) restaurants#show
PUT /restaurants/:id(.:format) restaurants#update
DELETE /restaurants/:id(.:format) restaurants#destroy
pages_about GET /pages/about(.:format) pages#about
root / restaurants#index
pages_contact GET /pages/contact(.:format) pages#contact"
can some one please help me!!
Your about and contact are under the url /pages/about and /pages/contact but the URL you are accessing is /pages/pages/about which doesn't exist.
You can see in the rake routes, the possible urls in the system.
you need to have the link in your web app as
<%= link_to 'About', pages_about_path %>
<%= link_to 'Contact', pages_contact_path %>
in your routes you can do something like
#config/routes.rb
ClientCruiser::Application.routes.draw do
....
match "contact" => "pages#contact", :as => :contact, via: :all
match "about" => "pages#about", :as => :about, via: :all
....
root :to => 'pages#index'
end
The output of this
contact /contact(.:format) pages#contact
about /about(.:format) pages#about
root GET / pages#index
the way you would make the call would be
<%= link_to about_path, "About", class: '' %>
<%= link_to contact_path, "Contact", class: '' %>

Rails: Linking from Subdomain to Main Domain and Back

I have an app with subdomains for various people that all share the same domain (i.e. www.liz.domain.com, www.anthony.domain.com, etc.). I need to create links from one subdomain to the main domain and back, but can't figure out how to make it work. My routes stand like this:
Rails.application.routes.draw do
constraints subdomain: 'liz' do
scope module: 'liz', as: 'liz' do
get 'home/index'
root 'home#index'
resources :inquiries
get 'services/hire'
get 'services/dev'
get 'services/design'
get 'services/branding'
get 'services/portfolio'
end
end
constraints subdomain: 'anthony' do
scope module: 'anthony', as: 'anthony' do
get 'home/index'
root 'home#index'
end
end
get 'home/index'
root 'home#index'
end
And when I rake routes it turns out like this:
Prefix Verb URI Pattern Controller#Action
liz_home_index GET /home/index(.:format) liz/home#index {:subdomain=>"liz"}
liz_root GET / liz/home#index {:subdomain=>"liz"}
liz_inquiries GET /inquiries(.:format) liz/inquiries#index {:subdomain=>"liz"}
POST /inquiries(.:format) liz/inquiries#create {:subdomain=>"liz"}
new_liz_inquiry GET /inquiries/new(.:format) liz/inquiries#new {:subdomain=>"liz"}
edit_liz_inquiry GET /inquiries/:id/edit(.:format) liz/inquiries#edit {:subdomain=>"liz"}
liz_inquiry GET /inquiries/:id(.:format) liz/inquiries#show {:subdomain=>"liz"}
PATCH /inquiries/:id(.:format) liz/inquiries#update {:subdomain=>"liz"}
PUT /inquiries/:id(.:format) liz/inquiries#update {:subdomain=>"liz"}
DELETE /inquiries/:id(.:format) liz/inquiries#destroy {:subdomain=>"liz"}
liz_services_hire GET /services/hire(.:format) liz/services#hire {:subdomain=>"liz"}
liz_services_dev GET /services/dev(.:format) liz/services#dev {:subdomain=>"liz"}
liz_services_design GET /services/design(.:format) liz/services#design {:subdomain=>"liz"}
liz_services_branding GET /services/branding(.:format) liz/services#branding {:subdomain=>"liz"}
liz_services_portfolio GET /services/portfolio(.:format) liz/services#portfolio {:subdomain=>"liz"}
anthony_home_index GET /home/index(.:format) anthony/home#index {:subdomain=>"anthony"}
anthony_root GET / anthony/home#index {:subdomain=>"anthony"}
home_index GET /home/index(.:format) home#index
root GET / home#index
I've tried using a <%= link_to "Liz's Page", liz_root_path(subdomain: 'liz') %> or <%= link_to "Liz's Page", liz_root_path %> from the main domain (without a subdomain), but neither links to the subdomain.
Similarly, I've tried <%= link_to "Main Page", root_path %> from a page inside a subdomain and it just links to the subdomain's home, not the site root.
Can anyone straighten me out on how to link back and forth between subdomains/main domains?
I eventually changed these from path to url to solve the problem.
This way <%= link_to "Liz's Page", liz_root_path(subdomain: 'liz') %> became <%= link_to "Liz's Page", liz_root_url(subdomain: 'liz') %> and worked fine.

Invalid path in form using namespace routes

I have some routes under a namespace
namespace :admin do
resources :pages
end
what should i write in the page form in order to perform POST and PUT request?
I tried with
= form_for(#page, url: page_path(#page)) do |f|
but i get this error
undefined method `page_path'
but it works fine when i try to edit a page.
Here my routes for page
pages GET /pages(.:format) pages#index
POST /pages(.:format) pages#create
new_page GET /pages/new(.:format) pages#new
edit_page GET /pages/:id/edit(.:format) pages#edit
page GET /pages/:id(.:format) pages#show
PUT /pages/:id(.:format) pages#update
DELETE /pages/:id(.:format) pages#destroy
thank you
Try with:
= form_for [:admin, #page] do |f|
The namespace will be added to the page resource path.

Ruby on Rails - routing error, goes to "show" instead of "index"

I have a basic homepage with a link that I would like to go to businesses/index.html.erb
<%= link_to("Go to businesses index page", {:controller=>"businesses", :action =>"index"}) %>
When I click on this link I get a routing error:
No route matches {:action=>"show", :controller=>"businesses"}
My routes.rb file looks like:
RailsProject::Application.routes.draw do
get "welcome/index"
root :to => 'welcome#index'
get "businesses/index"
resources :businesses
end
and rake routes gets me:
welcome_index GET /welcome/index(.:format) welcome#index
businesses GET /businesses(.:format) businesses#index
POST /businesses(.:format) businesses#create
new_business GET /businesses/new(.:format) businesses#new
edit_business GET /businesses/:id/edit(.:format) businesses#edit
business GET /businesses/:id(.:format) businesses#show
PUT /businesses/:id(.:format) businesses#update
DELETE /businesses/:id(.:format) businesses#destroy
root / welcome#index
businesses_index GET /businesses/index(.:format) businesses#index
I am using rails version 3.2
The problem was that in my businesses/index there was a line reading
<%= link_to 'show', business_path %>
that should have been
<%= link_to 'show', business_path(business) %>

RoutingError on a mounted engine in a controller spec

I created a mountable engine with this routes :
Rails.application.routes.draw do
scope module: :minimalist_cms do
root to: "pages#show"
get ':id', to: "pages#show"
resources :pages
resources :page_parts
end
end
And I have this test :
require 'spec_helper'
module MinimalistCms
describe PagesController, type: :controller do
let(:page) { stub_model(Page) }
describe :show do
context "when there is a page" do
it 'should find by slug' do
Page.should_receive(:find_by_slug).and_return(page)
get :show, id: 'test'
end
end
end
end
end
And when I type rake routes I have this result :
root / minimalist_cms/pages#show
GET /:id(.:format) minimalist_cms/pages#show
pages GET /pages(.:format) minimalist_cms/pages#index
POST /pages(.:format) minimalist_cms/pages#create
new_page GET /pages/new(.:format) minimalist_cms/pages#new
edit_page GET /pages/:id/edit(.:format) minimalist_cms/pages#edit
page GET /pages/:id(.:format) minimalist_cms/pages#show
PUT /pages/:id(.:format) minimalist_cms/pages#update
DELETE /pages/:id(.:format) minimalist_cms/pages#destroy
page_parts GET /page_parts(.:format) minimalist_cms/page_parts#index
POST /page_parts(.:format) minimalist_cms/page_parts#create
new_page_part GET /page_parts/new(.:format) minimalist_cms/page_parts#new
edit_page_part GET /page_parts/:id/edit(.:format) minimalist_cms/page_parts#edit
page_part GET /page_parts/:id(.:format) minimalist_cms/page_parts#show
PUT /page_parts/:id(.:format) minimalist_cms/page_parts#update
DELETE /page_parts/:id(.:format) minimalist_cms/page_parts#destroy
It works but if I change for this, in my engine :
MinimalistCms::Engine.routes.draw do
scope module: :minimalist_cms do
root to: "pages#show"
get ':id', to: "pages#show"
resources :pages
resources :page_parts
end
end
And in my application :
mounted in my dummy application like this :
Dummy::Application.routes.draw do
mount MinimalistCms::Engine, at: '/'
end
I have this error :
Failure/Error: get :show, id: 'test'
ActionController::RoutingError:
No route matches {:id=>"test", :controller=>"minimalist_cms/pages", :action=>"show"}
And the rake routes result seem to be similar :
minimalist / MinimalistCms::Engine
root / minimalist_cms/pages#show
GET /:id(.:format) minimalist_cms/pages#show
pages GET /pages(.:format) minimalist_cms/pages#index
POST /pages(.:format) minimalist_cms/pages#create
new_page GET /pages/new(.:format) minimalist_cms/pages#new
edit_page GET /pages/:id/edit(.:format) minimalist_cms/pages#edit
page GET /pages/:id(.:format) minimalist_cms/pages#show
PUT /pages/:id(.:format) minimalist_cms/pages#update
DELETE /pages/:id(.:format) minimalist_cms/pages#destroy
page_parts GET /page_parts(.:format) minimalist_cms/page_parts#index
POST /page_parts(.:format) minimalist_cms/page_parts#create
new_page_part GET /page_parts/new(.:format) minimalist_cms/page_parts#new
edit_page_part GET /page_parts/:id/edit(.:format) minimalist_cms/page_parts#edit
page_part GET /page_parts/:id(.:format) minimalist_cms/page_parts#show
PUT /page_parts/:id(.:format) minimalist_cms/page_parts#update
DELETE /page_parts/:id(.:format) minimalist_cms/page_parts#destroy
The behaviour of the application is not changed, it works, but the test fail.
Do you have a solution?
Maybe instead of using a scope, try to use write the routes the normal way (without scope).
Now in the file where you declare the engine which inherits from Rails::Engine add isolated_namespace.
Module MinimalistCms
Class Engine < Rails::Engine
isolate_namespace MinimalistCms
end
end
Try running your test now.

Resources