I have two queries, I need an or
between them, i.e. I want results that are returned by either the first or the second query.
First query is a simple where()
which gets all available items.
@items = @items.where(available: true)
Second includes a join()
and gives the current user’s items.
@items = @items .joins(:orders) .where(orders: { user_id: current_user.id})
I tried to combine these with Rails’ or()
method in various forms, including:
@items = @items .joins(:orders) .where(orders: { user_id: current_user.id}) .or( @items .joins(:orders) .where(available: true) )
But I keep running into this error and I’m not sure how to fix it.
Relation passed to #or must be structurally compatible. Incompatible values: [:references]
Advertisement
Answer
There is a known issue about it on Github.
According to this comment you might want to override the structurally_incompatible_values_for_or
to overcome the issue:
def structurally_incompatible_values_for_or(other) Relation::SINGLE_VALUE_METHODS.reject { |m| send("#{m}_value") == other.send("#{m}_value") } + (Relation::MULTI_VALUE_METHODS - [:eager_load, :references, :extending]).reject { |m| send("#{m}_values") == other.send("#{m}_values") } + (Relation::CLAUSE_METHODS - [:having, :where]).reject { |m| send("#{m}_clause") == other.send("#{m}_clause") } end
Also there is always an option to use SQL:
@items .joins(:orders) .where("orders.user_id = ? OR items.available = true", current_user.id)