我有一个模型(配对),它有一个长度和日期属性(除其他外)。我试图查询所有不触及特定日期或日期范围的配对,同时匹配配对的其他属性。所有其他查询的代码运行良好,但我的where.not排除了所有记录。这是因为(我认为)我构建关系/查询的方式。
我需要的东西,排除选定的日期范围和匹配长度。这需要在其他作用域查询上堆叠。
对如何做到这一点有什么想法吗?
提前感谢!
控制器代码:
rel = rel.other scoped queries
@all_trip_len.each do |len|
rel = rel.date_selector(@date_sel_1, @date_start_1, @date_end_1, len)
end
rel = rel.more scoped queries示范范围:
def self.date_selector(sel, start_d, end_d, length)
# Need to get all possible start dates that could touch avoid days for each length of trip
rel = self
start = Date.parse(start_d) - (length.to_i - 1)
rel = rel.where.not(date: start.to_s..Date.parse(end_d).to_s).where(length: length)
return rel
end我正在收到一个查询,即:
SELECT "pairings".*
FROM "pairings"
WHERE "pairings"."bid_month_id" = $1
AND NOT ("pairings"."date" BETWEEN $2 AND $3)
AND "pairings"."length" = $4
AND NOT ("pairings"."date" BETWEEN $5 AND $6)
AND "pairings"."length" = $7 [["bid_month_id", 8], ["date", "2020-04-08"], ["date", "2020-04-08"], ["length", 1], ["date", "2020-04-07"], ["date", "2020-04-08"], ["length", 2]我需要更像:
SELECT "pairings".*
FROM "pairings"
WHERE "pairings"."bid_month_id" = $1
AND NOT (("pairings"."date" BETWEEN $2 AND $3)
AND "pairings"."length" = $4)
AND NOT (("pairings"."date" BETWEEN $5 AND $6)
AND "pairings"."length" = $7) [["bid_month_id", 8], ["date", "2020-04-08"], ["date", "2020-04-08"], ["length", 1], ["date", "2020-04-07"], ["date", "2020-04-08"], ["length", 2]编辑:
在MurifoX的帮助下,我走得更远了。查询的构建几乎是正确的,但我需要在pairing.date分组之间使用OR。
我现在拥有的是:
SELECT "pairings".*
FROM "pairings"
WHERE "pairings"."bid_month_id" = $3
AND (((date <= '2020-04-06' AND date >= '2020-04-07') AND length = 1))
AND (((date <= '2020-04-05' AND date >= '2020-04-07') AND length = 2))我需要的是:
SELECT "pairings".*
FROM "pairings"
WHERE "pairings"."bid_month_id" = $3
AND (((date <= '2020-04-06' AND date >= '2020-04-07') AND length = 1)
OR ((date <= '2020-04-05' AND date >= '2020-04-07') AND length = 2))我试过使用rails 5或(rel.or(Pairing.date_selector(xxx)),但这不起作用,因为它将所有where和into转换为or,我只需要配对/日期分组之间的OR。还需要在日期分组周围的父母。
发布于 2020-03-03 22:45:57
最后,我不得不把它构建成一个字符串来让它完全按照我的意愿去做。rails 5中的or relation创建了一条语句,其中OR用新子句(all和-> OR)处理了我以前所有的scope子句,我需要所有以前的作用域查询都保持不变,并且只需要新的日期。
def exclude_dates(rel, date_start_1, date_end_1, all_trip_len)
dates_query = String.new
count = 0
all_trip_len.each do |len|
start_d = Date.parse(date_start_1) - (len.to_i - 1)
end_d = Date.parse(date_end_1)
count += 1
dates_query += " OR " if count > 1
dates_query += "((date < '#{start_d.to_s}' OR date > '#{end_d.to_s}') AND length = '#{len}')"
end
rel = rel.where(dates_query)
end这就创建了我需要的查询。希望有更多的“rails”方式来做这件事..。
SELECT COUNT(*) FROM "pairings" WHERE "pairings"."bid_month_id" = $1 AND (((date < '2020-04-02' OR date > '2020-04-02') AND length = '1') OR ((date < '2020-04-01' OR date > '2020-04-02') AND length = '2') OR ((date < '2020-03-31' OR date > '2020-04-02') AND length = '3') OR ((date < '2020-03-30' OR date > '2020-04-02') AND length = '4')) AND (((date < '2020-04-14' OR date > '2020-04-17') AND length = '1') OR ((date < '2020-04-13' OR date > '2020-04-17') AND length = '2') OR ((date < '2020-04-12' OR date > '2020-04-17') AND length = '3') OR ((date < '2020-04-11' OR date > '2020-04-17') AND length = '4')) [["bid_month_id", 8]]感谢@MurifoX让我在约会的事情上走到正确的方向!
发布于 2020-03-03 18:26:43
使用ActiveRecord方法构造半复杂查询有时会很棘手,因此在这种特殊情况下,我总是告诉人们手工进行查询:
rel = self
start = Date.parse(start_d) - (length.to_i - 1)
rel = rel.where("((date <= ? AND date >= ?) AND length = ?)", start.to_s, Date.parse(end_d).to_s, length)
return relhttps://stackoverflow.com/questions/60513296
复制相似问题