Have I namespaced my controllers properly? Getting a Circular Dependency Error - ruby-on-rails

Hi I'm getting this error
Circular dependency detected while autoloading constant
Subdomain::Settings::ThemesController
in my Rails 4.0 app whenever I try to access the stated controller. In fact I get similar errors for any of the other controllers name-spaced with the themes controller.
I have the following controllers name-spaced under Settings which itself is name-spaced under Subdomain.
Are these controllers defined correctly? Can anyone spot why this circular dependency error is cropping up?
# app/controllers/subdomain/settings/security_controller.rb
module Subdomain
class Settings::SecurityController < BaseController
def edit
...
end
end
end
# app/controllers/subdomain/settings/themes_controller.rb
module Subdomain
class Settings::ThemesController < BaseController
def edit
...
end
end
end
# app/controllers/subdomain/settings/profiles_controller.rb
module Subdomain
class Settings::ProfilesController < BaseController
def edit
...
end
end
end
# app/controllers/subdomain/base_controller.rb
class Subdomain::BaseController < ApplicationController
...
end
And the following routes configuration
MyApp::Application.routes.draw do
constraints(Constraints::SubdomainRequired) do
scope :module => :subdomain do
namespace 'settings' do
root to: 'security#edit'
resource :theme, only: [:create, :edit, :update], :controller => 'themes'
resource :profile, only: [:edit, :update], :controller => 'profiles'
resource :security, only: [:edit, :update], :controller => 'security'
end
end
end
end

The solution was I needed to rewrite each controller like so
module Subdomain
module Settings
class ProfileController
...
instead of
module Subdomain
class Settings::ProfileController

Related

【Rails】How can I write child directory path in route.rb?

