Rails 4 + append_view_path

33
我希望在我的Rails gem的控制器中使用动态路径。
我已添加到:
module MyGem
  class FooController < Config.controller
    before_action ->{ append_view_path "app/views/my_gem/#{wizard_name}" }
...

在视图中,我需要像这样指定路径:

app/views/my_gem/#{wizard_name}/my_gem/foo/some.erb

Rails中是否有一种方法可以截断gem命名空间的相对路径,并获取类似于查找路径的内容?
app/views/my_gem/#{wizard_name}/some.erb
# or
foo/bar/some.erb

谢谢!

更新:

我知道可以通过在 Engine 中禁用 isolate_namespace 的方式来解决,但我相信这不是最佳和唯一的选择。

更新2:对于Rails4,这个想法非常有用https://coderwall.com/p/p_yelg/render-view-outside-of-a-controller-in-rails-4


3
我难以理解你具体想要什么。请你举一个例子来阐述你的看法,谢谢。 - Eric Duminil
此问题与视图内容无关,仅涉及查找路径。 - Mike Belyakov
那么,你的 view_paths 是什么样子的?应该是什么样子的?使用 isolate_namespace 后它又变成了什么样子? - Eric Duminil
在Rails 5中,您只需在控制器上调用render方法即可。这使得在后台作业等地方呈现视图变得非常简单:这是一篇不错的博客文章。http://blog.bigbinary.com/2016/01/08/rendering-views-outside-of-controllers-in-rails-5.html 因此,在未来升级时,您可能能够简化一些事情。 - joshuacronemeyer
4个回答

1
Devise gem 有一种通过覆盖 _prefixes 方法来添加视图查找路径的方式:
class DeviseController < Devise.parent_controller.constantize
  include Devise::Controllers::ScopedViews

  # Override prefixes to consider the scoped view.
  # Notice we need to check for the request due to a bug in
  # Action Controller tests that forces _prefixes to be
  # loaded before even having a request object.
  #
  # This method should be public as it is is in ActionPack
  # itself. Changing its visibility may break other gems.
  def _prefixes #:nodoc:
    @_prefixes ||= if self.class.scoped_views? && request && devise_mapping
      ["#{devise_mapping.scoped_path}/#{controller_name}"] + super
    else
      super
    end
  end

end

这个能应用于你的使用情况吗?

查看源代码:
https://github.com/plataformatec/devise/blob/master/app/controllers/devise_controller.rb


0
通常情况下,您应该只覆盖部分视图或来自宝石的函数,不要像这样从宝石库中加载,因为在部署到真实服务器时,这将对您进行调试和改进带来很多麻烦。

-1

假设你的 gem 是一个引擎,你应该能够在引擎中简单地调用 render :some。如果应用程序有一个名为 <gem_name>/<controller_name>/some.html.erb 的视图,它将被使用。

此外,您可以在您的 gem 中提供该视图的版本,如果应用程序尚未提供,则将使用该版本。

如果您需要查找 wizard_name,我认为最好的方法是将视图路径的该部分移动到您调用 render 的末尾。

因此,在您的 gem 控制器中,您将编写 render "#{wizard_name}/some",它将在我们应用程序的 app/views/<gem_name>/<controller_name>/<wizard_name>/some.html.erb 和您的 gem 的 app/views/<controller_name>/<wizard_name>/some.html.erb 中查找该视图。


-1

你可以编写自己的渲染方法,读取任意文件,解释ERB并将其呈现为HTML页面。

ERB.new(File.read(Rails.root.join('foo', bar', 'some.erb'))).result(binding)

通过传递binding,模板将可以访问当前上下文中的所有变量。

有关更多详细信息,请参阅ERB文档:http://apidock.com/ruby/ERB


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接