Neil
Neil

Reputation: 5178

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

I have two scopes in a model. Both utilize joins. It appears that joins is incompatible with the Rails 5 or query.

Example:

class Blog < ApplicationRecord

  has_many :comments

  scope :with_comment_likes, -> {joins(:comments).merge(Comment.some_scope_on_comment)}
  scope :some_other_comment_merge_scope, -> {joins(:comments).merge(Comment.other_scope)}

  scope :aggregate_or_scope, -> {with_comment_likes.or(some_other_comment_merge_scope)}
end

Blog.aggregate_or_scope

Returned error:

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

Any suggestions for how to get around this? I'm stumped. I did see this question, but I was having trouble applying it.

Upvotes: 9

Views: 2110

Answers (3)

Aditya Joardar
Aditya Joardar

Reputation: 594

After much trails. Here is the working solution:

def self.aggregate_or_scope
  with_comment_likes_id = with_comment_likes.pluck(:id)
  some_other_comment_merge_scope_id = some_other_comment_merge_scope.pluck(:id)
  all_ids = with_comment_likes_id.concat(some_other_comment_merge_scope_id)
  
  Blog.where(id: all_ids)
end

Upvotes: 0

Pat McGee
Pat McGee

Reputation: 379

Two years late to the party but here is the way you could accomplish this:

class Blog < ApplicationRecord

  has_many :comments

  scope :aggregate_or_scope, lambda {
    joins(:comments).merge(
      Comment.some_scope_on_comment.or(Comment.other_scope)
    )
  }
end

Blog.aggregate_or_scope

The difference here is that you are only joining once and the or is on the Comment query being merged which does not have any joins, rather than the Blog query which does.

Upvotes: 3

I was having this same issue, and the solution I found out was:

def matching_one_or_two temp = Model.matching_one + Model.matching_two Model.where('id in (?)',temp.map(&:id)) end

Certainly not the world's greatest performance, but it results in an ActiveRecord::Relation object pointing at the 'OR' results.

Upvotes: 1

Related Questions