1

Rails アプリのロギングを作成しようとしていますが、Rails で使用される哲学についてジレンマがあります。私のアプリには次のLinkモデルがありhas_many Hitます:

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

ここで私は混乱しています。オブジェクトに付属するデータ(リモートIP、リファラー、ユーザーエージェントなど)を記録したいrequestので、リクエストオブジェクトをモデルに渡す必要がありますが、これは「関心の分離」に準拠しておらず、ぼやけていると思いますMVC デザイン パターンの責任行 (もちろん、間違っている場合は訂正してください)。またHit、コントローラー自体にオブジェクトを作成する場合は、スキニー モデルとファット コントローラーを作成します。

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

後者の場合はテストがはるかに簡単になりますが (モデル仕様でリクエストをモックする必要はありません)、正しくないように思えます。

これに関するアドバイス - 大変感謝しています。

PSextract_data_from_request(req)メソッドは、必要に応じて適切な場所に配置されます。オブジェクトに必要な属性のハッシュを返しHitます。

4

2 に答える 2

3

個人的には、これらのことを考えすぎないように注意します。

ヒットの概念は、(HTTP) 要求の概念と同様に、Web サイトまたは Web アプリケーションと密接に結びついています。ファット コントローラーのアンチパターンは、モデルに簡単に抽出できるActiveRecord の find ステートメントとビジネス ロジック (多くの場合、if/ elsif/ブロックで特徴付けられる) を含む長いコントローラー アクションを持つことに関するものです。else

コントローラーには、特定のオーケストレーションの責任があります。1 つの中でオブジェクトを作成することは、凶悪な犯罪ではありません。結局のところ、私たちはcreate行動の中で常にそれを行っています。

于 2010-07-06T12:39:19.060 に答える
2

ええ、私はジョンに同意します。リクエストの概念は通常「コントローラーのこと」ですが、この場合、モデルはリクエストをモデリングしているため、この場合は間違いなくモデルの領域にあります。事実上、リクエスト オブジェクトがコントローラーからモデルへの境界を越えると、それは特別なプロパティを持たない単なる別のオブジェクトになります。もはや html リクエストを取得して応答するプロセスには関与しません。それは、あなたがやりたいことを何でもできるただのオブジェクトです。

ただし、気をつけなければならないことの 1 つは、Ruby では引数が参照によって渡されることです。つまり、モデルで操作しているリクエスト オブジェクトは、コントローラーで処理されているものと同じオブジェクトです。私は偏執的すぎるかもしれません (または単に間違っているかもしれません) が、実際のリクエスト自体ではなく、その複製をモデルに渡したいと思うかもしれません。すなわち

class LinksController < ApplicationController
  def hit
    link = Link.find(params[:id])
    link.hit!(request.dup)
  end
end
于 2010-07-06T14:14:54.413 に答える