The code is below.
#app/controllers/admin/feeds_controller.rb
class Admin::FeedsController < ApplicationController
def api_index
#routes.rb
Rails.application.routes.draw do
scope '/hoge' do
resource :feeds, only: [] do
collection do
get :api_index
end
end
end
end
My wish is that path is hoge/feeds/api_index and can execute api_index action in admin/feeds_controller.
The routes.rb is currently Routing Error.
Because the path is controller/feeds.
How can I call api_index action in controller/admin/feeds?
Thank you.
Error(Add)
I wrote the below
#routes.rb
Rails.application.routes.draw do
scope '/hoge' do
resource :feeds, controller: 'admin/feeds', only: [] do
collection do
get :api_index
end
end
end
end
Then, I got a error
undefined local variable or method `api_index' for Admin::FeedsController:Class
But I definitely wrote def api_index in app/controllers/admin/feeds_controller.rb
How Can I do that?
You can use namespace.
More info in the Rails guide: https://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing
#app/controllers/admin/feeds_controller.rb
class Admin::FeedsController < ApplicationController
def api_index
end
end
#routes.rb
Rails.application.routes.draw do
namespace :admin do
scope '/hoge' do
resource :feeds, only: [] do
collection do
get :api_index
end
end
end
end
end

ActionController::RoutingError: uninitialized constant Api::V1::ApiController

I have Rails 5 API project for controlling user tasks and I have the following error but not always for the same controller and route.
ActionController::RoutingError: uninitialized constant Api::V1::ApiController
I describe you a little bit my project to explain in more detail the error.
App structure
Routes
scope module: 'api' do
namespace :v1 do
# => Login routes
scope module: 'login' do
match 'login', to: 'sessions#login', as: 'login', via: :post
end
# => Team routes
scope module: 'team' do
# => no admin routes
resources :tasks, except: [:index] do
collection do
match ':view', to: 'tasks#index', as: 'tasks', via: [:get, :post]
end
end
end
end
end
API Controller
module Api
class ApiController < ApplicationController
def respond_with_errors(object)
render json: {errors: ErrorSerializer.serialize(object)}, status: :unprocessable_entity
end
end
end
Team Controller
module Api::V1
class Team::TeamController < ApiController
Tasks Controller
module Api::V1
class Team::TasksController < Team::TeamController
Login Controller
module Api::V1
class Login::LoginController < ApiController
Sessions Controller
module Api::V1
class Login::SessionsController < Login::LoginController
When I execute login route and after tasks route, I get the error in last route and all the routes in team module. If I change the project and save it (only one blank space) and then I execute tasks route and after login route, I get the error in last route and all the routes in login module.
It doesn't have any sense...
Rails server in this errors
You should be using the right constant while inheriting - ::Api::ApiController:
module Api::V1
class Team::TeamController < ::Api::ApiController
because otherwise it is searching for Api::V1::ApiController, but should search for Api::ApiController
Right now you have Api::ApiController.
Your app/controllers/api/v1/api_controller.rb is missing V1 in namespace
module Api::V1
class ApiController < ApplicationController
..
end
end
UPDATE
If your ApiController is outside V1 folder then you should do
module Api::V1
class Team::TeamController < ::Api::ApiController

uninitialized constant when calling class method in controller

I have a class called Device. It has a model device.rb
I have set the routing up so that the same controller is called from two different paths. i.e. the paths:
/driver_api/v1/devices
and
/sender_api/v1/devices
both call the following controller:
/user_api/v1/devices
In my routes.rb I have:
namespace :driver_api do
namespace :v1 do
resources :devices, :only => [:create], controller: '/user_api/v1/devices'
end
end
namespace :sender_api do
namespace :v1 do
resources :devices, :only => [:create], controller: '/user_api/v1/devices'
end
end
Now, in my devices controller, I'm trying to call a Device class method. i.e. in my controller:
class UserApi::V1::DevicesController < ApplicationController
Devise.method_name(input)
end
But i get an error:
uninitialized constant UserApi::V1::DevicesController::Device
Why am I getting this error?
Because you wrote Devise and not Device that could be a good reason.
If that is just a typpo from the question, here's another alternative.
Sometimes there's some kind of naming problem when the classes are defined in the way you did (I ignore the reason why that happens)
Try to decompose the class scoping by defining the modules:
module UserApi
module V1
class DevicesController < ApplicationController
# rest
end
end
end

Unable to use inherited_resources' polymorphic belongs_to with namespaced controllers

I am facing an issue with inherited_resources when using a polymorphic nested resource, one of whose parents is a namespaced controller. Here is an abstract example:
# routes.rb
resources :tasks do
resources :comments
end
namespace :admin do
resources :projects do
resources :comments
end
end
# comments_controller.rb
class CommentsController < InheritedResources::Base
belongs_to :projects, :tasks, :polymorphic => true
end
When I access /admin/projects/1/comments, I get this error:
ActionController::RoutingError at /admin/projects/1/comments
uninitialized constant Admin::CommentsController
Now if I define the controller as Admin::CommentsController, I would need to move the file under controllers/admin which will in turn throw up an error for the url /tasks/1/comments
Is there a way I can fix this?
Why not keep CommentsController where it is and make a separate controller for admin in admin/comments_controller.rb? that inherits from it?
class Admin::CommentsController < CommentsController
before_filter :do_some_admin_verification_stuff
# since we're inheriting from CommentsController you'll be using
# CommentsController's actions by default - if you want
# you can override them here with admin-specific stuff
protected
def do_some_admin_verification_stuff
# here you can check that your logged in used is indeed an admin,
# otherwise you can redirect them somewhere safe.
end
end
The short answer to your question is mentioned here in the Rails Guide.
Basically you have to tell the route mapper which controller to use because the default is not there:
#routes.rb
namespace :admin do
resources :projects do
resources :comments, controller: 'comments'
end
end
That will take care of your routing problem, which is actually probably not related to Inherited Resources.
On the other hand, I have been unable to use Inherited Resources as well, in cases of a nested controller inside a namespace. I've moved away from that gem because of this.
I created something that might be interesting to you: a controller concern that will define all of the useful route helpers that inherited resources gives, in a way that accounts for namespaces. It's not smart enough to handle optional or multiple parentage, but it spared me a lot of typing long method names.
class Manage::UsersController < ApplicationController
include RouteHelpers
layout "manage"
before_action :authenticate_admin!
before_action :load_parent
before_action :load_resource, only: [:show, :edit, :update, :destroy]
respond_to :html, :js
create_resource_helpers :manage, ::Account, ::User
def index
#users = parent.users
respond_with [:manage, parent, #users]
end
def show
respond_with resource_params
end
def new
#user = parent.users.build
respond_with resource_params
end
# etc...
end
And then inside my views:
td = link_to 'Show', resource_path(user)
td = link_to 'Edit', edit_resource_path(user)
td = link_to 'Destroy', resource_path(user), data: {:confirm => 'Are you sure?'}, :method => :delete
Hope that helps!

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

Resources