获取日期早于当前日期的所有作业,并按用户和每个作业的评论数进行过滤

时间:2019-03-26 11:57:08

标签: ruby-on-rails activerecord

我需要获取日期早于当前日期的属于当前用户的所有作业,并且还需要过滤评论为零的作业。

我尝试了以下操作:

Job.joins(:user, :review).where("jobs.date < ? AND jobs.status = ? AND users.id = ?", Time.now, 3 , user.id).group("jobs.id").having("COUNT(reviews) = ?", 0)

在使用特定用户ID(3356)的情况下,我应该获得一份工作,但没有得到。

这是我的模特

class Job < ActiveRecord::Base
  belongs_to :user
  has_one :review
end

class User < ActiveRecord::Base
  has_many :jobs
  has_one :reviews
end

class Review < ActiveRecord::Base
  belongs_to :job
  belongs_to :user
end

status是一个枚举(必须为3,即为“已接受”)

我在做什么错?我不确定如何正确构造SQL,所以这可能是问题所在。感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

您需要执行左外部联接,而不是内部联接,如果您进行内部联接,则如果具有0条评论,则该任务将不起作用。作业必须至少具有一条评论,然后才可以记录该任务的记录,此外,在左外部加入后,将记录所有作业是否经过审查。

Job.left_outer_joins(:user, :reviews).where("jobs.date < ? AND jobs.status = ? AND users.id = ?", Time.now, 3 , user.id).group("jobs.id").having("COUNT(reviews) = ?", 0)

答案 1 :(得分:1)

joins(:review)将执行Job和Review的内部联接,这将导致结果中跳过0条评论的作业。 试试这个:

Job.joins(:user).joins("left join reviews on reviews.job_id = jobs.id ").where("jobs.date < ? AND jobs.status = ? AND users.id = ?", Time.now, 3 , user.id).group("jobs.id").having("COUNT(reviews) = ?", 0)

答案 2 :(得分:1)

我喜欢思考这样的问题的一种方法是将它们分解为较小的问题。

根据您的问题,我们希望...

获取所有作业:

  • 具有“接受”状态
Job.accepted
  • 属于当前用户
Job.where(user: current_user)
  • 日期早于今天的日期
Job.where('date < ?', Time.zone.today)
  • 评论为零
reviews = Review.all
Job.where.not(id: reviews.select(:job_id))

此人与其他人稍有不同,使用的是subquery


现在,让我们将所有这些放在一起,并在Job类中定义一个方法:

class Job < ApplicationRecord
  enum status: [:other_status, :accepted]
  belongs_to :user
  has_one :review

  def self.unreviewed(user)
    accepted
      .where(user: user)
      .where('date < ?', Time.zone.today)
      .where.not(id: Review.select(:job_id))
  end
end

这将生成以下SQL:

irb(main):002:0> puts Job.unreviewed(user).to_sql
SELECT "jobs".* FROM "jobs" WHERE "jobs"."status" = 0 AND "jobs"."user_id" = 1 AND (date < '2019-03-26') AND "jobs"."id" NOT IN (SELECT "reviews"."job_id" FROM "reviews")

您还可以找到some specs testing this here