【问题标题】:What is the best way to avoid code duplication between views and controllers in Ruby on Rails?在 Ruby on Rails 中避免视图和控制器之间代码重复的最佳方法是什么?
【发布时间】:2010-09-27 11:47:42
【问题描述】:

我的 ApplicationController 目前有代码来检查用户是否已登录并具有执行给定操作所需的访问权限(测试在 before_filter 中进行)。

我需要视图中的相同功能来决定是否应在列表视图中显示管理链接,但如何最好地避免在控制器和视图中重复代码?

我现在选择这样做的方式是拥有 user_can_edit_customers?本质上是“can_edit_customers”的包装器?在我的用户类上:

应用控制器:

类 ApplicationController

然后在我的视图助手中做类似的事情。

这样所有功能都封装在 User 模型中,但我仍然需要在我的控制器和帮助器中定义包装器,但是有更聪明的方法吗?

请注意,用户内容只是一个示例 - 这也适用于其他功能。

【问题讨论】:

    标签: ruby-on-rails ruby model-view-controller


    【解决方案1】:

    我想说去掉包装器,直接在传递给视图的用户对象上调用 can_edit_customers?

    如果您想保留它们,一个解决方案可能是在您的控制器中使用 helper_method

    helper_method :current_user, :can_edit_customers?
    
    def current_user
        @current_user ||= User.find_by_id(session[:user])
    end
    
    def can_edit_customers?
        @current_user.can_edit_customers?
    end
    

    这样,该方法也可以在视图中使用。

    <% if can_edit_customers? -%>...<% end -%>
    

    【讨论】:

      【解决方案2】:

      只是为了更直接。控制器中的 helper_method“宏”导致控制器方法的行为就像它也是应用程序助手中的方法一样。

      helper_method :current_user, :can_edit_customers?
      

      【讨论】:

        【解决方案3】:

        我个人认为你不应该使用助手。

        我会采取不同的解决方案。

        假设我们有 Cucumber,这是一个模型,某些用户不应该对其进行编辑。我创建#editable?方法如下:

        class Cucumber < ActiveRecord::Base
          def editable?(current_user)
            # Something happens here.
          end
        end
        

        请注意,如果每个人都可以访问某个页面,则 current_user 可能为 false。

        那么,在你能做的视图中:

        <%- if @cucumber.editable?(current_user) -%>
        <%# Something happens here. -%>
        <%- end -%>
        

        并且,在控制器中,使用过滤器。

        这种方法的最佳之处在于它遵循Fat Model,使您能够轻松地通过单元测试覆盖您的权限。

        【讨论】:

          【解决方案4】:

          我认为助手是做你想做的事的方法。至于在视图中检查用户是否有权做某事,您可以在会话数据中放置一个标志(例如 session[:admin] = true 并在您的视图中检查。

          【讨论】:

            【解决方案5】:

            通常的做法是制作像logged_in这样的方法?在控制器和视图中可用。大多数情况下,您不需要将授权逻辑下推到模型中。

            一定要采用用户 Hates 描述的方法。看看restful_authentication和acts_as_authenticated等插件,看看他们是如何做到的。

            有几个 railscasts (http://railscasts.com/episodes?search=authentication) 涵盖了这个主题。例如,您可以编写一个获取块的助手,然后像这样使用:

            <%- admin_user_ do %>
              <%= link_to .. %>
              <%= link_to .. %>
              <%= link_to .. %>
            <%- end %>
            

            【讨论】:

              猜你喜欢
              • 2010-09-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-03-22
              • 1970-01-01
              • 2019-08-23
              • 1970-01-01
              • 2015-02-26
              相关资源
              最近更新 更多