RoutingError on a mounted engine in a controller spec - ruby-on-rails

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.

Related

Administrate - Rails 4 | `add_route': Invalid route name, already in use: 'admin_root'

=> After deploying my rails app on Heroku
=> I cannot access to my admin at mysite.heroku.com/admin
--
I run heroku logs
The error : Invalid route name, already in use: 'admin_root'
/app/vendor/bundle/ruby/2.3.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/route_set.rb:549:in `add_route': Invalid route name, already in use: 'admin_root' (ArgumentError)
And You may have defined two routes with the same name using the :as option
2016-10-24T13:43:56.930010+00:00 app[web.1]: You may have defined two routes with the same name using the `:as` option, or you may be overriding a route already defined by a resource with the same naming. For the latter, you can restrict the routes created with `resources` as explained here:
--
This is my config/routes.rb :
Rails.application.routes.draw do
root 'pages#index'
get '/agence' => 'pages#agence'
get '/methode' => 'pages#methode'
get 'projets' => 'projet#index'
get 'projets/:slug' => 'projet#show', as: 'projet'
get '/article' => 'article#index'
get '/article/:slug' => 'article#show', as: 'articles'
get '/contact' => 'pages#contact'
get '/mentionslegales' => 'pages#mentionslegales'
namespace :admin do
resources :projets
resources :articles
resources :users
# get '/' => 'projets#index'
root to: "projets#index"
end
if defined?(DashboardManifest)
namespace :admin do
DashboardManifest::DASHBOARDS.each do |dashboard_resource|
resources dashboard_resource
end
root controller: DashboardManifest::ROOT_DASHBOARD, action: :index
end
end
--
Rake routes :
Prefix Verb URI Pattern Controller#Action
root GET / pages#index
agence GET /agence(.:format) pages#agence
methode GET /methode(.:format) pages#methode
projets GET /projets(.:format) projet#index
projet GET /projets/:slug(.:format) projet#show
article GET /article(.:format) article#index
articles GET /article/:slug(.:format) article#show
contact GET /contact(.:format) pages#contact
mentionslegales GET /mentionslegales(.:format) pages#mentionslegales
admin_projets GET /admin/projets(.:format) admin/projets#index
POST /admin/projets(.:format) admin/projets#create
new_admin_projet GET /admin/projets/new(.:format) admin/projets#new
edit_admin_projet GET /admin/projets/:id/edit(.:format) admin/projets#edit
admin_projet GET /admin/projets/:id(.:format) admin/projets#show
PATCH /admin/projets/:id(.:format) admin/projets#update
PUT /admin/projets/:id(.:format) admin/projets#update
DELETE /admin/projets/:id(.:format) admin/projets#destroy
admin_articles GET /admin/articles(.:format) admin/articles#index
POST /admin/articles(.:format) admin/articles#create
new_admin_article GET /admin/articles/new(.:format) admin/articles#new
edit_admin_article GET /admin/articles/:id/edit(.:format) admin/articles#edit
admin_article GET /admin/articles/:id(.:format) admin/articles#show
PATCH /admin/articles/:id(.:format) admin/articles#update
PUT /admin/articles/:id(.:format) admin/articles#update
DELETE /admin/articles/:id(.:format) admin/articles#destroy
admin_users GET /admin/users(.:format) admin/users#index
POST /admin/users(.:format) admin/users#create
new_admin_user GET /admin/users/new(.:format) admin/users#new
edit_admin_user GET /admin/users/:id/edit(.:format) admin/users#edit
admin_user GET /admin/users/:id(.:format) admin/users#show
PATCH /admin/users/:id(.:format) admin/users#update
PUT /admin/users/:id(.:format) admin/users#update
DELETE /admin/users/:id(.:format) admin/users#destroy
admin_root GET /admin(.:format) admin/projets#index
I don't understand this error and how to resolve it.
I already read all posts about this error but can't find the solution..
Finally the solution was to with draw theses lines from routes.rb :
if defined?(DashboardManifest)
namespace :admin do
DashboardManifest::DASHBOARDS.each do |dashboard_resource|
resources dashboard_resource
end
root controller: DashboardManifest::ROOT_DASHBOARD, action: :index
end
end

Rails 4 - How to match routes in namespace

