Search code examples
rubydatabasesequel

Sequel add a 'scope' according to a conditional


The code goes like this:

class Foo < Sequel::Model
  self.dataset_module do
    def property_active
      where('properties @> \'{"active": true}\'')
    end
  end
end

class Bar
  def foo_ids
    Foo.select(:other_model_id).distinct.all
  end

  def condition?
    ...
  end
end

I want to modify the foo_ids method to add the scope property_active depending o the condition? method. So far I come up with this:

Foo.select(:other_model_id).where{ Foo.property_active if condition? }.distinct

And it returns:

# when condition? is true
=> "SELECT DISTINCT \"other_model_id\" FROM \"foos\" WHERE (SELECT * FROM \"foos\" WHERE (properties @> '{\"active\": true}'))"

# when condition? is false
=> "SELECT DISTINCT \"other_model_id\" FROM \"foos\""

The code is good, but I don't like the idea of having that SELECT after the WHERE, is there a way to return a nice query for the true case? something like:

"SELECT DISTINCT \"other_model_id\" FROM \"foos\" WHERE (properties @> '{\"active\": true}')"

Solution

  • I'm not too familiar with the way Sequel handles chaining and scopes, but this is how I would approach it with the way ActiveRecord handles this. Does this work?

    class Bar
      def foo_ids
        scope = Foo.select(:other_model_id)
        scope = scope.property_active if condition?
        scope.distinct.all
      end
    end