我正在尝试创建一个查询,该查询将根据关联表中的条件从一个表返回不同的记录。
具体来说,有一个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),但我不确定它是否正确。
答案 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]
)