Rails - Namespaced routes in conjunction with a module - ruby-on-rails

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...

Related

How to set the correct resource name for devise?

I have a problem with the configuration of my Devise (4.5.0) in Rails (5.2.1). The login doesn't work via the api.
In my routes.rb I define the routes for Devise within a namespace like this:
Rails.application.routes.draw do
namespace :api do
devise_for :users
end
[...]
end
This generates the correct routes, but the login doesn't work, because Devise thinks that the resource_name or scope is api_user instead of user. If I override the auth_options method I can fix this problem, but is it really the way to go?
Update
I've investigated this further. It's possible to workaround this by adding singular: :user to the devise_for declaration. This isn't intuitive to me, why I created an issue: https://github.com/plataformatec/devise/issues/4969

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.

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

adding controllers with a namespace admin as a subfolder

i have a simple cms on ROR 3.2.
with this folder scheme:
app |controllers |my controllers
but i wanted to have an "admin" section where i could have some controllers too.
so i created
rails generate controller admin/Users
app | controllers |admin & my admin controllers
so my file is:
users_controller.rb
class Admin::UsersController < ApplicationController
def index
render(:text => "sou o index!")
end
def list
render(:text => "sou o list")
end
end
On my routes i have:
namespace :admin do
resources :users
end
match ':controller(/:action(/:id))(.:format)'
Im new to rails and i cant figure out the solution. Cant find it anywhere.
The PROBLEM is
i try do acess:
http://localhost:3000/admin/users/list
and i get this error:
Unknown action The action 'show' could not be found for
Admin::UsersController
You seem to not have an understanding of how Rails's RESTful routing works by default. I recommend reading the Resource Routing section of the Rails Guides. By default, when using resources in your routes, the show action is what is used to display a particular model record. You can customize this behavior to an extent in that you can change the URL that for the show action, but not the method name in the model:
resources :users, :path_names => { :new => 'list' }
If you are going to use RESTful routing (which you should), you should remove the default route (match ':controller(/:action(/:id))(.:format)'). Also, you can run rake routes at any time from the terminal to see details about your current routing configuration.
Your on the right track, however, there are a few more steps involved to complete your solution for a backend admin CRUD section. Check out the following example of how to create it yourself:
https://stackoverflow.com/a/15615003/2207480

Best practices: Namespace or resources for admin interface dashboard Mongoid

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 ).

Resources