amberframework/granite

order in assocation collection

yujiri8 opened this issue · 1 comments

It seems like association collections cannot be ordered like normal queries? With this example:

Granite::Connections << Granite::Adapter::Sqlite.new(name: "test", url: "sqlite:./blah")

require "granite/adapter/sqlite"

class User < Granite::Base
  connection mysql

  has_many :post

  # pluralization requires providing the class name
  has_many posts : Post

  # or you can provide class name as a parameter
  has_many :posts, class_name: Post

  # you can provide a custom foreign key
  has_many :posts, class_name: Post, foreign_key: :custom_id

  column id : Int64, primary: true
  column name : String
  column email : String
  timestamps
end
class Post < Granite::Base
  connection mysql
  table posts

  belongs_to :user

  # or custom name
  belongs_to my_user : User

  # or custom foreign key
  belongs_to user : User, foreign_key: uuid : String

  column id : Int64, primary: true
  column title : String
  timestamps
end

puts User.find!(1).posts.order(title: :desc)

I get:

Showing last frame. Use --error-trace for full trace.

There was a problem expanding macro 'method_missing'

Code in macro 'forward_missing_to'

 1 | macro method_missing(call)
     ^
Called macro defined in macro 'forward_missing_to'

 1 | macro method_missing(call)

Which expanded to:

 > 1 | collection.order(title: title)
                  ^----
Error: undefined method 'order' for Array(Post)

This error makes sense, right now associations are returned as an Array, so instead of using order you'd want to use sort, because by then the objects are already in memory.

I don't think we have a lazy evaluation of associations at this point, and making the order method work on an association collection means we'll need to consider returning a Granite object that lets us add the convenience method of Object.assocation_of_some_kind.order(attribute: :asc)