Rails full-fledged admin control panel - ruby-on-rails

I'm wondering what's Rails approach when it comes to creating a full-fledged admin control panel. And by full-fledged I mean a real control panel that could be used on a professional level, not personal/internal scaffolding.
I don't believe its stored in the same folder as the user interface as it's shown in the blog screencast or in Getting Started with Rails tutorial!
I'm certain the same model will be used everywhere but what about the views?
Please explain in details. I don't want to use my PHP mentality when starting my first real project in Rails.
Thanks.

here you can find a list of rails plugins/engines to manage admin interfaces:
http://ruby-toolbox.com/categories/rails_admin_interfaces.html
I've used a bunch of them (typus and rails_admin), not bad at all.
also check the recent released ActiveAdmin
http://activeadmin.info/

As hinted at by the previous answers namespacing is useful to keep admin functionality neatly separated from other user functionality, for example:
# In your routes
namespace :admin do
resources :stories
resources :editors
#etc.
end
Then you'd put all your admin controllers in an 'admin' subfolder and always require an admin to access them:
# app > controllers > admin > stories_controller.rb
class Admin::StoriesController < ApplicationController
before_filter :authenticate_admin! # assuming you're using devise
def index
#etc.
end
end
The advantage of this is you only have to check for admin in one place (the before_filter of an admin controller) rather than having to put conditionals everywhere in your normal controllers / views.

It depends on the nature of your application, but there's nothing wrong with having the admin functions in the same view as the user; Just test your permission role before showing certain part of the display.
If you really need an admin only interface, you could namespace some controllers and views. There are other posts that deal with how to do this, such as The Rails Way - Namespaces

Related

Devise model without devise routes

I have two Rails projects sharing some files, one is the actual app and the other one is the admin tool for the app. They share migrations, models, some config, etc. The admin tools is ActiveAdmin 1.0.0-pre2 and Rails' version is 4.2.
I have two Devise models, User and AdminUser. In the app project, there's no route for admin_user and I want to keep it that way, but if I don't add:
devise_for :admin_users
to the routes file, I get all sort of strange errors, such as:
ActionView::Template::Error: undefined method `admin_user_confirmation_url' for #<ActionDispatch::Routing::RoutesProxy:0x007fc613ecde08>
or:
Could not find a valid mapping for <AdminUser ...>
whenever I'm creating an AdminUser in the app project (sample data generation).
How can I achieve having a devise model, without the routes?
If you just want a model for Admin, to Have some methods and data, remove all devise entries (database_authenticatable, etc.) from the admin user migration and model, and use it as a plain activerecord model. If you need any specific devise modules, you can add them one by one. But the devise modules you add will likely require the controller and routes to be present.
What I would do if I were you:
Merge the two applications into one.
Create a new field in the User migration and call it "role", with default value "user"
Use Cancan or something similar to set different permissions depending on the role ("user" or "admin"). For example users with role "user" cannot view any of the admin pages. And this way whoever is admin in your website, doesn't need to have a separate model/account for loging in to active admin.
Don't get me wrong, I just can't think of a good reason to keep the two sides as different projects. It will only add problems to your logic and implementation and you will have to constantly be passing information around. I actually use ActiveAdmin in the way I explained above and everything works like a charm.

Super-simple updates app in Rails

I have to cook up a super-simple Rails app with the following functionality:
Only one model: Update. Updates are simply news that my client will be publishing on the site, i.e. basically mini blog posts. An update has three fields: headline, text (both mandatory) and image.
The client will need to log in to create, update, & delete updates. No roles and authorization levels are necessary — just a single login / password combination for the above tasks.
It's desirable to have a very basic WYSIWYG (for inserting links, etc) in the UI for creating & editing updates.
It's been a while I've done something similar, so the question is: is it advisable just to roll everything from scratch or are there gems I should consider?
(I'll be probably using AWS and CarrierWave for images).
Much thanks!
Simplest way to achieve this (and yes, it will be relatively simple) will be to use the Devise gem with InheritedResources. Here's how:
Flow
Firstly, you'll want to ensure you're able to give the use a place to compose & submit the updates. To do this, you'll want to create a simple backend (admin) system, to give you a separate space to update your backend:
#config/routes.rb
namespace :admin do
resources :updates, path: "", except: :show #-> domain.com/admin/
end
root: "updates#index"
resources :updates, path: "", only: [:show, :index] #-> domain.com/:id
The importance of this type of system is relevant.
The issue I think you're alluding to is the way in which you won't be able to either create or access the various mini-updates from a "protected" area. Using the method I'm detailing will only only provide this area, but also give you the ability to store the data correctly.
--
Controller
To get this to work, you'll need two controllers:
#app/controllers/updates_controller.rb #-> for general users
class UpdatesController < InheritedResources::Base
#InheritedResources will create relevant CRUD resources
end
#app/controllers/admin/updates_controller.rb #-> for admin
class Admin::UpdatesController < InheritedResources::Base
before_action :authenticate_user! #-> for Devise
#InheritedResources creates relevant responses
end
The above two controllers are really the core of what you need. They provide the CRUD functionality for both the admin and `general areas of your app - giving you the ability to provide the users with the ability to upload as they require.
The biggest thing you need to consider is the authentication. This is handled with Devise (which I'll explain below). The thing you need to consider is the authenticate_user! call - this is what determines whether the user is able to invoke the methods, depending on whether they are logged in (maintain an active session) or not
--
Devise (authentication)
The Devise gem will be what you need to get the authentication of your app sorted. This is what you're asking about -- and simply, it's a job for Devise.
There is a great tutorial on how to handle this here:
The bottom line with Devise is that you need 3 things to get it working:
A User model
A users table
The Devise columns & system installed
Without over-burdening you, I'd just recommend using the controllers I put up above (with the corresponding views), the routes, and then Devise
It's not a gem, but you could look at Rails Composer: https://github.com/RailsApps/rails-composer - they have templates for generating apps that meet your needs. It lets you set options to help you customise them further.

Path security and before_filters rails

I am currently creating an app where users can create and apply for jobs. However as I am fairly new to rails I am facing a fairly significant security feature in that if any user knows the correct path, for example:
localhost:3000/users/user_id/apps
Then they can see any application made by any user for any job!
I am fairly sure that I need to use a before_filter to check that the current_user.id matches either the user_id found in my jobs table for each job or matches the user_id found in my applications table.
I am really not sure how to structure this though or where to apply the filter - for example is it better to create the filter in the application controller and then apply a skip_before_filter instance where needed.
Any help people can offer on contructing this code and where to place it would be much appreciated! Thanks :)
Before you start looking at authorization solutions such as cancan, a simple approach is to avoid doing
App.find params[:id]
Since an app is associated to a user and you've got current_user setup you can do
app = current_user.apps.find params[:id]
Which will only find apps associated with the user, no matter what the parameters to find.
Where cancan really comes into its own is when you need a more complicated who can do what system. For example a user might be able to edit any job they've created but view (and not edit) another set of jobs.
For example
can :manage, Project, :user.id => user.id
can :read, Project, :department => user.department
This would allow users full access to any of their projects and read access to projects in their department
Another thing about cancan is that rather than having before_filters or macros scattered around your controllers you declare the rules in one place, so it's usually easier to see what's going on. There's loads more info on the cancan wiki an a railscast too.
You are right a before_filter might be an sollution but its not the state of the art solution. Theres a railscast for that,...
http://railscasts.com/episodes/192-authorization-with-cancan/
When your using cancan but not devise you need to create the current_user helper that should return the User object of the currently logged in user...

