Пространство имен 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
Итак, вопрос в том, ищет ли Руби Api::V1::ApplicationController
, Api::ApplicationController
или ApllicationController
для продления?
тут < ApplicationController
найдите собственное пространство имен, если я не укажу Api::ApplicationController
? Если да, то как указать корень один?
3 ответов
при использовании
#The code in question
module Api
module V1
class UserController < ApplicationController
end
end
end
ApplicationController
определение будет искать в Api::V1
тогда, если не нашли в Api
тогда, если не найден в корневом пространстве имен.
я согласен, что это может быть запутанным, поэтому я склонен использовать абсолютные пути так:::ApplicationController
если когда-нибудь мне понадобится Api::ApplicationController
, Я бы написал ::Api::ApplicationController
в основном ::
сообщает ruby, чтобы начать с корневого пространства имен, а не откуда код жизни.
Sidenote
имейте в виду, что в режиме разработки Rails есть порочные случаи. Для того, чтобы набрать скорость, минимально загружен. Затем Rails ищет определения классов, когда это необходимо.
но это иногда терпит неудачу большой пример времени, когда вы говорите ::User
уже загружен, а потом искать ::Admin::User
. Рельсы не будут его искать, он подумает ::User
делает трюк.
этот может быть решена с помощью require_dependency
операторы в вашем коде. Скорость имеет стоимость:)
Я бы скорее предложил не писать ApplicationController
в пространстве имен, я бы посоветовал следовать следующим
Примечание: Если вы строите профессиональный api, всегда хорошо иметь Api::V1::BaseController
наследование от ActionController::Base
, хотя я даю решение для вашего конкретного случая
Ref этот пост:реализация Rails API, как профессионал
1) Определите контроллер приложения обычным способом в app / controllers / application_controller.rb as
class ApplicationController < ActionController::Base
end
2) Определите базовый контроллер api, а именно Api:: V1:: BaseController в app/controllers/api/v1/base_controller.rb, который унаследует от ApplicationController
(ваш случай) как
class Api::V1::BaseController < ApplicationController
end
3) Определите свои контроллеры api, такие как Api::V1::UsersController
в app/controllers/api/v1/users_controller.rb, который наследуется от 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
ясно, что счет-фактура-это состав элементов, и элемент не может жить без содержащего счета-фактуры. Другие классы, вероятно, будут взаимодействие с накладной, а не с номенклатурой. Итак, давайте вытащим предмет из путь, вложив его в пространство имен накладной. Это включает переименование класс для выставления счета:: Item и перемещение исходного файла в app / модели / счет / товар.rb:
class Invoice::Item < ActiveRecord::Base belongs_to :invoice end
то же самое применяется к контроллерам и представлениям.