I’ve written a lot here about the Rails auto_complete plugin; I’ve also refactored the auto_complete plugin to support repeated fields and named scopes. Today I’d like to show how you can automatically generate Rails view and controller code with auto_complete behavior for one of your models using a new gem I’ve written called View Mapper. If you’ve never used the auto_complete plugin before this is a great way to learn quickly how to use it in your app; even if you are familiar with the plugin using scaffolding like this can help to get a working auto_complete form up and running quickly and let you concentrate on more important parts of your app.
Let’s say you have an existing model in your app called “Person:”
Class Person < ActiveRecord::Base end
And suppose the Person model has two string attributes for the person’s name and the name of the office they work in:
class CreatePeople < ActiveRecord::Migration def self.up create_table :people do |t| t.string :name t.string :office etc…
Now let’s install View Mapper so we can generate an auto_complete view for our person model. Since I’ve only deployed view_mapper on gemcutter.org for now, you’ll also need to add gemcutter as a gem source if you haven’t already.
$ gem sources -a http://gemcutter.org http://gemcutter.org added to sources $ sudo gem install view_mapper Successfully installed view_mapper-0.1.0 1 gem installed Installing ri documentation for view_mapper-0.1.0... Installing RDoc documentation for view_mapper-0.1.0...
Now with view_mapper you can run a single command to generate scaffolding that displays the your existing person model’s fields in a form with auto_complete type ahead behavior for the office field:
$ ./script/generate view_for person --view auto_complete:office exists app/controllers/ exists app/helpers/ create app/views/people exists app/views/layouts/ exists test/functional/ exists test/unit/ create test/unit/helpers/ exists public/stylesheets/ create app/views/people/index.html.erb create app/views/people/show.html.erb create app/views/people/new.html.erb create app/views/people/edit.html.erb create app/views/layouts/people.html.erb create public/stylesheets/scaffold.css create app/controllers/people_controller.rb create test/functional/people_controller_test.rb create app/helpers/people_helper.rb create test/unit/helpers/people_helper_test.rb route map.resources :people route map.connect 'auto_complete_for_person_office', :controller => 'people', :action => 'auto_complete_for_person_office'
This works just like the Rails scaffold generator, except that the view_for generator has also:
- inspected your person model and found the name and office columns.
- added a route for “auto_complete_for_person_office” to routes.rb.
- added a call to “auto_complete_for :person, :office” to PersonController.
- used text_field_for_auto_complete on the office field in your new and edit forms.
If you start up your application and create a few person records with names and addresses, then you will see the auto_complete plugin working!
With this working example right inside your application, you can easily review exactly how the view, route and controller files use auto_complete. After that you can adapt the view to fit into your application’s design and delete the scaffolding you don’t really need or want.
As another example, let’s create an entirely new Rails application completely from scratch, and use View Mapper to setup auto_complete inside it:
$ rails auto_complete_example create create app/controllers create app/helpers create app/models create app/views/layouts etc… $ cd auto_complete_example
First, let’s install the auto_complete plugin. (In a future post I’ll show how to use View Mapper with my fork of auto_complete in a complex form.)
$ ./script/plugin install git://github.com/rails/auto_complete.git Initialized empty Git repository in /Users/pat/rails-apps/auto_complete_example/vendor/plugins/auto_complete/.git/ remote: Counting objects: 13, done. remote: Compressing objects: 100% (12/12), done. remote: Total 13 (delta 2), reused 0 (delta 0) Unpacking objects: 100% (13/13), done. From git://github.com/rails/auto_complete * branch HEAD -> FETCH_HEAD
Now that we have the plugin installed, let’s create our scaffolding. Along with the “view_for” generator I used above, View Mapper also provides a generator called “scaffold_for_view.” This works the same way, except it just creates a new model the same way the Rails scaffold generator does, instead of inspecting an existing model.
Let’s create the same person model we used above, and an auto_complete view:
$ ./script/generate scaffold_for_view person name:string office:string --view auto_complete:office exists app/models/ exists app/controllers/ exists app/helpers/ create app/views/people exists app/views/layouts/ exists test/functional/ exists test/unit/ create test/unit/helpers/ exists public/stylesheets/ create app/views/people/index.html.erb create app/views/people/show.html.erb create app/views/people/new.html.erb create app/views/people/edit.html.erb create app/views/layouts/people.html.erb create public/stylesheets/scaffold.css create app/controllers/people_controller.rb create test/functional/people_controller_test.rb create app/helpers/people_helper.rb create test/unit/helpers/people_helper_test.rb route map.resources :people dependency model exists app/models/ exists test/unit/ exists test/fixtures/ create app/models/person.rb create test/unit/person_test.rb create test/fixtures/people.yml create db/migrate create db/migrate/20091001161349_create_people.rb route map.connect 'auto_complete_for_person_office', :controller => 'people', :action =>'auto_complete_for_person_office'
Note the syntax is the same as the standard Rails scaffold generator, except I’ve added the “view” parameter to specify we want the auto_complete plugin to be used in the view.
Now we just need to migrate the database schema and run our app:
$ rake db:migrate (in /Users/pat/rails-apps/auto_complete_example) == CreatePeople: migrating =================================================== -- create_table(:people) -> 0.0012s == CreatePeople: migrated (0.0015s) ==========================================
And if you add a few records, you’ll see auto_complete working!
I’ll be adding more views to View Mapper soon, and in future posts here I’ll write about how to generate scaffolding for Paperclip file attachments, my version of auto_complete used on a complex form, and also how to write your own views for View Mapper.