I'm trying to create a scope on an hstore column in my Rails app. Product is a model and features is an attribute of type hstore (using Postgresql 9.2). My class with scope is defined below:
class Product < ActiveRecord::Base
scope :with_features, lambda {|features| where("foo_id in (?)", features)
The above scope only works if you pass single values in as features. Arrays throw errors. This is illustrated below:
Product.with_features('api')
=> [#<Product id: 1, name: "Sample">]
# so great success
# now with an array
Product.with_features(['api','mobile'])
=> ActiveRecord::StatementInvalid: PG::Error: ERROR: argument of WHERE must be type boolean, not type record
# so no good, this query will work as usual if features isn't of type hstore
In Rails 3.2, it seems support for postgres hstore type is limited when arrays are involved (I'm using https://github.com/softa/activerecord-postgres-hstore). I've been trying some solutions with a each loop to append AND queries together, not much luck. Any ideas?
Here's one solution I came up with that works well:
scope :with_features, lambda { |features|
#store the composed scope in local variable to build on
composed_scope = self.scoped
# if array, then loop through each
if features.instance_of?(Array)
features.each do |feature|
composed_scope = composed_scope.where("features ? :key", :key => feature)
end
# otherwise, it's a single string parameter, parse as normal
else
composed_scope = composed_scope.where("features ? :key", :key => features)
end
# return the newly built composed scope
composed_scope
}
Now both example queries above return expected results.