Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have a tagging system in rails using postgres' array data type. I'm trying to write a scope that will return any posts that include a tag. So far I have this scope working:

scope :with_tag, ->(tag) { where("tags @> ARRAY[?]", tag) }

I want to extend this scope so that I can query on multiple tags at the same time, ideally something like:

Post.with_tags(['some', 'tags', 'to', 'query'])

Which would return any Post that have one of those tags. I've thought about making a class method to handle iterating over the input array:

def self.with_tags(args)
  # start with empty activerecord relation
  # want to output AR relation
  results = Post.none
  args.each do |tag|
    results = results.concat(Post.with_tag(tag))
  end
  results.flatten
end

but this approach smells funny to me because it's creating a new query for each argument. It also doesn't return an ActiveRecord::Relation because of flatten, which I would really like to have as the output.

Can I accomplish what I'm after in a scope with an OR query?

share|improve this question
1  
You're really trying to do an array intersection right? You have an array of strings in the tags column and an array of strings in the Ruby args variable and you want rows where those arrays overlap? –  mu is too short yesterday
    
Yes, I think. Except I want all of the tags that contain any of the values in args, they do not need to match all of the args –  user2936314 yesterday

1 Answer 1

up vote 1 down vote accepted

I'm not running the code but I think the && operator does what you want:

scope :with_tags, ->(tags) { where("tags && ARRAY[?]", tags) }
share|improve this answer
    
yes it does! http://www.postgresql.org/docs/9.4/static/functions-array.html –  user2936314 yesterday

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.