Hi i have admin panel controller and have many controller in admin panel.
I want to match routes usually without namespace i've used
match ':controller(/:action(/:id))', :via => [:get, :post]
I want this in namespace controller my current
router.rb
namespace :admin do
get '', to: 'dashboard#index', as: '/'
get 'dashboard/index'
##AUTHENTICATION
get 'login/index'
get 'login/logout'
post 'login/attempt_login'
get 'login/attempt_login'
##PAGES
get 'pages/index'
get 'pages/add_new'
get 'pages/edit'
post 'pages/create'
post 'pages/update'
post 'pages/task'
get 'pages/task'
##USERS
get 'users/index'
get 'users/edit'
get 'users/delete'
get 'users/destroy'
get 'users/update'
get 'users/add_new'
post 'users/create'
post 'users/update'
post 'users/task'
#USER GROUPS
get 'user_group/index'
get 'user_group/add_new'
get 'user_group/edit'
post 'user_group/create'
post 'user_group/update'
post 'user_group/task'
#USER GROUPS
get 'access_sections/index'
get 'access_sections/add_new'
post 'access_sections/create'
post 'access_sections/update'
post 'access_sections/task'
end
Any solution please?
You simply wrap the routes you're declaring in a namespace like so:
namespace :login do
get 'index'
get 'logout'
end
http://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing
For example we have orders which can be cancelled:
Following description in routes.rb
resources :orders do
post :cancel, to: 'orders/cancellations#cancel'
end
Will send request to app/controllers/orders/cancellations_contoller.rb
module Orders
class CancellationsController
def cancel
#order = Order.find(params[:id]).cancel
end
end
end
It's useful to refactor controller resourses with many service methods.
Wish it helps

Use same controller for multiple routes?

Is there a way to write the following routes so you don't have to specify the same controller each time?...
get 'jobs' => 'pages#jobs'
get 'contact' => 'pages#contact'
get 'terms' => 'pages#terms'
get 'privacy' => 'pages#privacy'
Here are couple of alternatives:
Out of the three, the first one i.e., Using scope as "/" would create the exact same routes as the ones created by the routes defined in the question.
1. Using scope as "/"
scope "/", controller: :pages do
get 'jobs'
get 'contact'
get 'terms'
get 'privacy'
end
Creates routes as below:
jobs GET /jobs(.:format) pages#jobs
contact GET /contact(.:format) pages#contact
terms GET /terms(.:format) pages#terms
privacy GET /privacy(.:format) pages#privacy
2. Using Scope as "pages"
scope :pages, controller: :pages do
get 'jobs'
get 'contact'
get 'terms'
get 'privacy'
end
Creates routes as below:
jobs GET /pages/jobs(.:format) pages#jobs
contact GET /pages/contact(.:format) pages#contact
terms GET /pages/terms(.:format) pages#terms
privacy GET /pages/privacy(.:format) pages#privacy
3. Nesting routes
resources :pages do
member do
get 'jobs'
get 'contact'
get 'terms'
get 'privacy'
end
end
Creates routes as below:
jobs_page GET /pages/:id/jobs(.:format) pages#jobs
contact_page GET /pages/:id/contact(.:format) pages#contact
terms_page GET /pages/:id/terms(.:format) pages#terms
privacy_page GET /pages/:id/privacy(.:format) pages#privacy

RSpec test fails with "No route matches" for resources route

Context
I'm running into a very weird test failure that I can't explain based on my code.
When I run the spec test provided below, it will display the following error:
Failures:
1) GroupsController GET 'index' returns http success
Failure/Error: get 'index'
ActionController::UrlGenerationError:
No route matches {:action=>"index", :controller=>"groups"}
# ./spec/controllers/groups_controller_spec.rb:14:in `block (3 levels) in '
Test case
The test case for the controller and routes set in RSpec looks like this:
describe GroupsController do
before :each do
#group = FactoryGirl.create(:group)
#user = FactoryGirl.create(:user)
sign_in #user
end
describe "GET 'index'" do
it "returns http success" do
get 'index'
response.should be_success
end
end
end
Controller under test
I've written a very basic skeleton for my controller based on the test.
Currently it doesn't do a whole lot of stuff.
class GroupsController < ApplicationController
before_filter :authenticate_user!
def index
#groups = current_user.groups
end
end
Routes configured to reach the controller
The routes.rb file looks like this:
NerdCooking::Application.routes.draw do
resources :groups
devise_for :users
root :to => "home#welcome"
end
Routes
groups GET /groups(.:format) groups#index
POST /groups(.:format) groups#create
new_group GET /groups/new(.:format) groups#new
edit_group GET /groups/:id/edit(.:format) groups#edit
group GET /groups/:id(.:format) groups#show
PATCH /groups/:id(.:format) groups#update
PUT /groups/:id(.:format) groups#update
DELETE /groups/:id(.:format) groups#destroy
Question
I have tried changing the route to get "groups" => "groups#index" instead of the resources route and that works, but it's not something I want since I want to use this as a RESTful service as well.
What am I doing wrong here?
Update: Added the routes related to groups.
Okay, apparently my Guard and Spork were acting mean.
Once I restarted Guard/Spork and it all worked as expected. Looking back at the code and configuration there was no reason why stuff was going wrong.
So if anyone else is experiencing this behavior and their config and code check out. Restart!

<Ruby on Rails> Routes

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

Resources