Ruby on Rails add nested controller/resource - ruby-on-rails

I have an application that I want to have a route that is /admin/active_vulnerabilities but when I generate the controller as rails generate controller ActiveVulnerabilities and put the following in my routes.rb
namespace :admin do
resources :users
resources :active_vulnerabilities
# Admin root
root to: 'application#index'
end
But I get the error uninitialized constant Admin::ActiveVulnerabilitiesController so I changed my controller to class Admin::ActiveVulnerabilitiesController < ApplicationController
I then get the error Unable to autoload constant ActiveVulnerabilitiesController, expected /home/luke/projects/vuln_frontend/app/controllers/active_vulnerabilities_controller.rb to define it but the file mentioned is my controller named exactly as that.

Your controller should be put in app/controllers/admin/ because the namespace. Otherwise, you can forget this directory and the namespace and use just scope
scope :admin do
resources :active_vulnerabilities
end
class ActiveVulnerabilitiesController < ApplicationController

Related

how to make dynamic namespace or scopes route in rails

I am trying to make admin route with namespace but it doest trigger to the route
I run rails g controller admin
it created the file app/controllers/admin_controller.rb , app/views/admin/index.html.haml
my namespace look like this
namespace :admin do
controller :admin do
get '/', :index
end
end
it doesn't trigger to localhost:3000/admin it said not found for that route
any idea ??
namespace not only adds a path prefix but it also adds a module nesting to the expected controller. For example:
namespace :blog do
resources :posts
end
Will create the route /blog/posts => Blog::PostsController#index.
In your example Rails expects the controller to be defined as:
# app/controllers/admin/admin_controller.rb
module Admin
class AdminController
# GET /admin
def index
end
end
end
If you just want to add a path prefix or other options to the routes without module nesting use scope instead:
scope :admin, controller: :admin do
get '/', action: :index
end
This will route /admin to AdminController#index
But if this just a one off route you could just write:
get :admin, to: 'admin#index'
Your controller path needs to be in the admin namespace.
So the filename for the admin controller needs to be app/controllers/admin/admin_controller.rb.

Ruby on Rails - Controller Subdirectory

I am somewhat new to RoR,
I want to have a structured directory, because project may become big I don't want to have all controllers directly into controllers directory.
I would want something as
app/
controllers/
application_controller.rb
groupa/
athing_controller.rb
athing2_controller.rb
groupb/
bthing_controller.rb
However when I place in the routes.rb the following:
get 'athing', :to => "groupa/athing#index"
I get the following error on localhost:3000/athing/ :
superclass mismatch for class AthingController
Which is like:
class AthingController < ApplicationController
def index
end
end
Am I missing something?
Can I place subdirectories at all?
Try to use namespace instead:
In your routes:
namespace :groupa do
get 'athing', :to => "athing#index"
end
In your controller:
class Groupa::AthingController < ApplicationController
In browser:
localhost:3000/groupa/athing/
Modularity
When you put your controllers (classes) into a subdirectory, Ruby/Rails expects it to subclass from the parent (module):
#app/controllers/group_a/a_thing_controller.rb
class GroupA::AThingController < ApplicationController
def index
end
end
#config/routes.rb
get :a_thing, to: "group_a/a_thing#index" #-> url.com/a_thing
I've changed your model / dir names to conform to Ruby snake_case convention:
Use snake_case for naming directories, e.g. lib/hello_world/hello_world.rb
Use CamelCase for classes and modules, e.g class GroupA
Rails routing has the namespace directive to help:
#config/routes.rb
namespace :group_a do
resources :a_thing, only: :index #-> url.com/group_a/a_thing
end
... also the module directive:
#config/routes.rb
resources :a_thing, only: :index, module: :group_a #-> url.com/a_thing
scope module: :group_a do
resources :a_thing, only: :index #-> url.com/a_thing
end
The difference is that namespace creates a subdir in your routes, module just sends the path to the subdir-ed controller.
Both of the above require the GroupA:: superclass on your subdirectory controllers.
In config/routes.rb
namespace :namespace_name do
resources : resource_name
end
In app/controllers/
create a module name with your namespace_name, in that place your controllers
In that controller class name should be like
class namespace_name::ExampleController < ApplicationController

