Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 我如何创建一个activerecord作用域以返回以下客户';他的下一次访问导致了一次购买_Ruby On Rails_Activerecord_Scopes_Database Relations - Fatal编程技术网

Ruby on rails 我如何创建一个activerecord作用域以返回以下客户';他的下一次访问导致了一次购买

Ruby on rails 我如何创建一个activerecord作用域以返回以下客户';他的下一次访问导致了一次购买,ruby-on-rails,activerecord,scopes,database-relations,Ruby On Rails,Activerecord,Scopes,Database Relations,我有三个activerecord模型:客户、访问和活动 Customer has_many :visits Visit belongs_to :customer Campaign has_many :visits 访问模型跟踪特定客户每次访问网站、访问页面、显示广告的时间,最重要的是他们是否进行了购买。活动是客户在访问网站时看到的一系列广告。每个活动持续1小时(每天24个活动),并有多次访问 我想做的是开发一些activerecord作用域或类方法,使我

我有三个activerecord模型:客户、访问和活动

Customer    has_many   :visits
Visit       belongs_to :customer
Campaign    has_many   :visits    
访问模型跟踪特定客户每次访问网站、访问页面、显示广告的时间,最重要的是他们是否进行了购买。活动是客户在访问网站时看到的一系列广告。每个活动持续1小时(每天24个活动),并有多次访问

我想做的是开发一些activerecord作用域或类方法,使我能够识别“下次访问购买”

例如,在7月4日,当天的第四个活动有100名客户访问。我希望能够查看每个客户的下一次访问,并确定在下一次访问中进行了购买的访问/客户。我发现很难理解的是,客户随后的访问并非都在同一天,但我想确定“下一次访问”和导致购买的访问

我所设想的是:

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

我在访问模型中有一个购买标志,因此购买范围相当简单

scope, :purchase, where(:purchase_flag => true)
同样基于,如果我在访问模型上创建此范围,那么我可以使用联接和合并将其应用于客户和活动模型

Campaign.joins(:visits).merge(Visit.purchase)
这是正确的方法吗?如果是,我如何定义我的下一个范围,如果不是,你会建议什么作为替代方法

更新
我得到了一些很好的回应。我只是想知道大家是否普遍认为Deepak的方法是正确的,还是其他的回答更可取。

我认为范围在这里不是正确的,因为你需要在一个对象上调用它。您可以在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

我不认为作用域在这里是正确的,因为你需要在一个对象上调用它。您可以在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

在当前的数据库结构中,实现所需的功能非常笨拙,而且效率也可能非常低

我对这个问题有不同的看法:

  • 当进行购买时-这是了解导致此次购买的活动/访问(检查用户的上次访问并查找活动)的最佳机会
  • 要捕获这些信息,请使用自定义名称在活动和访问之间创建适当的关系
  • 在适当模型的“保存后/创建后”回调中填充这些内容(最有可能是购买或访问)

一旦以上述方式捕获数据,查询就相对容易了。

在当前的数据库结构中,实现所需的功能非常笨拙,而且可能效率也非常低

我对这个问题有不同的看法:

  • 当进行购买时-这是了解导致此次购买的活动/访问(检查用户的上次访问并查找活动)的最佳机会
  • 要捕获这些信息,请使用自定义名称在活动和访问之间创建适当的关系
  • 在适当模型的“保存后/创建后”回调中填充这些内容(最有可能是购买或访问)

一旦以上述方式捕获了数据,查询就相对容易了。

因此,您需要的是测量活动的效率,并获得有关活动结束后回来并进行购买的客户的数据

我提议:

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)。下一次访问

编辑

您应该对变量
使用正确的TZ,因为

关于
@next|u访问|=开始。。。结束
:这是一种缓存技术。第一次调用该方法时,将执行
begin
blok中的所有代码,结果(记录)将存储在实例变量@next_visions中,并返回给调用者

下次调用该方法时,@Next_visions中的缓存结果将直接返回,而不会命中数据库。这对性能有好处


有关这方面的更多信息,因此您需要的是衡量活动的效率,并获得有关活动结束后回来并进行购买的客户的数据

我提议:

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)。下一次访问

编辑

您应该对变量
使用正确的TZ,因为

关于
@next|u访问|=开始。。。结束
:这是一种缓存技术。第一次调用该方法时,将执行
begin
blok中的所有代码,结果(记录)将存储在实例变量@next_visions中,并返回给调用者

下次调用该方法时,@Next_visions中的缓存结果将直接返回,而不会命中数据库。这对性能有好处


关于这方面的更多信息

因此,不可能有第三个范围将其延伸到特定的访问,然后应用下一次访问和购买范围:Visit.number(100)。Next_Visit.purchase或者它是否真的是一个范围很重要。我认为范围可能提供更多的灵活性和链接选项。在所有情况下,感谢您的响应。如果您希望
next_visit
只返回一个访问对象,那么将方法链接到它上是没有意义的。如果您想检索多个
下次访问
,只需从我的回答中删除
。首先
呼叫和
限制
,您将获得一个活动关系对象,该对象将是可链接的,因此不可能有第三个作用域将其向下延伸到特定的访问,然后应用下一个访问和购买作用域:Visit.nu