Ruby命名空间
我是一个非常新的ruby,来自php背景,但有些东西没有点击我。
所以,假设我有一个Ruby on Rails应用程序,我正在对我的API进行版本控制:
app |_controllers |_api | |_v1 | | |_application_controller.rb | | |_user_controller.rb | |_application_controller.rb |_application_controller.rb
具有类结构
# 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
所以问题是,ruby是否会查找Api::V1::ApplicationController
, Api::ApplicationController
或ApllicationController
进行扩展?
除非我指定Api::ApplicationController
否则< ApplicationController
是否会查找它自己的命名空间? 如果是这样,我如何指定根目录?
当你使用
#The code in question module Api module V1 class UserController < ApplicationController end end end
将在Api::V1
搜索ApplicationController
定义,如果在Api
找不到,则在根命名空间中找不到。
我同意它可能令人困惑,这就是为什么我倾向于使用绝对路径,如::ApplicationController
如果我需要Api::ApplicationController
,我会编写::Api::ApplicationController
基本上, ::
告诉ruby从根命名空间开始,而不是从代码所在的位置开始。
边注
请注意,Rails开发模式中存在恶意案例。 为了获得速度,加载严格的最小值。 然后Rails在需要时查找类定义。
但是这有时会失败大时间的例子,当你说::User
已经加载,然后寻找::Admin::User
。 Rails不会寻找它,它会认为::User
做到这一点。
这可以使用代码中的require_dependency
语句来解决。 速度有成本:)
我宁愿建议不要在命名空间中编写ApplicationController
,我建议遵循以下内容
注意:如果你正在构建专业的api,那么让Api::V1::BaseController
从ActionController::Base
inheritance总是好的,尽管我给你的具体案例提供了解决方案
参考这篇文章: 像专业人士一样实现Rails API
1)以app / controllers / application_controller.rb中的常规方式定义应用程序控制器
class ApplicationController < ActionController::Base end
2)定义基本api控制器,即app / controllers / api / v1 / base_controller.rb中的Api :: V1 :: BaseController,它将inheritance自ApplicationController
(你的情况)
class Api::V1::BaseController < ApplicationController end
3)在app / controllers / api / v1 / users_controller.rb中定义api控制器,如Api::V1::UsersController
,它将inheritance自Api :: V1 :: BaseController
class Api::V1::UsersController < Api::V1::BaseController end
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
您应该查看指南以了解路由: http : //guides.rubyonrails.org/routing.html#controller-namespaces-and-routing
我认为这个问题非常类似于:
Rails控制器命名空间
而作为短缺:
Rails将通过该文件夹自动检测命名空间。 所以你不需要将它附加到名称:
这篇博客文章解释得很好:
http://blog.makandra.com/2014/12/organizing-large-rails-projects-with-namespaces/
假设我们有一个发票类,每张发票可以有多个发票项目:
class Invoice < ActiveRecord::Base has_many :items end class Item < ActiveRecord::Base belongs_to :invoice end
显然,Invoice是Items的组合,如果没有包含Invoice,则Item不能生效。 其他类可能与Invoice交互而不与Item交互。 因此,让我们通过将它嵌套到Invoice命名空间中来获取Item。 这涉及将类重命名为Invoice :: Item并将源文件移动到app / models / invoice / item.rb:
class Invoice::Item < ActiveRecord::Base belongs_to :invoice end
同样适用于控制器和视图。