How to integrate frontend and admin theme together in ruby on rails - 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:

Related

rails_admin using separate login pages for admin and user

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

Alias route's name

I need to have one path accessible through multiple names. In my routes.rb I did
get '/route' => 'controller#edit', :as => 'name_a'
get '/route' => 'controller#edit', :as => 'name_b'
This works nicely but loads the routes table for nothing. From my understanding of the documentation, :as defines a helper method when called.
So I went to my ApplicationController and added
alias_method :name_b, :name_a
and I removed the second line from routes.rb
but that fails with Uncaught exception: undefined method name_a for class ApplicationController
is there any proper way of having two names for a single path?
=================EDIT====================
Elaboration:
I use Devise gem to manage session, registration, locking, etc. of 2 kinds of users, let's call them Admin and Guest. The gem is very well put but it asks for definitive route names to behave properly.
In my case, as far as devise is concerned, only the registration process is different so I'm trying to build a structure which looks as follow:
app
controllers
users
admin
registration_controller.rb
guest
registration_controller.rb
session_controller.rb
password_controller.rb
registration_controller.rb
the Admin and Guest controllers inherit from the above registration_controller which inherit's from Devise.
Now, to work properly, Devise needs for instance the names guest_user_password and admin_user_password to create or delete password retrievals. In my case, both are under the same path so I want both names to redirect to the same 'users/password' controller.
More important, and that's why I really wanted the alaising. Is that my views should not care whether it is dealing with Admin and Guest routes when redirecting to password retrieval controller. Both are users so I want to use user_password for both.
Hence my question. :)
Also note that as I wrote it, things works. I'm just trying to get the 'most elegant way' of writing it.
How about putting the alias in your ApplicationController?
class ApplicationController < ActionController::Base
alias_method :route_new, :route_old
helper_method :route_new
Remember that it's new name first, then old name.
The helper_method call is in order to use these in your views and not just controllers.
If you like, you can then place this in an included module called something like RouteAliases
You can add something like this to your routes.rb:
Rails.application.routes.draw do
...
Rails.application.routes.named_routes.tap do |named_routes|
named_routes['new_name'] = named_routes['real_name']
end
end
This will create new_name_path and new_name_url helpers. I have tested this with Rails 5.0.6.

How to use Devise/CanCan to protect mounted Engine resources?

I have an engine mounted to my main app and I want to protect certain controllers and actions within that engine.
The engine is mounted with:
mount SomeEngine::Engine => '/some_engine'
Devise/CanCan is working with the rest of the main app's controllers and actions, but letting things run without anything else produces this error:
This action failed the check_authorization because it does not authorize_resource. Add skip_authorization_check to bypass this check.
So I open up the engine controllers from the main app using the decorator approach and add:
load_and_authorize_resource
Then I get this error:
No route matches {:action=>"new", :controller=>"devise/sessions"}
I can get things working using the following, but it's clunky when I try to implement roles:
authenticate :administrator do
mount SomeEngine::Engine => '/some_engine'
end
By clunky I mean I'll have to reproduce the above block of code in the routes.rb file for each role that has access to the engine...unless there's another way to use authenticate with roles that I don't know about???
I'd like to use the normal Devise/CanCan authorization/authentication approach in the controller if possible. But I think "no route match" error occurs because the engine does not know how to get to the main app's Devise controllers. But how do I get around this from the main app?
To throw one more issue into the mix...there is one specific controller/action in the engine that I do want to make public to all users. Thus far I've just added this before the authenticate block of code in the routes.rb file.
match '/some_engine' => 'some_engine/some_controller#public_action'
It works...but this line with the block in the routes.rb seems like I'm doing something wrong. And it doesn't allow me to implement roles nicely.
You can inherit application controller for use devise and cancan from main app.
module SomeEngine
class ApplicationController < ::ApplicationController
before_filter :merge_abilities
private
def merge_abilities
current_ability.merge(SomeEngine::Ability.new(current_user))
end
end
end
After this you can create abilities for engine by create own.
module SomeEngine
class Ability
include ::CanCan::Ability
def initialize(user)
return if user.nil?
can :manage, SomeModel
end
end
end
SomeModel (SomeEngine::SomeModel) is model at SomeEngine engine.
At resource controllers you must specify class name of resource.
load_and_authorize_resource class: SomeEngine::SomeModel
And do not forgot change route helper to main_app.MAIN_APP_PATHS at main application layout if you want to use it at engine.

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.

Backend administration in Ruby on Rails

I'd like to build a real quick and dirty administrative backend for a Ruby on Rails application I have been attached to at the last minute. I've looked at activescaffold and streamlined and think they are both very attractive and they should be simple to get running, but I don't quite understand how to set up either one as a backend administration page. They seem designed to work like standard Ruby on Rails generators/scaffolds for creating visible front ends with model-view-controller-table name correspondence.
How do you create a admin_players interface when players is already in use and you want to avoid, as much as possible, affecting any of its related files?
The show, edit and index of the original resource are not usuable for the administrator.
I think namespaces is the solution to the problem you have here:
map.namespace :admin do |admin|
admin.resources :customers
end
Which will create routes admin_customers, new_admin_customers, etc.
Then inside the app/controller directory you can have an admin directory. Inside your admin directory, create an admin controller:
./script/generate rspec_controller admin/admin
class Admin::AdminController < ApplicationController
layout "admin"
before_filter :login_required
end
Then create an admin customers controller:
./script/generate rspec_controller admin/customers
And make this inhert from your ApplicationController:
class Admin::CustomersController < Admin::AdminController
This will look for views in app/views/admin/customers
and will expect a layout in app/views/layouts/admin.html.erb.
You can then use whichever plugin or code you like to actually do your administration, streamline, ActiveScaffold, whatever personally I like to use resourcecs_controller, as it saves you a lot of time if you use a REST style architecture, and forcing yourself down that route can save a lot of time elsewhere. Though if you inherited the application that's a moot point by now.
Do check out active_admin at https://github.com/gregbell/active_admin.
I have used Streamlined pretty extensively.
To get Streamline working you create your own controllers - so you can actually run it completely apart from the rest of your application, and you can even run it in a separate 'admin' folder and namespace that can be secured with .
Here is the Customers controller from a recent app:
class CustomersController < ApplicationController
layout 'streamlined'
acts_as_streamlined
Streamlined.ui_for(Customer) do
exporters :csv
new_submit_button :ajax => false
default_order_options :order => "created_at desc"
list_columns :name, :email, :mobile, :comments, :action_required_yes_no
end
end
Use https://github.com/sferik/rails_admin.

Resources