Łukasz Korol Łukasz Korol - 5 months ago 12
Ruby Question

Sorting associated column in table

I try doing sortable column based on 228 Sortable Table Columns

Everything is correct, but I don't have idea how to sort associated column with another model.

# Table name: vacations
# id :integer not null, primary key
# start_at :date not null
# end_at :date not null
# person_id :integer not null


I tried using this:

= sortable "person.first_name", "Employee"


This not work correct.

Associations

class Vacation < ActiveRecord::Base
belongs_to :person
end

class Person < ActiveRecord::Base
has_many :vacations
end


Schema of people table:

# Table name: people
#
# id :integer not null, primary key
# pesel :string not null
# first_name :string not null
# last_name :string not null


Current index action in VacationsController.

def index
@vacations = Vacation.order(sort_column + ' ' + sort_direction)
.paginate(page: params[:page], per_page: 20)
end


Sorting methods.

def sort_column
Vacation.column_names.include?(params[:sort]) ? params[:sort] : 'start_at'
end

def sort_direction
%w(asc desc).include?(params[:direction]) ? params[:direction] : 'asc'
end


Update:

Vacation.joins(:person).column_names


returns:

=> ["id", "start_at", "end_at", "free", "reason", "person_id", "accepted"]

Answer

If you are following guides from the RailsCast, you should have some code like:

@vocations = Vocation.order(params[:sort] + ' ' + params[:direction])

And if you would like to sort by column in another model, which in your case Person model, you have to update your query to join your people table to make it work.

@vocations = Vocation.includes(:person).order(params[:sort] + ' ' + params[:direction]).references(:people)

In you view,

= sortable "people.first_name", "Employee"

UPDATE:

You could update your sort_column to handle the special case for your joined table:

  JOINED_TABLE_COLUMNS = %w(people.first_name)
  def sort_column
    if JOINED_TABLE_COLUMNS.include?(params[:sort]) || Vacation.column_names.include?(params[:sort])
      params[:sort]
    else
      'start_at
    end
  end
Comments