使用Active Record,我如何获得随机未查看的文章?

时间:2015-02-08 20:00:26

标签: ruby-on-rails activerecord

我有一个Rails应用程序,它有几个模型:文章和UserArticleViews。

文章有文章ID。

UserArticleViews具有用户ID和文章ID,并且对应于查看过文章的用户。

这使用belongs_to和has_many。

是否有一种有效的方式来获取用户尚未看到的新文章。类似于:随机选择一篇文章,以便没有UserArticleView与user_id和article_id?

4 个答案:

答案 0 :(得分:0)

我建议使用ruby Array#sample方法获取随机文章(在应用程序中随机获取,而不是数据库,随机()级别在数据库级别有点慢):

viewed_article_ids = UserArticleView.where(user_id: user_in_question.id).pluck(:article_id)
random_article_id = (Article.pluck(:id) - viewed_article_ids).sample
Article.find(random_article_id)

答案 1 :(得分:0)

你也可以查看这样的随机记录

     offset = rand(Article.count)
     rand_record = Article.offset(offset).first

答案 2 :(得分:0)

请尝试以下单个查询

article = Article.join("LEFT JOIN user_article_views uav ON uav.article_id = articles.id AND uav.user_id = #{user_id}")
                 .where("uav.id IS NULL")
                 .order("random()")
                 .limit(1)

答案 3 :(得分:0)

我假设您有关联:

class User
  has_many :article_views
  has_many :articles, :through => :article views
end

class Article
  has_many :article_views
  has_many :users, :through => :article views
end

class ArticleViews
  belongs_to :user
  belongs_to :article
end

如果这是真的,那么我认为这将有效(@user实例方法):

def random_unread
  unviewed = false
  until unviewed
    @article = Article.offset(rand(Article.count)).first
    unviewed = true unless articles.include?(@article)
  end
  @article
end

这假设上述速度快于:

Article.all.select{|a| !articles.include?(a)}.sample