Ruby on rails 我如何创建一个activerecord作用域以返回以下客户';他的下一次访问导致了一次购买
我有三个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作用域或类方法,使我
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