Multiple rails resource routes split across scope - ruby-on-rails

Im having some issues trying to split up a controller based on scope.
My code looks like this
scope '/admin' do
resources :pages, only: [:index, :create, :new, :edit, :update, :destroy]
end
resources :pages, only: [:show]
Ideally, Id just like to have the show page not behind the admin scope, however when I call page_path(1), it routes to /admin/pages/1, not /pages/1.
What is the easiest way to work around this issue?
Thanks
Updated with routes
pages_path GET /admin/pages(.:format) pages#index
POST /admin/pages(.:format) pages#create
new_page_path GET /admin/pages/new(.:format) pages#new
edit_page_path GET /admin/pages/:id/edit(.:format) pages#edit
page_path PATCH /admin/pages/:id(.:format) pages#update
PUT /admin/pages/:id(.:format) pages#update
DELETE /admin/pages/:id(.:format) pages#destroy
GET /pages/:id(.:format) pages#show
root_path GET / pages#main
And view:
<% #pages.each do |page| %>
<%= link_to page.title, page_path(page) %>
<% end %>

To influence route helper names, use as-parameter:
scope '/admin', as: 'admin' do
However, it makes sense to place the admin's controller in Admin namespace, so you can do this:
namespace 'admin' do
That will influence path (/admin), route helpers (admin_) and controller namespace (Admin::PagesController). A separate controller allows for easier access and layout control. Also, you can make a separate show for admins, which is nice to have.
Of course, in your forms you'll have to use constructs like form_for [:admin, #page], or form_for #page, url: admin_page_path(#page).

scope '/admin', as: 'admin' do
resources :pages, only: [:index, :create, :new, :edit, :update, :destroy]
end
resources :pages, only: [:show]
Just do the changes as above

scope module: '/admin' do
resources :pages, only: [:index, :create, :new, :edit, :update, :destroy]
end

Related

Rails routing to nested controller

I have one controller for creating category, and I want to have one more nested controller to create language versions of categories. I want to avoid methods like new_language, edit_language, ... and routing on them, I would like to do it the best rails way. But I am new to rails (from Padrino and Sinatra), and I am little bit lost in routing.
I have my controller for categories
module Admin
class CategoriesController < ApplicationController
before_action :authenticate_user!
before_action :find_category, only: [:show, :edit, :update]
layout 'admin'
def index
#categories = Category.all
end
..... all the others CRUD methods ....
end
end
And another controller.
module Admin
class CategoriesLanguageController < ApplicationController
before_action :authenticate_user!
before_action :find_category, only: [:show, :edit, :update]
def new
#category = Category.find(params[:category].to_i)
end
.... all the others CRUD methods ...
end
end
and my routes config.
Rails.application.routes.draw do
devise_for :users
resources :users
namespace :admin do
get '/' => 'dashboard#index'
resources :dashboard, only: [:index]
resources :categories do
collection do
get :publish_category
#get :new_lang
#post :create_lang
#get :edit
#post :update
#get :destroy
end
resources :language, only: [:new, :create, :edit]
end
end
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
root to: "homepage#index"
namespace :api, defaults: { format: 'json' } do
namespace :v1 do
resources :categories, only: [:index]
end
end
end
I would like to have methods new_lang and create_lang under second controller with default names new, create, ....
It generates this
admin GET /admin(.:format) admin/dashboard#index
admin_dashboard_index GET /admin/dashboard(.:format) admin/dashboard#index
publish_category_admin_categories GET /admin/categories/publish_category(.:format) admin/categories#publish_category
admin_category_language_index POST /admin/categories/:category_id/language(.:format) admin/language#create
new_admin_category_language GET /admin/categories/:category_id/language/new(.:format) admin/language#new
edit_admin_category_language GET /admin/categories/:category_id/language/:id/edit(.:format) admin/language#edit
admin_categories GET /admin/categories(.:format) admin/categories#index
POST /admin/categories(.:format) admin/categories#create
new_admin_category GET /admin/categories/new(.:format) admin/categories#new
edit_admin_category GET /admin/categories/:id/edit(.:format) admin/categories#edit
admin_category GET /admin/categories/:id(.:format) admin/categories#show
PATCH /admin/categories/:id(.:format) admin/categories#update
PUT /admin/categories/:id(.:format) admin/categories#update
DELETE /admin/categories/:id(.:format) admin/categories#destroy
but it is not working.
ActionController::UrlGenerationError in Admin::Categories#index
and error is this route:
<td><%= link_to cat.internal_name, edit_admin_category_language_path(id: cat) %></td>
And I don't know how to create these actions in another controller and use url helpers.
Or this is not the best way to do it?
Please any advice?

Delete/Destroy is not working within Rails

