Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
453 views
in Technique[技术] by (71.8m points)

sql - Relation passed to #or must be structurally compatible. Incompatible values: [:references]

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]
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...