Reuse Devise authentication for custom controller

I am trying to create a custom controller in the admin section of Spree and reuse the devise authentication mechanism. How do I go about doing this. I have simply tried to do the following:
module Spree
module Admin
class WorkflowController < Spree::Admin::BaseController
end
end
end
And I created a route like this:
namespace :admin do
resources :workflow, :only => [:index, :show]
end
I am getting the following error:
ActionController::RoutingError (uninitialized constant Admin):
So, any thoughts on how to best create a custom controller or am I just doing something wrong with this?
This is happening because your controller is nested inside the Spree namespace, but your routes are not. If you want to extend Spree's routes, then do this:
Spree::Core::Engine.routes.draw do
namespace :admin do
resources :workflow, :only => [:index, :show]
end
end

Namespaced API with resources specified twice

I'm trying to create a namespaced API in rails and am running into an issue
# Resources
resources :users do
resources :contacts
end
#==========================================>
# API namespacing and routing
#==========================================>
namespace :api do
namespace :v1 do
# =======================>
# Resources -> Users
# Resources -> Contacts
# =======================>
resources :users do
resources :contacts
end
# =======================>
# Resources -> Messages
# Resources -> Transcriptions
# =======================>
resources :messages do
resources :transcriptions
end
end
end
I want to have my html-responding version of the resource outside of the 'api' namespace (i.e. in the regular app/controllers/users_controller.rb area) but my json-responding inside the namespace.
However when I point my url at the "/api/v1/users.json" link it utilizes the controller specified by the OUTSIDE resources app/controllers/users_controller rather than the one I put in app/controllers/api/v1/users_controller.
Am I only allowed one resources reference despite it being namespaced differently?
Why exactly is this happending
Your routing definitions look ok. The first thing I'd check is what routes are generated by your rails router by running:
$ bundle exec rake routes | grep users
You should have your defined users routes mapped to their respective URL structure. If something's amiss then your routes aren't probably defined correctly. Which i doubt in your case.
Another possible issue might be your controller class name in your namespaced users controller. So your users controller under app/controllers/api/v1 should be
class Api::V1::UsersController < ApplicationController
....
end
Look at the Rubygems.org source which has the same kind of structure you're trying to implement.
your controller should look like
module Api::V1
class UserController < ActionController::Base
...
end
end

Routing errors when adding an Admin namespace

I added an Admin namespace to my app so when logging in to the administration area, it would have to be like this: admin/websites and admin/page/8
So this is what I have in my routes.rb
namespace :admin do |admin|
match '/' => 'dashboard#index'
resources :websites
resources :pages
resources :sessions
get 'login' => 'sessions#new', :as => 'login'
get 'logout' => 'sessions#destroy', :as => 'logout'
end
I have admin_controller.rb in app/controllers directory.
class Admin::BaseController < ApplicationController
protect_from_forgery
include UrlHelper
...
I created an admin directory inside app/controllers. So I have this inside app/controllers/admin/websites_controller.rb
class Admin::WebsitesController < ApplicationController
Some other answers suggested class Admin::WebsitesController < Admin::BaseController, but that never worked for me. If I'm wrong please let me know.
So then in my layout file (app/views/layouts/application.html.erb) I have links like this one edit_admin_website_path(#website) that give me routing errors Routing Error No route matches {:action=>"edit", :controller=>"admin/websites"} Whyyyy?! :(
Add a file named application_controller.rb in the admin directory with this content:
class Admin::ApplicationController < ApplicationController
end
Then, for each controller on this directory, extend the Admin::ApplicationController class.
Did you try this?
admin_edit_website_path(#website)
Rails namespaces rely on folder structure for loading the right classes. You should structure it like this:
app/controllers
admin_controller.rb # class AdminController < ApplicationController
app/controllers/admin
websites_controller.rb # class Admin::WebsitesController < AdminController
The AdminController should be defined outside the admin folder. If put it in there you'd have to refer to it as Admin::AdminController which is a little odd. In fact, you could call it AdminNamespaceController to be clear.
You can also use rails generate which will set things up for you in the expected places, although I don't think it creates the namespace base class for you to inherit from.

Resources