Posted on December 28, 2007
1
2
3
4
5
6
7
8
9
10
11
12
13
|
def self.paginating_ferret_search(options)
offset = (options[:current].to_i - 1) * options[:page_size]
limit = options[:page_size]
order = options[:order]
count = total_hits(options[:q])
PagingEnumerator.new(options[:page_size], count, false, options[:current], 1) do |page|
res = find_with_ferret(options[:q],
{:offset => offset, :limit => limit, :sort => order})
end
end
|
This is the method in the controller
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
def search
#params[:d] is the direction of sorting
if params[:d]
sort_order = params[:c] + (params[:d] == 'down' ? ' DESC' : ' ASC')
else
sort_order = "name ASC"
end
current_page = (params[:page] ||= 1).to_i
# check for each search field on the form
if params[:city] && !params[:city].blank?
@city_query = "city:\"#{params[:city]}\""
@city_label = "City: <blue>#{params[:city]}</blue>"
end
if params[:state] && !params[:state].blank?
@state_query = "state:#{params[:state]}"
@state_label = "State: <blue>#{params[:state]}</blue>"
if @state_query.size != 2
flash[:notice] = "State should be 2 Digits"
end
end
if params[:zip] && !params[:zip].blank?
@zip_code_query = "zip:#{params[:zip]}*"
@zip_code_label = "Zip: <blue>#{params[:zip]}*</blue>"
end
if params[:name] && !params[:name].blank?
@name_query = "name:#{params[:name]}"
@name_label = "Name: <blue>#{params[:name]}</blue>"
end
# for ferret we cannot User "name ASC", have to be "name"
if @city_query or @state_query or @zip_code_query or @keyword_query
# params[:c] is the column name to sort
if params[:c]
sort_order = case params[:c]
when "name" then "name"
when "city" then "city"
when "state" then "state"
when "zip" then "zip"
else "name"
end
else
sort_order = "name"
end
# Conditions: can be either of both AND/OR
@condition = "AND"
# Queries for Ferret
# My helper to build the query,
@full_query = build_query(@full_query, @keyword_query, @condition)
@full_query = build_query(@full_query, @city_query, @condition)
@full_query = build_query(@full_query, @state_query, @condition)
@full_query = build_query(@full_query, @zip_query, @condition)
# Labels for flash[:notice]
# I use comma to delimiter the labels in flash[:notice]
@condition = ","
@query_label = build_query(@query_label, @keyword_label, @condition)
@query_label = build_query(@query_label, @city_label, @condition)
@query_label = build_query(@query_label, @state_label, @condition)
@query_label = build_query(@query_label, @zip_label, @condition)
# get the query
@users = User.paginating_ferret_search({:q => @full_query,
:page_size => 100,
:current => current_page,
:order => sort_order}
)
flash[:notice] = "<h3> Found #{@prospects.size} records for #{@query_label} </h3>"
else
# if no query, just return empty
@User = []
end
end
|
My application method, in application.rb add this method:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
def build_query(full_query, query, condition)
if query
if full_query && !full_query.empty?
full_query = "#{full_query} #{condition} #{query}"
else
full_query = query
end
end
return full_query
end
|
in application_helper.rb I have this little helper I found in
this site
it helps to make the links in the sorting columns in the views..
def sort_link(title, column, options = {})
condition = options[:unless] if options.has_key?(:unless)
sort_dir = params[:d] == 'up' ? 'down' : 'up'
link_to_unless condition, title, request.parameters.merge( {:c => column, :d =>
Tagged with: ferret pagination rails sorting |
1 comment
Just a note that if you're on the latest versions of actsas_ferret and willpaginate then paginated ferret searches are as simple as this:
@results = ActsAsFerret::find(params[:q], [ModelA, ModelB, ModelC], {:page => params[:page], :per_page => 25})And you can add conditions to do the search order