0

Customer、Visit、Campaign の 3 つの ActiveRecord モデルがあります。

Customer    has_many   :visits
Visit       belongs_to :customer
Campaign    has_many   :visits    

訪問モデルは、特定の顧客が Web サイトを訪問するたびに、訪問したページ、表示された広告、そして最も重要な購入を行ったかどうかを追跡します。キャンペーンは、サイトへの訪問中に顧客が見る一連の広告です。各キャンペーンは 1 時間続き (1 日 24 キャンペーン)、多くの訪問者がいます。

私がやろうとしているのは、「次の訪問の購入」を識別できるようにするアクティブレコードスコープまたはクラスメソッドを開発することです。

たとえば、7 月 4 日の 4 回目のキャンペーンでは、100 回の顧客訪問がありました。私は、それらの各顧客の次の訪問を見て、その次の訪問で購入した/購入した訪問/顧客を識別できるようにしたいと考えています. 私が理解するのが難しいと感じているのは、顧客のその後の訪問がすべて同じ日にあるわけではありませんが、「次の訪問」と購入につながったものを特定したいということです。

私が想像したのは次のようなものです:

Campaign.find(2232).next_visit.purchase     #where next_visit and purchase are scopes

また

Visit.find(5445).next_visit.purchase 

訪問モデルに購入フラグがあるので、購入スコープはかなり単純です。

scope, :purchase, where(:purchase_flag => true)

また、 Railscast #215に基づいて、訪問モデルでこのスコープを作成すると、結合とマージを使用してそれらを Customer モデルと Campaign モデルに適用できます。

Campaign.joins(:visits).merge(Visit.purchase)

これは正しいアプローチですか?もしそうなら、私はどのように私の次のスコープを定義しますか? そうでない場合は、代替アプローチとして何を提案しますか.

更新: 素晴らしい回答をいくつか得ました。一般的なコンセンサスが、Deepak のアプローチが適切であるということなのか、それとも他の応答が望ましいということなのかを知りたいだけです。

4

3 に答える 3

2

オブジェクトでスコープを呼び出す必要があるため、ここではスコープが正しいとは思いません。これは、visit.rb のメソッドとして実装できます。

次のようになります。

def next_visit
  Visit.where(['date > ?', self.date]).order(:date).limit(1).first
end

編集: メソッドをチェーンできるようにする

def next_visits
  Visit.where(['date > ?', self.date])
end
于 2013-07-18T12:15:23.823 に答える
1

したがって、キャンペーンの効率を測定し、キャンペーン後に戻ってきて購入した顧客に関するデータを取得する必要があります。

私が提案する:

class Campaign

  def next_visits
    # Wrapping the whole code of this method in @next_visits will perform local caching
    # There is a good railscast that explain it in details (5 minutes long video)
    # You can see it there: http://railscasts.com/episodes/1-caching-with-instance-variables
    @next_visits ||= begin
      # This will be the starting date of "next visits"
      since = self.end_of_campaign # I assume you can get the TimeDate of the end of campain

      # List of ids of customers that participated to the campaign
      customers_ids = self.visits.uniq(:customer_id).pluck(:customer_id)

      # Return the visit records
      next_visits = Visit.where(purchase_flag: true, customer_id: customers_ids)
      next_visits.where('created_at > ?', since).first
    end
  end

end

それからあなたは電話しますCampaign.find(123).next_visits

編集

変数で正しい TZ を使用する必要がありますsince

概要@next_visits ||= begin ... end: これはキャッシング技術です。メソッドを初めて呼び出すと、ブロック内のすべてのコードbeginが実行され、結果 (レコード) がインスタンス変数 @next_visits に格納され、呼び出し元に返されます。

次回このメソッドを呼び出すと、@next_visits に保存されたキャッシュされた結果が、データベースにアクセスすることなく直接返されます。それはパフォーマンスに適しています。

その詳細についてはhttp://railscasts.com/episodes/1-caching-with-instance-variables

于 2013-07-25T01:03:15.107 に答える
1

現在のデータベース構造では、必要なものを達成するのは非常に不器用であり、おそらく非常に非効率的です.

この問題には別のアプローチがあります。

  • 購入が行われたとき - どのキャンペーン/訪問 (ユーザーの最後の訪問を確認し、キャンペーンを見つける) がこの購入につながったかを知る絶好の機会です。
  • これらの情報を取得するには、キャンペーンと訪問の間にカスタム名を使用して適切な関係を作成します。
  • これらを適切なモデル (ほとんどの場合、購入または訪問) の after_save/after_create コールバックに入力します。

上記の方法でデータが取得されると、クエリは比較的簡単になります。

于 2013-07-21T16:41:08.340 に答える