ruby-on-rails – Rails的自动加载/恒定分辨率正在创建ghost模块

前端之家收集整理的这篇文章主要介绍了ruby-on-rails – Rails的自动加载/恒定分辨率正在创建ghost模块前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这是 a brand new Rails 5.1.4 app,有一个型号和几个路线和控制器.

命名空间控制器引用顶级模型:

class AdminArea::WelcomeController < ApplicationController
  def index
    @user = User.new(name: 'Sergio')
  end
end

到现在为止还挺好.您可以查看主服务器,导航到http:// localhost:3000 / admin_area / welcome并查看它是否有效.

但是如果我们were to add an empty directory app/presenters/admin_area/user/ *,那么事情会变得奇怪.突然之间,该控制器中的用户不是我的模型,而是一个不存在的模块!

NoMethodError (undefined method `new' for AdminArea::User:Module):

app/controllers/admin_area/welcome_controller.rb:3:in `index'

当然,该模块没有任何[非内置]方法,也无法固定到磁盘上的源文件中.

问题:为什么添加一个空目录导致rails神秘地通过空气神秘地召唤一个模块,而不是正确地将用户名解析为我的模型?

*实际上,如果您按原样检查该分支,您将收到不同的错误.

NameError (uninitialized constant AdminArea::WelcomeController::User)

因为git不会让我提交一个空目录,所以我在那里添加了一个.keep文件.但是一旦删除文件,就会得到上述行为.

解决方法

这是ruby常量查找的结果,以及Rails如何解析自动加载.

控制器中的常量用户称为“relative reference”,这意味着它应该相对于其发生的命名空间进行解析.
对于此常量,有三种可能的变量,其中可以定义常量:

AdminArea::WelcomeController::User
AdminArea::User
User

Rails自动加载将这些常量映射到文件名中并在autoload_path上进行迭代,以便找到定义常量的文件.例如.:

app/assets/admin_area/welcome_controller/user.rb
app/assets/admin_area/welcome_controller/user
app/channels/admin_area/welcome_controller/user.rb
...
app/assets/admin_area/user.rb
app/assets/admin_area/user
...
app/assets/user.rb
...
app/models/user.rb #=> here it is!

将admin_area / user文件添加到presenters目录中时,您实际上是在定义这样的常量. Modules in Rails are automagically created,这样您实际上不需要创建定义这些仅用作命名空间的模块的文件.

添加文件夹后,该文件夹出现在Rails查找中:

...
app/assets/admin_area/user.rb
app/assets/admin_area/user
...
app/presenters/admin_area/user #=> Here Rails finds the folder

和Rails解析用户引用该模块.

但是,这很容易修复,如果您希望AdminArea命名空间中使用的User常量引用顶级常量(而不是AdminArea :: User模块),则应将“相对引用”更改为绝对引用通过在::之前加上常量.

@user = ::User.new(name: 'Sergio')
原文链接:https://www.f2er.com/ruby/268168.html

猜你在找的Ruby相关文章