Rails每天都会显示不同的对象

时间:2013-10-22 04:44:49

标签: sql ruby-on-rails ruby postgresql activerecord

我想每天将我的用户与他/她社区中的其他用户匹配。目前,我使用这样的代码:

@matched_user = User.near(@user).order("RANDOM()").first

但我希望每天都有一个不同的@matched_user。我无法在Stack或API中找到任何能让我了解如何操作的内容。我觉得它应该比使用cron求助于rake任务更简单。 (我在postgres上。)

3 个答案:

答案 0 :(得分:4)

每当我发现自己渴望共享“记忆”时或者是暂时状态,我认为自己"这就是(分布式)缓存是为#34发明的。

@matched_user = Rails.cache.fetch(@user.cache_key + '/daily_match', expires_in: 1.day) {
  User.near(@user).order("RANDOM()").first
}

注意:为缓存条目指定TTL时,Rails /缓存系统会尝试在给定的时间范围内保留该值,但是 NO 保证。特别是,积极尝试回收内存的缓存可能会在其所需的expires_in时间之前到达一个条目。

对于这个特定的用例,它不应该是一个大问题但是在业务/域逻辑要求定期生成持久的值的情况下你真的必须将它纳入你的数据库。

答案 1 :(得分:1)

如何使用PostgreSQL的SETSEED函数?我用日期来播种,这样每天种子都会改变,但是在一天之内,种子就会一致。:

User.connection.execute "SELECT SETSEED(#{Date.today.strftime("%y%d%m").to_i/1000000.0})"
@matched_user = User.near(@user).order("RANDOM()").first

你可能想在使用它之后播种随机值,这样以后对随机的任何调用都不会有偏见:

random = User.connection.execute("SELECT RANDOM()").to_a.first["random"]
# Same code as above:
User.connection.execute "SELECT SETSEED(#{Date.today.strftime("%y%d%m").to_i/1000000.0})"
@matched_user = User.near(@user).order("RANDOM()").first
# Use random value before seed to make new seed:
User.connection.execute "SELECT SETSEED(#{random})"

答案 2 :(得分:1)

为了便于阅读,我在不同的部分拆分了这些步骤。您可以稍后优化查询。

1)查找所有用户记录直至今天上午。这样计数就会冻结。

usrs_till_today_morning = User.where("created_at <?", DateTime.now.in_time_zone(Time.zone).beginning_of_day)

2)拨打所有ID

user_ids = usr_till_today_morning.pluck(:id)

3)今天的日期是一个范围(1..30),但会在一天内保持不变。

day_today = Time.now.day

4)选择当天的相同ID

todays_user_id = user_ids[day_today % user_ids.count]

@matched_user =  User.find(todays_user_id)

所以它会通过在一天内保持相同记录来为您提供随机用户记录!!