Rails best practice for backend admin system setup?

We have a site where we have a backend management interface, and a frontend that displays our information. We are using Devise to secure authentication.
The backend should allow for normal CRUD type editing of our model objects. The views and layout are also completely different than the frontend. What is the best practice for implementing this in Rails 3?
Our two approaches are:
An admin view folder houses all view specific code, as well as an admin folder in the controllers folder houses all controllers that control admin specific access.
A conditional logic system with one set of views and controllers, with if statements checking whether the user is in admin mode or not.
Which is more recommended, or if there is another approach we have missed, please let me know.
The first solution is better, however for these cases was created the namespaces and the best practice is to go with namespaces when you need relevant differentiation between user site and administration area. Read more about it here
Your directory structure should look like this:
controllers/
|--admin/
|--posts_controller.rb
In your routes you put everything you need into admin namespace:
namespace :admin do
resources :posts, :comments
end
Your controllers should have an admin folder, and a controller in the admin area will look like:
class Admin::PostsController < ApplicationController
end
You also should have an admin folder in your views, where you put the respective views:
views/
|--admin/
|--posts/
|--index.html.erb
|--...
You can also namespace your models, but it depends on your needs, it is good when you need to have different models with the same name. For example if you need different table for the admin users, and different table for normal users. Personally I wouldn't use model namespacing, just in very justified cases.
The second option I think can cause a lot of headache, you gonna be lost in the if statements, I don't recommend that at all.

Pros & Cons of separating the controllers using subfolders on an ruby on rails app based?

Need some help gathering thoughts on this issue.
Our team is moving ahead with the idea that separating the authenticated and public sections of our app in two separate folders will allow us to be more organized and secured.
I have seen this approach for Admin apps within the site but never for authentication.
We are currently using Authlogic.
What would be the disadvantage of this?
Thanks for your help.
i don't think you will find any disadvantages with moving the controllers into subfolders. we actually do this by "namespace"/process. for example, we have an "order" subfolder containing all controllers related to an order.
i think having a clean folder structure inside your rails app directory increases maintainability.
We namespace controllers in this manner - typically we'll have a /admin and a /my folder for the admin and user account controllers respectively.
Additionally, in the subfolder we will have an application_controller.rb that each of the controllers in that subfolder derives from. So in the admin subfolder, we have an application_controller.rb that looks like this:
class Admin::AdminController < ApplicationController
permit "admin"
layout 'admin'
end
We'll then inherit from this controller in our admin controllers. The example uses the rails-authorization-plugin for roles.

Resources