Best practices: Namespace or resources for admin interface dashboard Mongoid - ruby-on-rails

I will build a admin interface for my aplication back-end.
I am using Mongoid, and I want to know What is the best for make my own Backend Interface.
I can not use active_admin because it does not works for mongoid odm.
I have in my routes:
devise_for :admins
namespace :admin do
resources :categories
resources: users
resources: posts
.
.
.
end
I have in my controller categories for example:
class Admin::CategoriesController < ApplicationController
before_filter :authenticate_admin! # assuming you're using devise
def index
#etc.
end
end
Its better use namespace or resources?
which is best practice to create an interface for the administrator with others odms or database without using gems as active_admin, rails_admin, typus...etc

Use namespace but remember this:
Do not use the same word as namespace and resources
namespace :admin
resources :categories
end
is fine as long as you don't have a model resource named admin or admins. Otherwise, you will have a hard time debugging or constructing the proper routes( admin_foo_bar_path, can refer either admin namespace or admin resource, which confuses both you and rails ).

Related

Resource in and outside namespace

I have the following routes.rb:
resources :users
namespace :vmt do
resources :dashboards do
resources :users
resources :evaluation_units
resources :orga_units
end
end
I want to set the user in an overall context and nested in a single dashboard context within a namespace. The users-Controller is not in the namespace. So when I open the path /vmt/dashboards/1/users in browser, I get the following Routing Error
uninitialized constant Vmt::UsersController
So how can I specify, that in this resource
namespace :vmt do
resources :dashboards do
resources :users
that the controller is not in a namespace? I tried to set the controller explecitly with
resources :users, controller: 'user'
but it's still in the vmt namespace.
Using scopes will point rails to the proper url, but does not seem to provide the same useful route url helpers. We can, however, use / to point to the 'top level' controller.
Say you have two routes we want to display the users on:
/users and /admin/users
resources: users
namespace :admin do
resources :users, controller: '/users' # 'users' alone would look for a '/admin/users_controller'
end
With this, we can continue to use the url helper admin_users_path
(Note: Not a rails expert, there may be a way to create url helpers for scopes, or some other solution. Above tested on rails 5.2)
My original answer didn't work in the end, once you're inside a namespaced scope within a route you can't get out anymore.
The easiest way to re-use your logic is to create a Vmt::UsersController like so:
class Vmt::UsersController < ::UsersController
end
You can specify a different module with the module key.
For example:
resources :users, module: nil
Edit: I'm not 100% sure if this will work inside a namespace. If not, you can change it to a scope, and add the module explicitly to the other resources.

How to have one resource in routes for namespace and root path altogether - Rails 4

