Ruby namespacing

后端 未结 3 926
温柔的废话
温柔的废话 2020-12-10 05:32

I\'m pretty new to ruby, coming from a php background, but something is not clicking with me.

So, let\'s say I have a Ruby on Rails application and I am versioning m

相关标签:
3条回答
  • 2020-12-10 05:49

    You should check the guide 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 shortage:

    Rails will detect the namespace automagically by the folder. So you don't need to append it to the name:

    This blog post explains it so well:

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

    Let's say we have an Invoice class and each invoice can have multiple invoice items:

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

    Clearly Invoice is a composition of Items and an Item cannot live without a containing Invoice. Other classes will probably interact with Invoice and not with Item. So let's get Item out of the way by nesting it into the Invoice namespace. This involves renaming the class to Invoice::Item and moving the source file to app/models/invoice/item.rb:

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

    Same is applied to controllers and views.

    0 讨论(0)
  • 2020-12-10 05:50

    When you use

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

    ApplicationControllerdefinition will be searched in Api::V1 then if not found in Api then if not found in the root namespace.

    I agree it could be confusing, that's why I tend to use absolute paths like so: ::ApplicationController

    If ever I'd need Api::ApplicationController, I'd write ::Api::ApplicationController

    Basically the :: tells ruby to start from the root namespace and not from where the code lives.


    Sidenote

    Be aware that there are vicious cases in Rails development mode. In order to gain speed, the strict minimum is loaded. Then Rails looks for classes definitions when needed.

    But this sometimes fails big time example, when you have say ::User already loaded, and then look for ::Admin::User. Rails would not look for it, it will think ::User does the trick.

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

    0 讨论(0)
  • 2020-12-10 06:03

    I would rather suggest don't write ApplicationController in namespace, I would suggest to follow following

    Note: If you are building professional api's it always good to have Api::V1::BaseController inheriting from ActionController::Base, though I am giving solution to your specific case

    Ref this post: Implementing Rails APIs like a professional

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

    class ApplicationController < ActionController::Base
    end 
    

    2) Define base api controller namely Api::V1::BaseController in app/controllers/api/v1/base_controller.rb which will inherit from ApplicationController (your case) like

    class Api::V1::BaseController < ApplicationController
    end 
    

    3) Define your api controllers like Api::V1::UsersController in app/controllers/api/v1/users_controller.rb which will inherit from Api::V1::BaseController

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

    4) Add all subsequent controllers like Api::V1::UsersController (step 3)

    Then routing will contain namespaces 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
    
    0 讨论(0)
提交回复
热议问题