Ruby namespace

I am new to ruby ​​based on php background, but something doesn't click with me.

So let's say I have a Ruby on Rails application, and I control my API version as follows:

app |_controllers |_api | |_v1 | | |_application_controller.rb | | |_user_controller.rb | |_application_controller.rb |_application_controller.rb 

With class structure with

 # Versioned API V1 app controller module Api module V1 class ApplicationController end end end # Versioned API app controller module Api class ApplicationController end end # Root app controller class ApplicationController end #The code in question module Api module V1 class UserController < ApplicationController end end end 

So the question is, does ruby ​​look for Api::V1::ApplicationController , Api::ApplicationController or ApllicationController for extension?

Does < ApplicationController go its own namespace if I don't specify Api::ApplicationController ? If so, how can I specify the root file?

+8
ruby namespaces ruby-on-rails
source share
3 answers

When you use

 #The code in question module Api module V1 class UserController < ApplicationController end end end 

ApplicationController will search for a definition in Api::V1 , and then if it is not found in Api , then if it is not found in the root namespace.

I agree that this can be confusing, so I tend to use absolute paths like this: ::ApplicationController

If I need Api::ApplicationController , I would write ::Api::ApplicationController

Basically :: tells ruby ​​to run from the root namespace, and not from where the code is located.


Sidenote

Keep in mind that there are vicious cases in Rails development mode. To get speed, a strict minimum is loaded. Rails then searches for class definitions when necessary.

But this sometimes is not suitable for a large example of the time when you already said ::User already loaded, and then look for ::Admin::User . Rails will not look for it, it will think that ::User doing the trick.

This can be solved using the require_dependency statements in your code. Speed ​​has a cost :)

+16
source share

I would rather not write ApplicationController in the namespace, I would suggest to follow below

Note. If you are creating a professional api, it is always useful to have Api::V1::BaseController inheritance from ActionController::Base , although I give a solution for your specific case

Ref this post: Implement a Rails API such as a professional

1) Define the application controller in the usual way in application / controllers / application_controller.rb as

 class ApplicationController < ActionController::Base end 

2) Define the base api controller, namely Api :: V1 :: BaseController in app / controller / api / v1 / base_controller.rb, which inherits from ApplicationController (your case), for example

 class Api::V1::BaseController < ApplicationController end 

3) Define your api controllers such as Api::V1::UsersController in the application / controllers / api / v1 / users_controller.rb that inherit from Api :: V1 :: BaseController

 class Api::V1::UsersController < Api::V1::BaseController end 

4) Add all subsequent controllers, such as Api::V1::UsersController (step 3)

Then the routing will contain the namespace routing in config / routes.rb

 namespace :api do namespace :v1 do resources :users do #user routes goes here end # any new resource routing goes here # resources :new_resource do # end end end 
+2
source share

You should check the manual to understand the routing: http://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing

I think this question is very similar to:

Rails controller namespace

And as a disadvantage:

Rails will automatically detect the namespace in the folder. Therefore, you do not need to add it to the name:

This blog post explains it so well:

http://blog.makandra.com/2014/12/organizing-large-rails-projects-with-namespaces/

Say we have an Invoice class, and each invoice can have several invoice elements:

 class Invoice < ActiveRecord::Base has_many :items end class Item < ActiveRecord::Base belongs_to :invoice end 

It is clear that an invoice is a composition of items, and an item cannot live without a containing invoice. Other classes are likely to interact with the invoice and not with the item. So let’s get the Item out by pasting it into the account namespace. This involves renaming the class to Invoice :: Item and moving the source file to application / model / invoice / item.rb:

  class Invoice::Item < ActiveRecord::Base belongs_to :invoice end 

The same applies to controllers and views.

0
source share

All Articles