AJAX autocomplete based on a static table in the database

I have a field where a user enters his city. I want to add
autocompletion to this field based on a table with a predefined set of
cities not based on previous entries of other users. How can I do this?

I know about the method described in rails recipes which allows to
cache a predefined set of values for autocompletion
(Autocomplete.Local). This is not what I'm looking for though because
my list of cities is very long and I don't want to cache it.

Thanks,
Aeneas

You can write your own "auto_complete_for_#{object}_#{method}" method
pretty easily, rather than calling auto_complete_for to generate it
for you. The source code of auto_complete_for is a good starting
point.

-- James

Thanks James. I solved the problem now. It's really easy. In your
controller you just replace

auto_complete_for :ad, :city

with

  def auto_complete_for_ad_city
    @cities = City.find(:all)
    render :inline => "<%= auto_complete_result(@cities, 'name') %>"
  end

For this to work you will need a table called cities and a city model.

Aeneas

I still have one probelm though. The soruce for auto_complete_for is as
follows:

37: def auto_complete_for(object, method, options = {})
38: define_method("auto_complete_for_#{object}_#{method}") do
39: find_options = {
40: :conditions => [ "LOWER(#{method}) LIKE ?", '%' +
params[object][method].downcase + '%' ],
41: :order => "#{method} ASC",
42: :limit => 10 }.merge!(options)
43:
44: @items = object.to_s.camelize.constantize.find(:all,
find_options)
45:
46: render :inline => "<%= auto_complete_result @items,
'#{method}' %>"
47: end
48: end

However, the following adaption dowsn't work (in the controller):

  def auto_complete_for_ad_city
    @items = City.to_s.camelize.constantize.find( :all,
            :conditions => [ "LOWER(name) LIKE ?", '%' +
params[ad][city].downcase + '%' ],
            :order => "name ASC",
            :limit => 10
          )
          render :inline => "<%= auto_complete_result(@items, 'name')
%>"
  end

the part causing problems is params[city][name]. Is this really the
variable which stores the letters typed into the field ad[city]? The
error message is: undefined local variable or method `ad' for
#<AdsController:0xb79908c0>

Any ideas?

Aeneas

I still have one probelm though. The soruce for auto_complete_for is as
follows:

37: def auto_complete_for(object, method, options = {})
38: define_method("auto_complete_for_#{object}_#{method}") do
39: find_options = {
40: :conditions => [ "LOWER(#{method}) LIKE ?", '%' +
params[object][method].downcase + '%' ],
41: :order => "#{method} ASC",
42: :limit => 10 }.merge!(options)
43:
44: @items = object.to_s.camelize.constantize.find(:all,
find_options)
45:
46: render :inline => "<%= auto_complete_result @items,
'#{method}' %>"
47: end
48: end

However, the following adaption dowsn't work (in the controller):

  def auto_complete_for_ad_city
    @items = City.to_s.camelize.constantize.find( :all,
            :conditions => [ "LOWER(name) LIKE ?", '%' +
params[ad][city].downcase + '%' ],
            :order => "name ASC",
            :limit => 10
          )
          render :inline => "<%= auto_complete_result(@items, 'name')
%>"
  end

the part causing problems is params[city][name]. Is this really the
variable which stores the letters typed into the field ad[city]? The
error message is: undefined local variable or method `ad' for
#<AdsController:0xb79908c0>

Any ideas?

Aeneas

Did you really mean this instead?

params[:ad][:city]

If that's not where your trouble lies, look at your development log
file. Every param is logged there, so you should be able to see the
names being used.

-- James

JDL wrote:

>
> I still have one probelm though. The soruce for auto_complete_for is as
> follows:
>
> 37: def auto_complete_for(object, method, options = {})
> 38: define_method("auto_complete_for_#{object}_#{method}") do
> 39: find_options = {
> 40: :conditions => [ "LOWER(#{method}) LIKE ?", '%' +
> params[object][method].downcase + '%' ],
> 41: :order => "#{method} ASC",
> 42: :limit => 10 }.merge!(options)
> 43:
> 44: @items = object.to_s.camelize.constantize.find(:all,
> find_options)
> 45:
> 46: render :inline => "<%= auto_complete_result @items,
> '#{method}' %>"
> 47: end
> 48: end
>
> However, the following adaption dowsn't work (in the controller):
>
> def auto_complete_for_ad_city
> @items = City.to_s.camelize.constantize.find( :all,
> :conditions => [ "LOWER(name) LIKE ?", '%' +
> params[ad][city].downcase + '%' ],
> :order => "name ASC",
> :limit => 10
> )
> render :inline => "<%= auto_complete_result(@items, 'name')
> %>"
> end
>
> the part causing problems is params[city][name]. Is this really the
> variable which stores the letters typed into the field ad[city]? The
> error message is: undefined local variable or method `ad' for
> #<AdsController:0xb79908c0>
>
> Any ideas?

Did you really mean this instead?

params[:ad][:city]

If that's not where your trouble lies, look at your development log
file. Every param is logged there, so you should be able to see the
names being used.

-- James

Thanks, that was it!

So for the archive here the working version:

  def auto_complete_for_ad_city
    @items = City.to_s.camelize.constantize.find( :all,
            :conditions => [ "LOWER(name) LIKE ?", '%' +
params[:ad][:city].downcase + '%' ],
            :order => "name ASC",
            :limit => 10
          )
     render :inline => "<%= auto_complete_result(@items, 'name') %>"
  end