Пространство имен 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

то же самое применяется к контроллерам и представлениям.