web-dev-qa-db-ja.com

#orに渡される関係は、構造的に互換性がなければなりません。互換性のない値:[:references]

2つのクエリがあり、それらの間にorが必要です。つまり、最初のクエリまたは2番目のクエリのいずれかによって返される結果が必要です。

最初のクエリは、使用可能なすべてのアイテムを取得する単純なwhere()です。

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

2番目はjoin()を含み、現在のユーザーのアイテムを提供します。

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

これらをRailsのor()メソッドとさまざまな形式で組み合わせてみました:

_@items =
  @items
  .joins(:orders)
  .where(orders: { user_id: current_user.id})
  .or(
    @items
    .joins(:orders)
    .where(available: true)
  )
_

しかし、私はこのエラーに遭遇し続け、それを修正する方法がわかりません。

_Relation passed to #or must be structurally compatible. Incompatible values: [:references]
_
20
frostbite

Githubでの既知の問題 があります。

このコメント によると、 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

また、SQLを使用するオプションが常にあります。

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

エラーを避けるために、この古き良き方法でクエリを書くことができます

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

お役に立てば幸いです!

8
Rajdeep Singh