简体   繁体   中英

Rails 4, order in has_many :through. It simply does nothing

I have this situation:

class Student < ActiveRecord::Base
    has_many :tickets
    has_many :movies, through: :tickets
end


class Movie < ActiveRecord::Base
    has_many :tickets
    has_many :students, through: :tickets
end


class Ticket < ActiveRecord::Base
    belongs_to :movie, counter_cache: true
    belongs_to :student
end


class Cinema < ActiveRecord::Base
    has_many :movies, dependent: :destroy
    has_many :students, through: :movies
end

I have this code in my ( movie_controller.rb ) controller:

def show
  @tickets = @movie.tickets.includes(:student)
end

Now in my grid ( show.html.erb ) I have this situation:

<% @tickets.each do |ticket| %>
  <tr>
    <td><%= ticket.student.id %></td>
    <td><%= ticket.student.code %></td>
    <td><%= ticket.student.last_name %> <%= ticket.student.first_name %></td>
    <td><%= ticket.hours %></td>
    <td><% if ticket.payed %>Yes<% else %>No<% end %></td>
  </tr>
<% end %>

Now I want to order the students by their "last_name, first_name", but if I use this code in my controller:

@tickets = @movie.tickets.includes(:student).order('students.last_name')

in my console I have a SQL query like this:

"AS t0_r0 .... AS t0_r1 ..." and so on... is it normal?

Is my logic wrong?

If I use in my model a code like this:

class Movie < ActiveRecord::Base
    has_many :tickets
    has_many :students, -> { order('last_name, first_name') }, through: :tickets
end

nothing works . My list is ordered not by last name and first name, but default (id).

How to do better?

UPDATE :

I changed from model "Children" to "Student".

""AS t0_r0 .... AS t0_r1 ..." and so on... is it normal?"

Yes, the includes has been implemented as an outer join, so the order by can be applied to the rows returned from the tickets table.

To use scope for this, you'd want to do something like :

student.rb

def self.by_last_name
  order(:last_name)
end

ticket.rb

def self.by_student_last_name
  joins(:student).merge(Student.by_last_name)
end

... then ...

@tickets = @movie.tickets.by_student_last_name

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM