rails 4 namespace ::文件夹结构模型和控制器

时间:2014-06-18 10:09:36

标签: ruby-on-rails namespaces rails-api

我目前的申请结构如下:

enter image description here

示例控制器如下所示:

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 个答案:

答案 0 :(得分:3)

常量查找搜索当前模块范围,然后向上移动模块嵌套树。如果您只使用V1::User,那么RegisterController中的代码将Api::V1::RegisterController中的V1首先显示Api::V1,然后找不到代码,将向上移动到Api ,然后最多V1,它找到V1,因此它已成功找到常量Api::V1。但是User并不包含名为::的常量(或者至少不是您正在考虑的常量)。将V1置于前面使得常量搜索从模块名称空间的顶部开始,或多或少。

至于是否有更好的方式...也许您想要将Api的级别与V1::Api::WhateverController交换?然后会有一个顶级版本控制模块,User可以找到{{1}}而无需指定版本。如果那是你想要实现的目标......

答案 1 :(得分:1)

在此示例中,::V1::Api::V1是单独的模块对象。当您从V1::User内部引用Api::V1::ApiController时,ruby会在最近的 V1模块中查找User。由于您已经在API::V1内,因此ruby会尝试引用::Api::V1::User。当它找不到它时,ActiveSupport的自动加载器启动并在加载路径中的某处查找api/v1/user.rb。由于不存在此类文件,因此自动加载器无法找到User模型,并且会抛出NameError