Order with multilevel nested attributes in rails

So, I tried to do this:

gig.rb

Class Gigenrollment < ActiveRecord::Base
  has_many :gigenrollments, dependent: :destroy

      

gigenrollment.rb

Class Gigenrollment < ActiveRecord::Base
  belongs_to :gig
  belongs_to :profile

  def self.order_by_instrument
    includes(profile: :instruments).order(profiles: {instruments: {primary: :desc}})
  end

      

profile.rb

Class Profile < ActiveRecord::Base
  has_many: :gigenrollments, dependent: :destroy
  has_many :instruments, -> {order(primary: :desc)}, dependent: :destroy

      

instrument.rb

Class Instrument < ActiveRecord::Base
  belongs_to :profile

      

I have one way to get the order correct, but it's kind of ugly. It looks like a controller:

# @gig is an instance of the Gig class, eg. Gig.last
@orchestra = @gig.gigenrollments
@orchestra = @orchestra.sort_by{ |ge| ge.profile.instruments.find_by(primary: true).nil? ? 'z'  : ge.profile.instruments.find_by(primary: true).name}

      

So, I'm trying to find a more accurate way to order participation in concerts from one concert, depending on the name of the primary instruments of one profile (one profile should not have one or more). So far, I think I have it correct, but I cannot find an example of an ordering with nested attributes like mine.

So far I've been doing this in my controller hoping to get what I want:

@orchestra = @gig.gigenrollments
@orchestra = @orchestra.order_by_instrument # check out the order_by_instrument function in the code snippet in gigenrollment.rb

      

But I am getting error

Direction should be :asc or :desc

      

Which leaves me thinking that I just can't get the syntax right. I have also tried this with no success

# gigenrollment.rb
def self.order_by_instrument
  includes(profile: :instruments).references(profile: :instruments).order('"profile"."instruments"."primary" ASC, "profile"."instruments"."name" ASC')
end

      

I read about this includes and this about ordering and a few posts on this topic on Stackoverflow, but they all either have nested attributes at one level only (I have two, gigenrollments -> profile -> tools), they use scopes, have forms or they have a where clause instead of ordering which doesn't really get me where I would like (wrong syntax). I also found some issues on Github that made me think this should be doable.

But I kind of understand that this is not doable with ordering, since one profile can have many tools, and only tools with the "primary" attribute as true should affect the ordering of the gigenrollments while I'm writing this question.


Apparently I need a reputation for posting links, so I put them here instead ...

Stackoverflow pages:
stackoverflow.com/questions/23121975/how-can-i-order-nested-includes-records-with-rails-4
stackoverflow.com/questions/19865208/rails-query-join-order-by-group- by-issue
stackoverflow.com/questions/13619560/rails-y-way-to-query-a-model-with-a-belongs-to-association

Github issues:
github.com/rails/rails/issues/8663
github.com/rails/rails/issues/726

+3


source to share





All Articles