granite icon indicating copy to clipboard operation
granite copied to clipboard

Support select in query builder

Open Serdnad opened this issue 4 years ago • 2 comments

I'd like to be able to do this (like in ActiveRecord):

User.select(:name)

From #215 and the docs, it seems like it's possible to specify a custom SELECT at the model level, but I'd like to be able to do this at the query level. As far as I can tell (it's been a while) ActiveRecord returns an instance of the model with only the selected fields populated, but personally I think this would be very useful even if it only returned an array, or, in the case of multiple columns, an array of hashes.

Willing to look into this myself and open a PR if this is straightforward enough + wanted, though I also noticed an open PR about ModelViews from some time ago.

Serdnad avatar Sep 06 '20 00:09 Serdnad

I have faced with the same issue, and as a workaround I decided to build custom sql query in my controllers, like the following one:

    query = Granite::Select::Container.new(
      custom: <<-SQL
        SELECT id, name, round(word_similarity(name, '#{escape_identifier(params[:name])}')::numeric, 2)::real AS similarity,
        …
        ORDER BY similarity DESC
        LIMIT 5;
      SQL
    )

    rows = [] of Property
    Property.adapter.select(query) do |results|
      results.each do
        rows << Property.from_rs(results)
      end
    end

Maybe this approach will help you.

theHellDog avatar Nov 30 '20 11:11 theHellDog

The biggest challenge with having a select that returns only the specified attributes in Crystal is that we then can't have the results as the actual object like what ActiveRecord does in Ruby. The typing is too strict for that, however, I do think there is value in having this method available if an array of the results is acceptible.

crimson-knight avatar Apr 25 '23 13:04 crimson-knight