I am making a custom admin panel in a namespace "admin".
I have resources "courses" within that namespace.
But I would also like a route to "courses" that is not in that namespace:
eg: BOTH localhost:3000/admin/courses AND localhost:3000/courses
It's OK if this requires different controllers.
My concern is that its not really DRY if i have both resources for the same route.
namespace admin do
resources :courses
end
and just
resources :courses
Is there a way to have one resource be shared between namespace and without namespace, or is the example above the way to go?
Oh wait ! There's also the possibility to use concerns !
concern :shared_actions do
resources :courses
resources :something_else
end
namespace :admin do
concerns :shared_actions
end
concerns :shared_actions # Will add it to the root namespace ^^
EDIT : apparently this is what this guy also tried to do :D
I'm not really sure I understand what you mean, but
namespace :something is actually a shorthand for scope :something, module: :something, as: :something
scope :something will add /something/ as a URL prefix
scope module: :something will add /something as a controller prefix (controllers will be fetched under controlelrs/something/the_controller.rb
scope as: :something will add the something as a prefix for path helpers
Now it's totally fine to have both in your routes
resources :courses
# Will generate "/courses/", "/courses/new", "/courses/1/edit", ...
# And will point to `controllers/courses_controller.rb`
namespace :admin do
resources :courses
end
# Will generate "/admin/courses/", "/admin/courses/new", "/admin/courses/1/edit", ...
# And will point to `controllers/admin/courses_controller.rb`
Does this answer your question ?

Rails - Namespaced routes in conjunction with a module

I am trying to build some admin forms for a CMS I've created. I have recently moved the 'core' CMS models into their own modules. I am running into problems with my named routes.
I will use the Page model as an example.
Page.rb lives in /app/models/cms/ :
module Cms
Class Page < ActiveRecord::Base
...page model code
end
end
In config/routes.rb I have
namespace :admin do
resources :things
resources :otherthings
scope :cms do
resources :pages
end
...more routes
end
In my admin views, I am using simple form. When I try to use named routes, I start running into problems:
=simple_form_for [:admin, #page] do |f|
nets me: undefined method `admin_cms_page_path'
I am unsure of how to route pages in the admin namespace such that I will get usable named routes. Should it be in a scope? This seems logical to me, but rails seems to be choking on it.
Rails: 4.2.0
Ruby 2.2.0
Turns out I was looking for as:
namespace :admin do
scope :cms do
resources: pages, as: "cms_pages"
However, if anyone has a better suggestion, they are welcome...

Namespaced API with resources specified twice

I'm trying to create a namespaced API in rails and am running into an issue
# Resources
resources :users do
resources :contacts
end
#==========================================>
# API namespacing and routing
#==========================================>
namespace :api do
namespace :v1 do
# =======================>
# Resources -> Users
# Resources -> Contacts
# =======================>
resources :users do
resources :contacts
end
# =======================>
# Resources -> Messages
# Resources -> Transcriptions
# =======================>
resources :messages do
resources :transcriptions
end
end
end
I want to have my html-responding version of the resource outside of the 'api' namespace (i.e. in the regular app/controllers/users_controller.rb area) but my json-responding inside the namespace.
However when I point my url at the "/api/v1/users.json" link it utilizes the controller specified by the OUTSIDE resources app/controllers/users_controller rather than the one I put in app/controllers/api/v1/users_controller.
Am I only allowed one resources reference despite it being namespaced differently?
Why exactly is this happending
Your routing definitions look ok. The first thing I'd check is what routes are generated by your rails router by running:
$ bundle exec rake routes | grep users
You should have your defined users routes mapped to their respective URL structure. If something's amiss then your routes aren't probably defined correctly. Which i doubt in your case.
Another possible issue might be your controller class name in your namespaced users controller. So your users controller under app/controllers/api/v1 should be
class Api::V1::UsersController < ApplicationController
....
end
Look at the Rubygems.org source which has the same kind of structure you're trying to implement.
your controller should look like
module Api::V1
class UserController < ActionController::Base
...
end
end

Namespace, static pages, and inherited controllers, what files in what folders?

I'm building an admin control panel (attempting to ;) ).
I have been looking at Backend administration in Ruby on Rails and as suggested I am trying to make Admin::AdminController that checks for admin and sets the layout etc.
But I'm also trying to set a route in it that routes /admin to /admin/dash
From my understanding of reading http://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing , specifically section 2.6,
Admin::AdminController
tells rails that Admin is the name space, AdminController is the controller which is a subclass (extension?, implementation of the interface?) of ApplicationController. Which would imply the controller should live in app/controllers/admin/ and be called admin_controller.rb.
But what I want is
AdminController
I get errors like:
uninitialized constant Admin::Controller
My code for the route:
match :admin, :to => 'admin/admin#dash'
namespace :admin do
# Directs to /admin/resources/*
match '/dash', to: '#dash'
resources :users, :pictures
end
I have put the controller in app/controllers/admin, app/controllers and the combinations with
class Admin::AdminController < ApplicationController
before_filter :admin_user
# / ** STATIC ADMIN PAGES ** /
def dash
end
end
or class AdminController < ApplicationController.
Edit: Maybe it's my understanding of routing.
Example:
namespace :admin do
get "/dash"
vs.
namespace :admin do
match "/dash" to "admin#dash"
vs.
namespace...
match "/dash" to "#dash"
The first one makes it so i can display a dash via the controller, i.e. admin/dash would be controlled by
AdminController < ApplicationControler
def dash
end
Does the second one route admin/admin/dash to admin/dash?
TL/DR:
I think my confusion comes from syntax or my poor understanding of RESTful practices or maybe even class / object inheritance in ruby.
Thanks for helping this n00b out. :)
Side question: can I change my code to be minimized until someone opens it like a spoiler so it doesn't crowd things up if I find more information and add it?
I think your initial approach was correct, but you need to change it a little.
1) insert the /admin => /admin/dash inside the namespace (imho, its better to redirect it)
match 'admin' => redirect('admin/dash')
or
namespace :admin do
match '/', to: 'admin#dash'
end
2) You can't match '/dash' to '#dash' since you're not inside a resource block, you're inside a namespace block, so it doesnt' have implied controller.
namespace :admin do
match 'dash', to: 'admin#dash'
# This will go to Admin::AdminController#dash
# (first Admin because of the namespace,
# and the second because of the controller name)
end
hope it works :D
What you want is "scope" in routing.
scope "/admin" do
resources :articles
end
Which will route /admin/articles to ArticlesController (without Admin:: prefix)
Documentation covers almost every possible case.
http://edgeguides.rubyonrails.org/routing.html

Resources