postgresql 传递给#or 的关系必须在结构上兼容。不兼容的值:[:references]

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40742078/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 02:26:54  来源:igfitidea点击:

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

sqlruby-on-railspostgresqlactiverecordruby-on-rails-5

提问by frostbite

I have two queries, I need an orbetween them, i.e. I want results that are returned by either the first or the second query.

我有两个查询,我需要or在它们之间进行查询,即我想要第一个或第二个查询返回的结果。

First query is a simple where()which gets all available items.

第一个查询是一个简单的查询where(),它获取所有可用的项目。

@items = @items.where(available: true)

Second includes a join()and gives the current user's items.

第二个包括一个join()并给出当前用户的项目。

@items =
  @items
  .joins(:orders)
  .where(orders: { user_id: current_user.id})

I tried to combine these with Rails' or()method in various forms, including:

我尝试以or()各种形式将这些与 Rails 的方法结合起来,包括:

@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]

采纳答案by Andrey Deineko

There is a known issue about it on Github.

Github 上有一个关于它已知问题

According to this commentyou might want to override the structurally_incompatible_values_for_orto overcome the issue:

根据此评论,您可能想要覆盖structurally_incompatible_values_for_or以克服该问题:

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:

此外,总有一个选项可以使用 SQL:

@items
  .joins(:orders)
  .where(
    "orders.user_id = ? OR items.available = true",
    current_user.id
  )

回答by Rajdeep Singh

You can write the query in this good old way to avoid error

您可以用这种很好的旧方式编写查询以避免错误

@items = @items.joins(:orders).where("items.available = ? OR orders.user_id = ?", true, current_user.id)

Hope that helps!

希望有帮助!