Rails:在Rails6中使用绝对路径

Rails: Use of absolute path in Rails 6

最近,我将我正在维护的 Rails 应用程序升级到了 Rails 6 RC2(来自 5.2.3)。因此,在升级之后,我 运行 自动测试 (RSpec) 并且测试输出给了我很多弃用警告。其中一个警告是:

DEPRECATION WARNING: render file: should be given the absolute path to a file

所以我去触发警告的视图文件,做了如下修改,

之前: render file: 'devise/sessions/new'

之后: render file: Rails.root.join('app', 'views', 'devise', 'sessions', 'new.html.slim')

我再次运行 测试,没有看到弃用警告的输出。但是,在切换到绝对路径后,视图现在只呈现纯 HTML 代码,但如果我删除 .slim 扩展名,即

render file: Rails.root.join('app', 'views', 'devise', 'sessions', 'new.html')

相应的视图正确呈现,但现在测试会抱怨没有使用绝对路径。有没有办法解决这个问题,或者这是一个 Rails/Slim 错误?

在您的情况下,您似乎想要呈现一个普通视图,即 模板.

在这种情况下,不推荐使用 file 选项。相反,您应该使用 template 选项。

render template: 'devise/sessions/new'

或者更好的是,您可以使用此快捷方式:

render 'devise/sessions/new'

背景

file 选项旨在呈现 您的 Rails 应用程序之外的视图,您不能依赖 Rails' 查看查找逻辑。因此 Rails 想要一个绝对路径。要求绝对路径还迫使开发人员考虑相对路径段 (/../)。

省略 .slim 扩展名,然后让模板引擎处理文件是模板的一项功能。使用 file 似乎提供了完全相同的功能,但我猜测这只是视图路径查找内部工作的副作用。看起来 Rails 开发人员希望在未来改进文件和模板之间的区别,弃用相关文件是一个中间步骤,不会破坏太多依赖使用 file 的现有应用程序,并且仍然期望模板的功能。

PS: 没有必要手动分割你的路径。因此,如果您出于某种原因仍想使用 file 和绝对路径,而不是

render file: Rails.root.join('app', 'views', 'devise', 'sessions', 'new.html.slim')

使用这个

render file: Rails.root.join('app/views/devise/sessions/new.html.slim')

我在处理 Rails 6 API-only 应用程序时遇到了同样的挑战。

我想从名为 home_controller.rb

的控制器呈现静态页面

这是我的代码:

require 'rails/application_controller'

class HomeController < Rails::ApplicationController
  def index
    render file: Rails.root.join('public/index.html')
  end
end

但是当我尝试访问页面时出现错误:

Started GET "/favicon.ico" for ::1 at 2021-02-23 16:25:41 +0100
Processing by HomeController#index as */*
  Parameters: {"other"=>"favicon"}
Completed 500 Internal Server Error in 1ms (ActiveRecord: 0.0ms | Allocations: 301)
 
ArgumentError (`render file:` should be given the absolute path to a file. '/home/my-computer/Projects/MyWebsite/public/index.html' was given instead):

我是这样解决的:

问题是我在目录 public 中丢失了文件 index.html,因此 Rails 找不到它。

我所要做的就是在目录 public 中添加文件 index.html。这次我测试的时候没问题

就这些了。

希望对您有所帮助