Alfie
Alfie

Reputation: 2784

acts_as_taggable_on multiple fields query using an OR

So i’m trying to write a query to fetch users based on the skills they have, the implementation goes like this :

A user has primary and secondary skills, both using acts_as_taggable_on

this is the scope i’ve got now

scope :by_skills, (lambda do |primary, secondary|
  if primary.present? && secondary.present?
    tagged_with(primary, on: :primary_skills, any: true)
      .tagged_with(secondary, on: :secondary_skills, any: true)
  elsif primary.present?
    tagged_with(primary, on: :primary_skills, any: true)
  elsif secondary.present?
    tagged_with(secondary, on: :secondary_skills, any: true)
  end
end)

problem with this now is that if both primary & secondary is present, the query fired would be an AND i.e primary and secondary, I’d like it to be an OR, and in no way am i able to figure that out

Upvotes: 1

Views: 149

Answers (2)

Alfie
Alfie

Reputation: 2784

I did end up using the or method of ActiveRecord which was introduced in Rails 5 as mentioned by @archana.

But before i got to using that i tried to find out another way to do the same, and looked a bit into how acts_as_taggable_on is designed.

So even if there are two different associations called as primary_skills & secondary_skills both are indeed an association with the same table tags with a through table taggings

That means the users table has an association with tags table, figuring that out everything was clearer now. The solution goes like this :

Users.includes(:primary_skills, :secondary_skills).where(tags: { name: (primary + secondary) })

This would work for all rails versions where acts_as_taggable_on is supported.

Upvotes: 0

archana
archana

Reputation: 1272

Try or introduced in Rails 5.

scope :by_skills, (lambda do |primary, secondary|
  if primary.present? && secondary.present?
    tagged_with(primary, on: :primary_skills, any: true).or(
      tagged_with(secondary, on: :secondary_skills, any: true))
  elsif primary.present?
    tagged_with(primary, on: :primary_skills, any: true)
  elsif secondary.present?
    tagged_with(secondary, on: :secondary_skills, any: true)
  end
end)

Upvotes: 2

Related Questions