rails_admin using separate login pages for admin and user - ruby-on-rails

I'm using rails_admin and devise gem for my rails 5 project. I used CanCanCan for authorization. My problem is i must use separate login pages, one for normal user and one for admin user (now it uses same login page for both).
Does anyone has solution for my problem?
Many thanks!

You find more info in the below link for multiple devise user model:
https://github.com/plataformatec/devise/wiki/How-to-Setup-Multiple-Devise-User-Models

if you want to use two different paths use namespace in your routes.rb
Example:
Rails.application.routes.draw do
root to: 'user#index'
.
.
.
namespace :admin do
root to: 'dashboard#index'
.
.
.
end
end
Don't forget that you will have to namespace all the controllers that you plan to include in the admin section, as well as remember to have those files on the proper folder.
For the above example you should have the admin controller inside the path app/controllers/admin/dashboard_controller.rb and the content of the controller should be similar to the below code
class Admin::DashboardController < ActionController::Base
def index
end
end
if you want to use one single login page for both admins and users, then you'll have to use a common controller to handle both

Related

Variable root in Rails router

I have completely re-written our Single Page Application (SPA) using a different technology, however instead of enforcing new UI to all the users, I would like them to opt to try new UI and similarly switch back to old UI, before enforcing the new UI to every user. The new UI was written keeping this is mind, however in routes.rb I need to define root manually to pick one of them. Ex:
root :to => 'dash#new' # for new UI
or
root :to => 'dash#old' # for old UI
How can this be achieved automatically? Something like:
default root will be 'dash#old'
when user opts to try new UI it should be stored in a new field in User model. (say user.newui = true)
as per the value of user.newui root should be picked. something like:
user.newui ? 'dash#new' : 'dash#old'
However obviously this is not possible. I do not have any user object in routes, most probably my whole solution is pointing south. Can someone please guide me on how to achieve this or whats the best practice?
You'd be best changing the layout in the controller, not middleware...
#config/routes.rb
root "dash#index"
#app/controllers/dash_controller.rb
class DashController < ActionController::Base
before_action :authenticate_user!, :set_layout
def index
current_user.newui?
# define data
else
# old data
end
end
private
def set_layout
layout (current_user.newui? "new" : "old")
end
end
You must remember that your "routes" are like a menu - you pick what you want and browse to it.
What is delivered from those routes is entirely dependent on the controller. In both instances, you're trying to invoke the dash#index action; what you're trying to do is ascertain whether the user has a different preference for how that will be displayed.
Since the middleware is meant to deal with the request (it doesn't know about the User), you'll be best using the controller to make the change.
If you had user object in routes it would be really easy.
Something like devise gem gives that to you out of the box. It allows you also define boolean triggers to user model.
For example I have default false admin tag that actually changes the route. Devise MODEL always gives you routes automatically so if you generate
rails g devise User you will have devise_for :users that you can use in your routes.
devise_for :admin do
root to: "admin#index"
end
root to: "home#index"
Without having user model there you can still define roots in controller but how you you persist them per user?

How to integrate frontend and admin theme together in ruby on rails

I have an application with admin in ruby on rails. Now I need to add front-end in that application. But I don't know how ingrate with both in a single application.
You can create an "admin" area pretty simply once you know how. It all comes down to namespaces, specifically:
#config/routes.rb
namespace :admin do
# Sets up "/admin"
root "application#index"
end
Namespaces are essentially "folders", which also influence the names of your Rails classes (for example, your controller class names).
This means you'll be able to use the following:
#app/controllers/admin/application_controller.rb
class Admin::ApplicationController < ActionController::Base
layout :admin
def index
#do stuff here
end
end
Your models will remain as they are now (no need to make them admin namespaced).
--
The above code should give you the ability to access yoururl.com/admin and have a controller/action to work with. Of course, this negates the fact you're going to have to populate this area with data & controller actions; it all works much similarly to a "standard" rails app once you get it working.
You'll want to check out these helpful resources:
ActiveAdmin gem
RailsAdmin gem
RubyToolbox Admin gems
Railscasts Admin tutorial:

How do I create the users root path route using the Devise gem?

I did a search and found this question on SO, but the accepted answer doesn't seem to be working for me. Basically, the Divise wiki says...
After signing in a user, confirming the account or updating the
password, Devise will look for a scoped root path to redirect. For
instance, for a :user resource, the user_root_path will be used if it
exists, otherwise the default root_path will be used.
With my amateur knowledge of RoR, I have a devise model called Player, and I created the following statement in my routes.rb file...
match 'player_root', to: 'pages#play', as: :player_root, via: :all
...but with that, my app always redirects to my root path, instead of the players root path, which I defined above. What am I doing wrong?
Thanks in advance for your wisdom! Also, I'm using Ruby 2 with Rails 4.
As I understand, you are trying to specify root_path for :players.
If order to do that, you can use following:
authenticated :players do
root to: 'pages#play', as: :authenticated_root
end
This will give you custom root_path for signed in users (players).
Further to Andrey Dieneko, there are two other options you have:
Use unauthenticated_path
Use authenticate_user! in your controller
The bottom line here is that you may be thinking about incorrectly. You may be trying to work out where to take users if authenticated. However, you may be better suited to actually using the authentication methods in the controller to test whether the user is logged in, and if not route them to a login page:
#config/routes.rb
root to: "players#play"
#app/controllers/players_controller.rb
class PlayersController < ApplicationController
before_action :authenticate_user!
end
This will take a user to the "login" path if they are not logged in.
Alternatively, you can use unauthenticated_path like so:
#config/routes.rb
root to: "players#play"
unauthenticated do
root to: "application#landing"
end
--
This method will only be best if you have an app like Facebook (IE it has no "landing page" etc)
I think Andrey's answer is more apt (especially if you have a landing page)

I want to customise devise gem's controllers, is it possible and how to do?

Is there a way to customise the devise controllers , as we can modify the devise views using the "rails g devise:views" generator command. ??
Ok purpose here is to create a statistics table's row for the current user as soon as a user is registered.
I have a user statistics maintained for every user.I just want to trigger the create method of the userstats controller in the background when a user sign-up for my web app.
Is there a way to do this ?
You need to create your own controllers inheriting from Devise's.
class Admins::SessionsController < Devise::SessionsController
end
Then you tell devise to use that controller:
devise_for :admins, :controllers => { :sessions => "admins/sessions" }
And copy your views from devise/sessions, to admin/sessions.
You can read it here: https://github.com/plataformatec/devise
Or simply do this:
rails generate devise:controllers Admin
or copy the devise controllers from where they are now to your app. This is what I did with RVM:
cp -R ~/.rvm/gems/ruby-1.9.3-p194#my_gemset/gems/devise-2.1.0/app/controllers/* my_rails_app/app/controllers/

Rails Beginner - which controller to put functions in?

New to rails and I have what I think is a basic question.
In an admin view, there will be varying operations done on different data models. I have a layout "admin" which has various tabs the user clicks to load forms to edit various sets of data.
Should the controller for everything that can be edited in this view be in admin_controller (ie, have an edit_product, edit_user...), or is it better to leave the functions in the controller for each model (say users_controller, products_controller, orders_controller) and specify in the controllers to use the admin layout?
I'm working through my first rails project, and it seems either way works, but obviously I want to follow the right convention going forward so any hint, or a link to an article about this topic would be appreciated.
Thanks,
The proper Rails way to do this would be to use Namespaces. I'll give an example below:
Inside your controllers folder, you add a new folder called admin, and for each model you want to edit as an admin, add a controller. Here is a basic blog application:
app/
models/
views/
controllers/
users_controller.rb
posts_controller.rb
comments_controller.rb
admin/
users_controller.rb
posts_controller.rb
comments_controller.rb
Notice the new folder layer within our controller folder. Inside each of these files, you'll change the definition of the class, from:
class UsersController < ApplicationController
to:
class Admin::UsersController < ApplicationController
Now, within your congif/routes.rb file, you can namespace your routes to the admin namespace, like so:
map.namespace :admin do |admin|
admin.resources :users
admin.resources :posts
admin.resources :comments
end
Now, you can go to a URL such as: http://localhost:3000/admin/users/1 and you'll have access to whatever you specified in the admin version of your users controller.
You can read more in this StackOverflow question, and read up on the Routes here.
Good answer from Mike. I would add that you can see the "standard" rails code for this by using a generator:
# in rails 2.3
$ script/generate controller admin/users
# in rails 3.0
$ rails generate controller admin/users
The slash in the controller name defines a namespace. Also see rake routes for the named paths that it creates, e.g. admin_users_path etc.

Resources