我目前正在构建一个特性,它要求我在哈希上循环,并为哈希中的每个键动态修改一个sql查询。
实际的sql查询应该如下所示:
select * from space_dates d
inner join space_prices p on p.space_date_id = d.id
where d.space_id = ?
and d.date between ? and ?
and (
(p.price_type = 'monthly' and p.price_cents <> 9360) or
(p.price_type = 'daily' and p.price_cents <> 66198) or
(p.price_type = 'hourly' and p.price_cents <> 66198) # This part should be added in dynamically
)
最后 and
查询是动态添加的,如您所见,我基本上只需要其中一个条件为真,而不是所有条件。
query = space.dates
.joins(:price)
.where('date between ? and ?', start_date, end_date)
# We are looping over the rails enum (hash) and getting the key for each key value pair, alongside the index
SpacePrice.price_types.each_with_index do |(price_type, _), index|
amount_cents = space.send("#{price_type}_price").price_cents
query = if index.positive? # It's not the first item so we want to chain it as an 'OR'
query.or(
space.dates
.joins(:price)
.where('space_prices.price_type = ?', price_type)
.where('space_prices.price_cents <> ?', amount_cents)
)
else
query # It's the first item, chain it as an and
.where('space_prices.price_type = ?', price_type)
.where('space_prices.price_cents <> ?', amount_cents)
end
end
rails中的输出是:
SELECT "space_dates".* FROM "space_dates"
INNER JOIN "space_prices" ON "space_prices"."space_date_id" = "space_dates"."id"
WHERE "space_dates"."space_id" = $1 AND (
(
(date between '2020-06-11' and '2020-06-11') AND
(space_prices.price_type = 'hourly') AND (space_prices.price_cents <> 9360) OR
(space_prices.price_type = 'daily') AND (space_prices.price_cents <> 66198)) OR
(space_prices.price_type = 'monthly') AND (space_prices.price_cents <> 5500)
) LIMIT $2
这和预期的不一样。为了产生相同的输出,我需要将最后几行放在另一组圆括号中。我不知道如何使用activerecord。
我不可能用 find_by_sql
因为这也是动态生成的sql。
1条答案
按热度按时间qlfbtfca1#
所以,我用arel和rails在一个小时内解决了这个问题
sql输出为:
我最后做的是:
基于枚举键和
price_cents
减少子句并使用or
使用and
操作员和combined_clauses