Reputation: 25
i have to implement a query, not with string only i have to use hash like this
Products.where(:id != @product_id AND init_time <= ? AND (:section_id => @section_id OR :type_id => @type_id))
but i am getting errors in 'AND' 'OR' and how can i fix this part '!='?
Upvotes: 0
Views: 88
Reputation: 29573
We can produce this query using Hash
syntax alone but it is not as nice as I would like because you have to repeat conditions
For Example:
Products
.where(section_id: @section_id, init_time: ..[YOUR INIT TIME HERE])
.where.not(id: @product_id)
.or(
Products
.where(type_id: @type_id, init_time: ..[YOUR INIT TIME HERE])
.where.not(id: @product_id)
)
as pointed out by @3limin4t0r you could also use
Product
.where(section_id: @section_id)
.or(Product.where(type_id: @type_id))
.where(init_time: ..@init_time).where.not(id: @product_id)
Which is definitely cleaner but this query is order dependent so the where(condition1).or(condition2)
needs to be in the front of the chain to wrap the condition in parens appropriately.
Instead I would do so as follows:
Product.where.not(id: @product_id)
.where(init_time: ..[YOUR INIT TIME HERE])
.where(
Product.arel_table[:section_id].eq(@section_id).or(
Product.arel_table[:type_id].eq(@type_id))
)
Assuming
@product_id = 123
@section_id = 7
@type_id = 12
Both will produce:
SELECT
products.*
FROM
products
WHERE
products.id != 123
AND products.init_time <= [YOUR INIT TIME]
AND (products.section_id = 7 OR products.type_id = 12)
Upvotes: 3
Reputation: 1334
I agree with the above explanation of the query, but I would prefer a more compact query:
scope = Products.where(init_time: ..@your_time).where.not(id: @product_id)
scope.where(section_id: @section_id).or(scope.where(type_id: @type_id))
Upvotes: 1