Question

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?

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top