Ruby命名空间

Gin*_*ech 10 ruby namespaces ruby-on-rails

我是非常新的ruby,来自php背景,但有些东西没有点击我.

所以,假设我有一个Ruby on Rails应用程序,我正在对我的API进行版本控制:

app
|_controllers
  |_api
  | |_v1
  | | |_application_controller.rb
  | | |_user_controller.rb
  | |_application_controller.rb
  |_application_controller.rb
Run Code Online (Sandbox Code Playgroud)

具有类结构

# 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
Run Code Online (Sandbox Code Playgroud)

所以现在的问题是,是否红宝石寻找Api::V1::ApplicationController,Api::ApplicationControllerApllicationController延长?

是否< ApplicationController寻找它自己的命名空间,除非我指定Api::ApplicationController?如果是这样,我如何指定根目录?

apn*_*ing 17

当你使用

#The code in question
module Api
  module V1
    class UserController < ApplicationController
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

ApplicationController如果在根名称空间中Api::V1找不到,Api那么将在那里搜索定义.

我同意这可能会令人困惑,这就是为什么我倾向于使用这样的绝对路径: ::ApplicationController

如果我需要Api::ApplicationController,我会写::Api::ApplicationController

基本上,::告诉ruby从根命名空间开始,而不是从代码所在的位置开始.


边注

请注意,Rails开发模式中存在恶意案例.为了获得速度,加载严格的最小值.然后Rails在需要时查找类定义.

但这有时会失败很大的时间例子,当你说::User已经加载,然后寻找::Admin::User.Rails不会寻找它,它会认为::User这样做.

这可以使用require_dependency代码中的语句来解决.速度有成本:)


Pra*_*nde 5

我宁愿建议不要ApplicationController在命名空间中编写,我建议遵循以下内容

注意:如果您正在构建专业的 api,那么继承总是好的Api::V1::BaseControllerActionController::Base尽管我正在针对您的具体情况提供解决方案

参考这篇文章:像专业人士一样实现 Rails API

1)在app/controllers/application_controller.rb中以通常的方式定义应用程序控制器为

class ApplicationController < ActionController::Base
end 
Run Code Online (Sandbox Code Playgroud)

2)在 app/controllers/api/v1/base_controller.rb 中定义基本 api 控制器,即 Api::V1::BaseController ,它将继承自ApplicationController(您的情况),例如

class Api::V1::BaseController < ApplicationController
end 
Run Code Online (Sandbox Code Playgroud)

3)定义你的api控制器,如Api::V1::UsersControllerapp/controllers/api/v1/users_controller.rb,它将继承自Api::V1::BaseController

class Api::V1::UsersController < Api::V1::BaseController
end 
Run Code Online (Sandbox Code Playgroud)

4) 添加所有后续控制器,如Api::V1::UsersController(步骤 3)

然后路由将在 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
Run Code Online (Sandbox Code Playgroud)