Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: After putting devise routes in namespace, the name of model are prefixed with the namespace. How to remove it?

I am using devise for authentication in my Rails RESTFul API service. Devise enables me to create a new user using [POST] http://domain/users with form_data:

[user]password = 123
[user]email = [email protected]
[user]password_confirmation = 123

Then I put devise_for in namespace like this

namespace :api do
  namespace :v1 do
    devise_for :users,
               controllers: {
                   :registrations => 'api/v1/registrations',
                   :sessions => 'api/v1/sessions',
                   :passwords => 'api/v1/passwords'
               }
  end
end

The file structure of controllers looks like this.

.
├── api
│   └── v1
│       ├── passwords_controller.rb
│       ├── registrations_controller.rb
│       └── sessions_controller.rb
├── application_controller.rb

After I made this change, I should use [POST] http://domain/api/v1/users to create a new user, but with the following form_data

[api_v1_user]password = 123
[api_v1_user]email = [email protected]
[api_v1_user]password_confirmation = 123

I don't want the model name (i.e. user) to be prefixed by api_v1_. Because if someday I switched my api version to v2, then I have to update all my client side API call!

Any ideas?

like image 645
John Wu Avatar asked Oct 01 '14 09:10

John Wu


People also ask

Why don’t developers use namespaces in rails?

In general, Rails doesn’t encourage developers to factor code into namespaces. Most apps end up with hundreds of files and very few directories in app/models and similarly flat hierarchies in other app directories.

Do you have to tell rails the class name of a table?

Outside the namespace, though, you’ll have to tell Rails the class name of any association that uses your namespaced model. Otherwise, it will guess incorrectly: Since most databases don’t support namespaces for tables, Rails expects you to prefix your table names with the “underscored” name of your namespace.

How to prevent name collisions between routes in rails?

You can use the :as option to prefix the named route helpers that Rails generates for a route. Use this option to prevent name collisions between routes using a path scope.

What is resource routing in rails?

The Rails.application.routes.draw do ... end block that wraps your route definitions is required to establish the scope for the router DSL and must not be deleted. Resource routing allows you to quickly declare all of the common routes for a given resourceful controller.


2 Answers

You can try the following in your routes

namespace :api, as: nil do
  namespace :v1, as: nil do |version|
    devise_for :users,
               controllers: {
                   :registrations => "api/#{version}/registrations",
                   :sessions => "api/#{version}/sessions",
                   :passwords => "api/#{version}/passwords"
               }
  end
end
like image 112
Bachan Smruty Avatar answered Sep 22 '22 07:09

Bachan Smruty


Check out devise Configuring Routes doc. You can achieve this by customizing the api routes yourself. E.g

namespace :api do
  namespace :v1 do
   devise_scope :user do
    resources :sessions,        defaults: {format: :json}
    resources :registrations,   defaults: {format: :json}
   end
 end
end
like image 29
dre-hh Avatar answered Sep 19 '22 07:09

dre-hh