Hi guys!
I am still not able to get the sorting onclick of the table headers
to work…
I get this error:
NoMethodError in PeopleController#index
You have a nil object when you didn’t expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.[]
RAILS_ROOT: C:/ruby/contact
Application Trace | Framework Trace | Full Trace
app/helpers/sort_helper.rb:104:in sort' app/controllers/people_controller.rb:19:in
index’
app/controllers/people_controller.rb:18:in sort' app/controllers/people_controller.rb:18:in
index’
This is my code:
controller.rb
helper :sort
include SortHelper
GET /people
GET /people.xml
def index
# @sorter = SortingHelper::Sorter.new self, %w(name address),
@params[‘sort’], @params[‘order’], ‘name’, ‘ASC’
SortHelper.columns = %w[
name
address
]
SortHelper.default_order = %w[name address]
@people = Person.search(params[:search], params[:page])
@people = Person.find(:all).sort do |a, b|
SortHelper.sort(a, b, @params)
end
@people = Person.find(:all)
#respond_to do |format|
# format.html # index.html.erb
#format.xml { render :xml => @people }
#end
end
index.html.erb
Listing people
<% for person in @people %>
<% end %><%= link_to_sort_by 'Name', 'name' %> | <%= link_to_sort_by 'Address', 'address' %> | |||
---|---|---|---|---|
<%=h person.name %> | <%=h person.address %> | <%= link_to 'Show', person %> | <%= link_to 'Edit', edit_person_path(person) %> | <%= link_to 'Destroy', person, :confirm => 'Are you sure?', :method => :delete %> |
<%= will_paginate @people %>
<%= link_to ‘New person’, new_person_path %>
sort_helper.rb
= sort_helper.rb - SortHelper for Ruby on Rails
Author: Dave B. mailto:[email protected]
Version: 17 Feb 2005
Makes column headings users can click to define how the table is
sorted.
== Example
=== View
<%= link_to_sort_by ‘First Name’, ‘name’ %>
<%= link_to_sort_by ‘Surname’, ‘family.name’ %>
<%= link_to_sort_by ‘Email’, ‘email’ %>
=== Controller:
helper :sort
def list # action
SortHelper.columns = %w[
name
family.name
]
SortHelper.default_order = %w[family.name name]
@people = Person.find_all.sort do |a, b|
SortHelper.sort(a, b, @params)
end
end
module SortHelper
Create a link (‘a’ tag) back to the current action, but sorting by
sort_column before any existing ordering.
Example:
On an un-sorted page,
<%= link_to_sort_by ‘First Name’, ‘name’ %>
<%= link_to_sort_by ‘Surname’, ‘family.name’ %>
<%= link_to_sort_by ‘Email’, ‘email’ %>
could result in:
First Name
Surname
If the page was already sorted by first name,
<%= link_to_sort_by ‘First Name’, ‘name’ %>
<%= link_to_sort_by ‘Surname’, ‘family.name’ %>
<%= link_to_sort_by ‘Email’, ‘email’ %>
could result in:
First Name
Surname
def link_to_sort_by(link_text, sort_column)
sort_key = @@sort_keys[sort_column]
sort = (@params['sort'] || '').split.map {|param| param.to_i }
if sort[0] && sort[0].abs == sort_key
sort[0] = -sort[0]
else
sort.delete_if {|key| key.abs == sort_key }
sort.unshift sort_key
end
link_to link_text, :params => {'sort' => sort.join(' ')}
end
Set the columns that may be used to sort by.
You must set this from the controller before you can use
+link_to_sort_by+ in a view.
def self.columns=(column_names)
# prepend id so that the first sortable column is at index 1
@@sort_columns = [‘id’] + column_names
@@sort_keys = {}
@@sort_columns.each_with_index {|obj, i| @@sort_keys[obj] = i }
end
Set the columns that are used to sort by default
def self.default_order=(column_names)
@@default_columns = column_names.map {|column|
@@sort_keys[column] }
end
This is a comparison method that returns -1, 0 or 1
depending on the passed objects a and b, and the sorting
priorities defined in params. It can be used in blocks
given to +Enumerable#sort+.
Use it like this:
@people = Person.find_all.sort do |a, b|
SortHelper.sort(a, b, @params)
end
def self.sort(a, b, params)
if /\d/ === params[‘sort’]
params[‘sort’].split
else
@@default_columns
end.each do |column_index|
column_index = column_index.to_i
next if column_index.abs >= @@sort_columns.size
a_col = a
b_col = b
@@sort_columns[column_index.abs].split(‘.’).each do |meth|
a_col = a_col.send(meth)
b_col = b_col.send(meth)
end
reverse = (column_index < 0)
case a_col && a_col <=> b_col
when -1
return reverse ? 1 : -1
when 1, nil # nil < anything else
return reverse ? -1 : 1
end
end
0
end
end
Please can anyone tell me whats the mistake? I had already got the
pagination working before, however, after i put the sorting code, it
too is not working…