如何在ActiveRecord中的关联表上使查询成为条件

时间:2019-05-14 00:11:00

标签: ruby-on-rails activerecord

我正在尝试创建一个查询,该查询将根据关联表中的条件从一个表返回不同的记录。

具体来说,有一个Act模型具有has_many Events,当然,“事件”属于Act,我想找到那些没有{ Acts在特定日期。

查询需要以Event条件运行,否则结果将不会排除任何not记录。

我尝试了多种构造,包括在类方法之间使用合并,但是没有用。

Act
#Act model
def self.busy_on(date)
    joins(:event).merge.not(Event.busy_on(date))
end
#Event model
def self.busy_on(date)
    where(date: date)
end

上面给了我一个参数错误(期望值1为0),但我不确定它是否正确。

4 个答案:

答案 0 :(得分:1)

不确定这是最优雅或“正确”的方法,但这是我唯一能做的事情:

#Event model
def self.act_busy_on(date)
    where(date: date).pluck(:act_id)
  end
#Act model
def self.available_on(date)
    where.not(id: Event.act_busy_on(date))
  end
#Controller
Act.available_on(params[:date])

答案 1 :(得分:0)

class Act < ApplicationRecord
  def self.busy_on(date)
    #includes(:events).where(events: {created_at: date, id: nil })
   includes(:events).where("events.created_at = ? AND events.id = ?", date, nil)
  end
end

答案 2 :(得分:0)

首先,您需要在联接查询中将event修改为events

您要求Acts在问题的特定日期是免费的,以便查询,

def get_acts(date)
    includes(:events).where('events.date = ? and events.id = ?', date, nil)
end

现在,如果您致电Act.get_acts(26-05-2019),将为您提供当天的免费表演。

答案 3 :(得分:0)

这是我推荐的解决方法。

我们将为忙碌和可用的情况创建倒置范围

class Act < ApplicationRecord
   has_many :events 

   scope :busy_on, ->(date) { joins(:events).where(events: {date: date}) }
   scope :available_on, ->(date) {where.not(id: busy_on(date).select(:id))}
end 

在这里,我们为Act忙碌的日子创建一个范围,然后使用该范围作为计数器过滤器来确定该行为是否可用。 用于busy_on范围的SQL将会是:

  SELECT 
     acts.* 
  FROM 
     acts
     INNER JOIN events ON acts.id = events.act_id
  WHERE 
     events.date = [THE DATE YOU PASS INTO THE SCOPE]

因此,available_on范围的结果SQL将是:

 SELECT 
   acts.* 
 FROM 
   acts 
 WHERE 
   acts.id NOT IN ( 
      SELECT 
         acts.id
      FROM 
         acts
         INNER JOIN events ON acts.id = events.act_id
      WHERE 
         events.date = [THE DATE YOU PASS INTO THE SCOPE]
   )