代码之家  ›  专栏  ›  技术社区  ›  Eimantas

铁路中的关注分离困境

  •  1
  • Eimantas  · 技术社区  · 16 年前

    我正在尝试为我的Rails应用程序做日志记录,并在Rails中使用的哲学上遇到了一些困难。我的应用程序已经 Link 模型 has_many Hit S:

    class Link < AR::Base
      has_many :hits
    end
    
    class Hit < AR::Base
      belongs_to :link
    end
    

    每次点击链接,我都会打电话 hit! 在链接上记录请求的方法(为了使控制器保持瘦,我使模型变胖):

    class LinksController < ApplicationController
      def hit
        link = Link.find(params[:id])
        link.hit!(request)
      end
    end
    
    class Link < AR::Base
      def hit!(request)
        params = extract_data_from_request(request)
        hits.create(params)
      end
    end
    

    这就是我困惑的地方。我要记录随附的数据 request 对象(如远程IP、引用、用户代理等),所以我需要将请求对象传递给模型,但我认为这不符合MVC设计模式中的“关注点分离”和模糊责任线(当然,如果我错了,请纠正我)。如果我要创建一个 击中 对象在控制器本身,然后我要做瘦模型和胖控制器:

    class LinksController < ApplicationController
      def hit
        hit_params = extract_data_from_request(request)
        Hit.create(hit_params.merge(:link_id => params[:id])
      end
    end
    

    尽管后一种情况使测试更加容易(我不需要在模型规范中模拟请求),但这似乎不正确。

    关于这方面的任何建议-非常感谢。

    附笔。 extract_data_from_request(req) 方法放置在需要的适当位置。它返回所需属性的哈希 击中 对象。

    2 回复  |  直到 16 年前
        1
  •  2
  •   John Topley    16 年前

    就我个人而言,我会小心过多地考虑这些事情。

    hit的概念与网站或Web应用程序非常相关,而(http)请求的概念也是如此。FAT控制器反模式更多的是拥有包含ActiveRecord查找语句和业务逻辑(通常以 if / elsif / else 块)可以很容易地提取到模型中。

    控制器具有一定的协调职责。在一个人体内创造一个物体并不是一种可恶的罪行。毕竟,我们一直在 create 行动。

        2
  •  2
  •   Max Williams    16 年前

    是的,我同意约翰的看法。请求的概念通常是“控制器的东西”,但在这种情况下,您的模型是 建模 一个请求,所以在本例中它肯定在模型领域中。实际上,一旦请求对象跨越控制器到模型的边界,它只是另一个对象,没有特殊的属性:它不再关心获取和响应HTML请求的过程,它只是一个对象,您可以用它来做任何您想做的事情。

    不过,要注意的一点是,在Ruby中,参数是通过引用传递的。这意味着您在模型中操作的请求对象与在控制器中处理的对象相同。我可能过于偏执(或者是完全错误的),但您可能希望将它的副本传递给模型,而不是实际的请求本身。工业工程

    class LinksController < ApplicationController
      def hit
        link = Link.find(params[:id])
        link.hit!(request.dup)
      end
    end