I am trying to get a delete button to work using a piece of code I have written within my tags_controller page;
def destroy
#tag = Tag.find(params[:id])
#tag.destroy
redirect_to :back, notice: 'Tag was successfully deleted!'
end
When I run from my local host, it throws an exception as shown below;
Routing Error
No route matches [DELETE] "/admin/tags/37/edit"
Rails.root: /Users/laurenwoodhams/Desktop/PROJECT/RAILS-BLOG/-t
Here is my config routes;
Rails.application.routes.draw do
get '/login' => 'admin/sessions#new'
get '/logout' => 'admin/sessions#destroy'
namespace :admin do
resources :posts
resources :tags, except: [:index]
resources :sessions, only: [:new, :create, :destroy]
resources :administrators, only: [:index, :edit, :update]
end
end
Could you please examine and explain why this may be occurring?
Thank you
DELETE is the HTTP verb (like GET or POST) which means..
To make a link to delete your tag you'll need to do something like this in your view.
<%= link_to "Delete Tag", #tag, method: "delete" %>
Then it should work properly.
P.S.
You can run bin/rake routes to see your routes.

Rails routes: GET method redirecting to show method

I have simple controller and routes file.
In my route and controller i have created a module. I wrote a simple method which is redirecting me show. I am not sure why.
Controller
module Seller
class CampaignsController < Seller::BaseController
before_action :confirm_logged_in
def viewAllCampaigns
#campaigns = Campaign.all
end
def show
end
end
end
Routes file
scope module: 'seller' do
#namespace :power do
resources :dashboard, only: [:index]
resources :sessions, only: [:create, :destroy]
resources :campaigns, only: [:index, :create, :show, :update, :destroy]
get 'viewAllCampaigns' => 'campaigns#viewAllCampaigns'
end
Output
Started GET "/campaigns/viewAllCampaigns" for 127.0.0.1 at 2015-10-12 17:39:43 +0500
Processing by Seller::CampaignsController#show as HTML
Parameters: {"id"=>"viewAllCampaigns"}
Rendered seller/campaigns/show.html.erb (0.1ms)
I am hitting http://localhost:3000/campaigns/viewAllCampaigns in browser.
Ideally your routes should be defined like this.
resources :campaigns, only: [:index, :create, :show, :update, :destroy] do
get 'viewAllCampaigns', on: :collection
end
The first comment on the routes.rb file is The priority is based upon order of creation: first created -> highest priority. This is the reason your route is redirecting to show. Rails is treating this url as campain/:id.
Routes are tested in order, from top to bottom. The show route you've added for the campaigns resource will look for urls matching this pattern:
/campaigns/:id
/campaigns/viewAllCampaigns matches this, so it will do the show action., with params[:id] = "viewAllCampaigns"
Move the special case route up above the resources#campaigns route to fix this, then it will catch the url first.
get 'viewAllCampaigns' => 'campaigns#viewAllCampaigns'
resources :campaigns, only: [:index, :create, :show, :update, :destroy]
It takes the following get request as a show action because show expects campaigns/:id, and it assumes 'viewAllCampaigns' is an id in this instance:
/campaigns/viewAllCampaigns
Your link_to should just be pointing to the following:
'/viewAllCampaigns'
Your route structure isn't really RESTful, but that's a separate topic.

Rails route with id after resource

I have nested routes that I'm having difficulty formatting the way I want to.
My routes.rb has the following
resource :loan_application do
scope ":loan_application_id" do
resources :wizard, only: [:show, :update]
end
end
When I click the link to create a new resource:
<%= link_to business_loan_application_path(#user), method: :post %>
I get sent to a URL that looks like the following
http://localhost:3000/businesses/69/163/loan_application/wizard/eligibility
For some reason the loan_id (163) comes before /loan_application. I would like it to come after /loan_application.
When I rake routes I can see the same problem:
business_loan_application_wizard GET /businesses/:business_id/:loan_application_id/loan_application/wizard/:id(.:format) wizard#show
In my application I made the routes without your scope:
resources :loan_application do
resources :wizard, only: [:show, :update]
end
That leads me into exact the pathes I need

use :only helper in routes

I have a project where user can download files. Now, i want another page for show all users. so, i add a method all_users in my addfiles_controller. I have also a view page all_users.html.erb for that. But The ploblem is with the routes.rb file . Here I want to ensure user can only use :index, :new, :create, :destroy, :all_users paths.
How can i set this :only helper in my routes.rb file, like
resources :addfiles, only: [:index, :new, :create, :destroy, :all_users]
My routes.rb file::
resources :addfiles do
collection do
get 'all_users'
end
end
you shouldn't write all_users to only, because only/except related just to standard actions index, show, new, edit, create, update, destroy which resources define by default
resources :addfiles, only: [:index, :new, :create, :destroy] do
collection do
get 'all_users'
end
end

Resources