在 Rails 中存储布局逻辑的最佳位置在哪里?

Posted

技术标签:

【中文标题】在 Rails 中存储布局逻辑的最佳位置在哪里?【英文标题】:Where is the best place to store layout logic in Rails? 【发布时间】:2013-09-01 05:39:39 【问题描述】:

在我的 Rails 应用程序中,我有几个控制器为我的客户构建一个网站。最终用户和管理员使用几乎所有的控制器。

我创建了一个包含导航链接的部分。我的问题是我不希望它们出现在管理部分内。让这件事变得棘手的部分是,虽然导航应该出现在 pages/home/galleries/galleries/5 之类的东西上,但它们不应该出现在 /pages/new/galleries/5/edit 之类的东西上。

到目前为止,我一直在向application.html.erb 添加逻辑,但事情开始失控,我的 if 语句中有太多规则,我觉得它很脏。这是一个例子:

来自 application.html.erb 的 sn-p

<% unless current_page?('/') or current_page?('/admin') or current_page?(action: :new) %>
    <%= render "layouts/top_links" %>
<% end %>

这就是我到目前为止所写的全部内容,但如果我继续这样下去,几乎肯定会变得更长。所以这是我的问题:

    我应该把它的逻辑放在哪里,我应该怎么称呼它? current_page? 是最好的布局方式吗?

【问题讨论】:

【参考方案1】:

你可以把这么脏的逻辑放到 helper 里,让它更干净

# layouts/application.html.erb
nav_links

# application_helper
def nav_links
  return "" if action_name.in?['new', 'edit'] || controller_path == 'admin'
  render partial: 'layouts/nav'
end

完成。

【讨论】:

这正是我想要的。 很高兴能提供一点帮助。【参考方案2】:

您可以使用基于角色的方法进行改进,因为它是 Rails 中使用最广泛的访问控制方法。事实上,application.html.erb 中的所有 if-else 循环无论如何都会有点代码味道。

为此检查 Ryan Bates CanCan gem。

【讨论】:

我真的希望这能奏效。无论如何,这可能就是我最终要做的事情。不过,这是我对这种方法的问题:如果管理员在未注销的情况下访问该站点,我仍然希望显示链接。条件应基于位置,而不是用户。这有意义吗? 确实如此,但您自己已经描述了与之相关的问题。如果你能驾驭它,那完全没有问题!【参考方案3】:

一种可能性是使用before_filter,您可以在ApplicationController 中设置它。你能做什么

对此应用你自己的风格,但一个愚蠢的例子可能是:

class ApplicationController < ActionController::Base
    before_filter :set_navigation_visibility

    def set_navigation_visibility
        # Your custom logic
    end

如果需要,也可以在子控制器中覆盖该方法,或使用:only:except 选项进行修改。

另一种可能性是使用基于角色的访问控制系统。有很多,我使用过的一个这样的库是Simple-Navigation。 A google search for role-based access control for rails 似乎产生了许多可能有用的结果。

【讨论】:

以上是关于在 Rails 中存储布局逻辑的最佳位置在哪里?的主要内容,如果未能解决你的问题,请参考以下文章

在 Rails API 中向第三方发送错误数据的最佳位置在哪里?

在 Rails 应用程序中存储 Configatron 配置的正确/最佳位置是啥?

Rails + 延迟作业:存储自定义作业类的正确位置在哪里?

Rails:放置在哪里以及如何调用预定的清理方法

在存储过程或应用程序中处理事务的最佳位置在哪里?

在哪里存储 Rails 应用程序的版本