1

I'd like to build a query builder using squeel, here is how I did:

Parent class:

module ModelFilters
  class Base
    def initialize(user)
      @user = user
    end

    def build(method_name)
      head.where { my { send(method_name) } }
    end

    protected

    def head
    end
  end
end

Child class:

module ModelFilters
  class Collection < Base
    def __showable__
      not_private | author
    end

    protected

    def head
      ::Collection.joins(:collaborators)
    end

    private

    def not_private
      is_private == false
    end

    def author
      user_id == @user.id
    end
  end
end

And finally my call:

a = ModelFilters::Collection.new(user)
a.build(:__showable__)

Actually my problem is that I don't know how Squeel work for innested query, my actual error is undefined local variable or method 'is_private' (obviously).

Is there a way to build something like this using Squeel (or other ActiveRecord query builder)?

Thank you all!

Rowandish
  • 2,655
  • 3
  • 31
  • 52

1 Answers1

2

What if you do:

module ModelFilters
  class Base
    def initialize(user)
      @user = user
    end

    def build(method_name)
      head.where { |q| send(method_name, q) }
    end

    protected

    def head
    end
  end
end

module ModelFilters
  class Collection < Base
    def __showable__(q)
      not_private(q) | author(q)
    end

    protected

    def head
      ::Collection.joins(:collaborators)
    end

    private

    def not_private(q)
      q.is_private == false
    end

    def author(q)
      q.user_id == @user.id
    end
  end
end
apneadiving
  • 114,565
  • 26
  • 219
  • 213
  • Thank you for your answer, it seems very close to the right solution but actually I get the following error: `PG::UndefinedColumn: ERROR: column collections.my does not exist`. – Rowandish Jan 16 '15 at 10:00
  • :) never used squeel before, is the my block really necessary? Could you try without it? – apneadiving Jan 16 '15 at 10:01
  • `my` is used to call instance methods inside the `where` block. I tryed in this way and now everything works: `head.where { |q| send(method_name, q) }`. You can edit your answer and I'll accept it :) – Rowandish Jan 16 '15 at 10:15