пространство имен rails 4: модели и контроллеры структуры папок


Моя текущая структура приложения выглядит следующим образом:

Введите описание изображения здесь

Пример контроллера выглядит так:

class Api::V1::RegisterController < Api::V1::ApiController

  def create
    @user                  = ::V1::User.new(user_params)
    @user.email_address    = params[:email_address]
    @user.age_verification = params[:age_verification]
    @user.remote_addr      = request.env['REMOTE_ADDR']
    @user.web_browser      = browser.name.to_s + "(" + browser.version.to_s + ")"
    @user.operating_system = browser.platform.to_s

    if @user.save
      head status: 201
    else
      render_bad_request(@user.errors.messages)
    end
  end

  private

  def user_params
    params.permit(:email_address, :remote_addr, :web_browser, :operating_system, :age_verification)
  end

end

Пример модели выглядит следующим образом:

class V1::User < ActiveRecord::Base

  validates_presence_of :remote_addr, :web_browser,
                        :operating_system, :age_verification, :email_address

  validates :email_address, uniqueness:   { case_sensitive: false },
                            email_format: { check_mx: true }

end

Мой основной вопрос здесь заключается в том, почему я вынужден использовать ::V1 перед моими моделями? Есть ли лучший способ обойти это, или я что-то упускаю?

2 4

2 ответа:

Постоянные поисковые запросы выполняют поиск в текущей области модуля, а затем перемещаются вверх по дереву вложенности модуля. Если вы просто используете V1::User, то код в RegisterController будет искать сначала в Api::V1::RegisterController для V1, затем, не найдя его, переместится до Api::V1, а затем до Api, где он находит V1, поэтому он успешно нашел константу V1. Но Api::V1 не содержит константы с именем User (или, по крайней мере, не той, о которой вы думаете). Если поместить :: впереди, то постоянный поиск начинается в верхней части модуля. пространство имен, более или менее.

Что касается того, есть ли лучший способ... возможно, вы хотите поменять местами уровни V1 с Api? Тогда был бы модуль управления версиями верхнего уровня, и V1::Api::WhateverController мог бы найти User без указания версии. Если это то, чего вы пытаетесь достичь....

В этом примере ::V1 и ::Api::V1 являются отдельными объектами модуля. Когда вы ссылаетесь на V1::User изнутри Api::V1::ApiController, ruby будет искать в пределах ближайшего V1 модуль для User. Поскольку вы уже находитесь внутри API::V1, ruby затем пытается ссылаться на ::Api::V1::User. Когда он не может найти его, включается автопогрузчик ActiveSupport и ищет api/v1/user.rb где-то в пути загрузки. Поскольку такого файла не существует, автозагрузчик не может найти модель User и выбрасывается NameError.