如何向 Rails 的部分渲染查找添加视图路径?
我想要以下目录结构:
views/
app1/
users/_user.html.erb
users/index.html.erb
app2/
users/index.html.erb
shared/
users/_user.html.erb
users/index.html.erb
在我看来,我会调用
# app1/users/index.html
<%= render :partial => "user" %>
# => /app1/users/_user.html.erb
# app2/users/index.html
<%= render :partial => "user" %>
# => /shared/users/_user.html.erb
所以基本上,我如何告诉 Rails 在引发缺少模板错误之前先签入 /app2/users 目录,然后签入共享目录?
更新
我解决了这个问题(按照 Senthil 的建议,使用 File.exist?
这是我的解决方案 - 欢迎反馈和建议
# application_helper.rb
# Checks for a partial in views/[vertical] before checking in views/shared
def partial_or_default(path_name, options={}, &block)
path_components = path_name.split("/")
file_name = path_components.pop
vertical_file_path = File.join(vertical}, path_components, file_name)
shared_file_path = File.join("shared", path_components, file_name)
full_vertical_file_path = File.join("#{Rails.root}/app/views/", "_#{vertical_file_path}.html.erb")
attempt_file_path = File.exist?(full_vertical_file_path) ? vertical_file_path : shared_file_path
render({:partial => attempt_file_path}.merge(options), &block)
end
I'd like to have the following directory structure:
views/
app1/
users/_user.html.erb
users/index.html.erb
app2/
users/index.html.erb
shared/
users/_user.html.erb
users/index.html.erb
In my view, I'd call
# app1/users/index.html
<%= render :partial => "user" %>
# => /app1/users/_user.html.erb
# app2/users/index.html
<%= render :partial => "user" %>
# => /shared/users/_user.html.erb
So basically, how do I tell Rails to check in the /app2/users dir then the shared dir before it raises it's missing template error?
Update
I got around this (as suggested by Senthil, using File.exist?
Here's my solution - feedback and suggestions welcome
# application_helper.rb
# Checks for a partial in views/[vertical] before checking in views/shared
def partial_or_default(path_name, options={}, &block)
path_components = path_name.split("/")
file_name = path_components.pop
vertical_file_path = File.join(vertical}, path_components, file_name)
shared_file_path = File.join("shared", path_components, file_name)
full_vertical_file_path = File.join("#{Rails.root}/app/views/", "_#{vertical_file_path}.html.erb")
attempt_file_path = File.exist?(full_vertical_file_path) ? vertical_file_path : shared_file_path
render({:partial => attempt_file_path}.merge(options), &block)
end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Rails 中已经内置了一些东西,可以为您提供这种类型的“主题化”。它称为prepend_view_path。
http://api.rubyonrails.org/classes/ActionView /ViewPaths/ClassMethods.html#method-i-prepend_view_path
还有 append_view_path 用于添加路径查找堆栈的末尾。
我在生产中成功地工作了:
现在每个控制器将首先在“views/app1”(或任何动态名称)中查找与被调用的操作相对应的视图。
它还足够智能,可以检查您正在查找的文件的所有已定义路径,因此如果找不到,它会回滚到默认位置。
There's already something built into rails that facilitates this type of "theming" for you. It's called prepend_view_path.
http://api.rubyonrails.org/classes/ActionView/ViewPaths/ClassMethods.html#method-i-prepend_view_path
There's also append_view_path for adding paths to the end of the lookup stack.
I have this successfully working in production:
Now every controller will first look in "views/app1" (or whatever your dynamic name turns out to be) for the views corresponding to the action being called.
It's also smart enough to check all the defined paths for the file you're looking for, so it rolls back to the default location if one isn't found.