I have admin controller and I want to set layout for '/admin' path.
I try like:
scope '/admin' do
layout 'admin' # did't work
get '/' => 'admin#index', as: 'admin'
resources :posts, as: 'admin_posts'
end
I can set layout in AdminController like:
class AdminController < ApplicationController
layout 'admin'
end
but is a bad way because rationally use some layout for all controllers who call from '/admin' path
How I can do it?
You cant set layout directly in your routes.rb
I think what you do is the right way
class AdminController < ApplicationController
layout 'admin'
end
Now you will use AdminController to generate other controllers in admin scope
class UsersController < AdminController
end
or if in a namespace
class Admin::UsersController < AdminController
end
Thats what i do, if i did understand your question.
Related
I have created a namespaced api in my rails 5 project. I have the following in my config/routes.rb
Rails.application.routes.draw do
post 'api_user_token' => 'api_user_token#create'
namespace :api do
namespace :v1 do
resources :events
end
end
end
Events Controller
module Api::V1
class EventsController < ApiController
#Code here
end
end
API Controller
module Api::V1
class ApiController < ApplicationController
before_action :authenticate_api_user
respond_to :json
def register
end
end
end
I want the '/api/v1/register' route to go to the register method defined in my api controller. How can i define the route in this case ?
Thanks
namespace :api do
namespace :v1 do
resources :events
post :register, to: 'apis#register'
end
end
This will generate
api_v1_register POST /api/v1/register(.:format) api/v1/apis#register
What I need is that when a user goes to '/admin', it redirects to '/admins/sign_in' for the user to sign in.
This is what I did:
# routes.rb
devise_for :admins
namespace :admin do
root to: 'users#index'
end
.
# controllers/admin/base_controller.rb
class Admin::BaseController < ApplicationController
before_action :authenticate_user!
layout 'admin'
end
.
# controllers/admin/users_controller.rb
class Admin::UsersController < Admin::BaseController
def index
end
end
The problem is that when I go to '/admin' it returns me an error:
NoMethodError in Admin::UsersController#index ..
undefined method `authenticate_user!' for Admin::UsersController
How can I make it work?
We have nearly the same setup as you, and it works perfectly:
I think the problem is that you're using devise_for :admins, and yet calling authenticate_user!; it should be authenticate_admin! (as per the Devise docs):
class Admin::BaseController < ApplicationController
before_action :authenticate_admin!
end
Given the following routes:
resource :public_profile do
resources :posts
end
resource :private_profile do
resources :posts
end
How can I, in the PostsController, determine which singular resource I am nested within?
One way you could do this is by creating 2 more controllers that extend some main PostsController, and use
resource :public_profile do
resources :posts, controller: "PublicPostsController"
end
resource :private_profile do
resources :posts, controller: "PrivatePostsController"
end
You could even do this in a variety of ways. For example, maybe it makes sense to have
class ProfileController < ApplicationController; end
class PostsController < ApplicationController; end
class Private::ProfileController < ProfileController; end
class Private::PostsController < PostsController; end
class Public::ProfileController < ProfileController; end
class Public::PostsController < PostsController; end
with routing
resource :public_profile, controller: "Public::ProfileController" do
resources :posts, controller: "Public::PostsController"
end
resource :private_profile, controller: "Private::ProfileController" do
resources :posts, controller: "Private::PostsController"
end
Regardless of how you set this up, you can easily 'know' what resource you're nested within because you'll actually be running within a separate controller specific to that nesting and can thus have a perfect place for logic specific to that nesting. For general logic, you'd put that into the parent PostsController.
Another way you could do this is by adding a before_filter to PostsController like
before_filter :check_nesting
private
def check_nesting
#is_public_profile = params.include?(:public)
end
and have routing like
resource :public_profile, public: true do
resources :posts, controller: "PublicPostsController"
end
resource :private_profile, private: true do
resources :posts, controller: "PrivatePostsController"
end
I don't care for this approach though.
You can route them to different controllers ( by specifying it in the routes) , that are extended from the same "base" controller PostsController. In the extended controllers you
identify them:
EX:
resource :public_profile do
resources :posts, :controller => "public_profile_posts_controller"
end
resource :private_profile do
resources :posts, :controller => "private_profile_posts_controller"
end
and the Controllers
class PublicProfilePostsController < PostsController
before_filter :identify_controller
def identify_controller
#nested_resource_of = :public_profile
end
end
class PrivateProfilePostsController < PostsController
before_filter :identify_controller
def identify_controller
#nested_resource_of = :private_profile
end
end
and then you have access to the variable
#nested_resource_of
in the PostsController actions
I am currently using Cancan and my users basically have different 'roles'.
I only want people to be able to register 'consumer' user accounts and for business accounts admins will be doing that.
So now, I have this in my ability.rb
def initialize(user)
user ||= User.new
...
# You can only create accounts that are consumers
can :create, User do |user|
user.role? :consumer
end
and in my controller/users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
load_and_authorize_resource
end
and config/routes.rb:
devise_for :users, :controllers => {
:registrations => "users/registrations"
}
Now when I visit the registration page, I am seeing "uninitialized constant Registration" with NO stack trace whatsoever. Any ideas?
My code example
class ApplicationController < ActionController::Base
authorize_resource
check_authorization
end
class Users::SessionsController < Devise::SessionsController
skip_authorize_resource
skip_authorization_check
end
For load_and_authorize_resource you will need skip_load_and_authorize_resource. And all this code is applicable for custom devise's controller. Just create one.
The issue is with the routes, please follow the following steps
1. $ rake routes, you will see the list of routes
2. In your config/routes.rb write the route you need, In my case the route to create a new user was,
devise_for :users, :controllers => { :new_user_registration => "users/registrations#new" }
3. restart rails server
In routes.rb:
namespace :admin do
root :controller => "base", :action => "index"
resources :products
end
The products controller inherits from the base controller:
class Admin::BaseController < ApplicationController
#layout 'admin'
def index
end
end
class Admin::ProductsController < Admin::BaseController
def index
end
end
Without "layout 'admin'", both index views render normally.
With "layout 'admin'", the admin layout is rendered, but the views are not rendered, despite WEBricks message:
Rendered admin/products/index.html.erb within layouts/admin
<%= yield %> might help there, mate