Ruby on Rails TutorialOverviewBefore You StartFor this tutorial you will need:
Several online "how to" guides are available for installing and configuring Ruby on Rails. See Rails Resources for links to setup tutorials and installation bundles Tutorial ScenarioThis tutorial walks you through the creation of a very simple Rails application. The Movie Lending Library application is a web application that allows you to add, remove, borrow and return movies from a shared library. Komodo has a very powerful Ruby on Rails project template with macros and commands for further automating the creation of Rails applications. The entire application can be created within Komodo using these tools and Komodo itself, without having to work at the command-line. In this tutorial you will:
Creating a Rails ProjectKomodo ships with a powerful template for Rails projects, containing several macros for:
To create the tutorial project file:
If Rails has been installed correctly, you should see a Komodo
Alert dialog box saying "The movielib project is built". The
movielib.kpf project should open in the Projects tab
on the left, and should contain "Live Folders" of all the
directories created by the
Creating the DatabaseEditing the database.yml fileIf MySQL is installed locally and can accept connections by 'root' without a password (it often is by default), click the Create Databases macro in the Rails Tools project folder to create the database. If you have set a MySQL root password, created another MySQL account that you would like to use, or are running the server on a different host, you will need to configure the database.yml file:
If you would like to use a database server other than MySQL, consult the Rails documentation on configuring this file, making sure you have the necessary database drivers installed, and creating the database manually. The database macros in the project will only work with MySQL. Running the Create Databases MacroIn the Rails Tools project folder is a macro called Create Databases. Double-click the macro to run it. If the database.yml file (and the database server) are configured correctly, a database called movielib (as specified in the database.yml file - derived from the project name) will be created and an alert will appear indicating that the database creation is done. Generating ModelsNow that we have a directory tree with stub files, and a database
for the application to use, we need to create our first model. At the
command line we would use ' In the Rails Tools/Generators project folder are macros for creating various parts of a Rails application. Double-click the model macro. A dialog-box appears prompting for a model name. The Movie ModelSince our application is a library for movies, we will need a movie
model. Enter The following output should appear in the Command Output tab showing the files created in this step: exists app/models/ exists test/unit/ exists test/fixtures/ create app/models/movie.rb create test/unit/movie_test.rb create test/fixtures/movies.yml create db/migrate create db/migrate/001_create_movies.rb Komodo will also open these files in editor tabs. At this point we need to define the database table that this model will use. Click on the 001_create_movies.rb editor tab (or open it from the db/migrate/ project folder). Notice that Rails has pluralized the name "movie" for the database table name. Add the following below the ' t.column :title, :string t.column :created_on, :date This is the file that will control the creation of the
The Person ModelWe will need to track the name of the person borrowing a movie. We'll do this with a person model. Double-click on the model macro again. This time,
specify The Command Output tab will again show us which files were created.
The file we need to edit is 002_create_people.rb. Add the
following below the t.column :name, :string With both models, Rails will automatically add a
The Checkout ModelNow we need a way to link people with movies. We'll do this with a
'checkout' model. Double-click on the model macro
again. This time, specify Add the following to to the newly created
003_create_checkouts.rb below the ' t.column :person_id, :integer, :null => false t.column :movie_id, :integer, :null => false t.column :created_on, :date MigrationNow that we've defined the models in Rails, we need to apply them
to our database. In Rails this is done with the ' Double-click the db:migrate macro in Rails Tools|Migrate. The Command Output tab should show that the tables 'movies', 'people' and 'checkouts' have been created. Creating a ScaffoldGenerating a scaffold is a quick way to get a skeletal, working Rails application that can be modified iteratively. Since most database driven web applications are very similar in their basic design, Rails builds a generic application based on the information in your models which you can then modify to meet your specific requirements. In the Generators folder, double-click the
scaffold macro. In the dialog box enter
Several files are created and opened in editor tabs. Since the tutorial won't be dealing with most of these files, feel free to close them to unclutter your workspace - they can all be opened from the project later as needed. Starting the Webrick ServerAt this point we have a working application. It's not yet useful as a lending library, but we can have a look at what we've got so far. In the Run folder, double-click the run server macro. This will start the the Webrick web server in a separate console. Open the http://localhost:3000/library in your favourite web browser. You should see a "Listing movies" page with no data and a "New movie" link. This isn't actually usable yet, but we can leave the webserver running and see our changes as we make them. Listing and Adding MoviesSo far, the main Library page doesn't tell us much. We need to create a basic listing page to view the library contents. Open the list.rhtml file from the app/views/library project directory, or click on it's editor tab if it is already open. Replace the contents with the following: <h1>DVD Lending Library</h1> <table> <tr> <th class="dvdlib_header">Title</th> <th class="dvdlib_header">Status</th> </tr> <% for movie in @movies %> <tr> <td class="dvdlib_item"><%=h movie.title %></td> <td class="dvdlib_item">In</td> <td><%= link_to 'Check out', :action => 'checkout', :id => movie %></td> <td><%= link_to 'Details', :action => 'details', :id => movie %></td> <td><%= link_to 'Edit', :action => 'edit', :id => movie %></td> <td><%= link_to 'Remove', { :action => 'destroy', :id => movie }, :confirm => 'Are you sure?', :method => :post %></td> </tr> <% end %> </table> <%= link_to 'Previous page', { :page => @movie_pages.current.previous } if @movie_pages.current.previous %> <%= link_to 'Next page', { :page => @movie_pages.current.next } if @movie_pages.current.next %> <br /> <%= link_to 'Add new movie', :action => 'new' %> We also need to create a form to add movies. The <%= error_messages_for 'movie' %> <!--[form:movie]--> <p><label for="movie_title">Title</label><br/> <%= text_field 'movie', 'title' %></p> <p><label for="movie_created_on">Added to library on:</label><br/> <%= date_select 'movie', 'created_on' %></p> <!--[eoform:movie]--> We've created an editable field for entering the movie title, and shown the current date stamp as the creation time. Go ahead and add a few of your favourite movies. The "Check out" and "Details" links won't do anything yet, but you can Add, Edit, or Remove titles. Editing a Title in PlaceRails has some built in JavaScript methods that provide some useful functionality. We could use one of these to make the Title field in our main library/list view editable. Open list.rhtml (apps/views/library/list.rhtml) and replace
the <td class="dvdlib_item"> <% @movie = movie %> <%= in_place_editor_field :movie, :title %> </td> The Next, open library.rhtml
(apps/views/layouts/library.rhtml). Add the following line in the
<%= javascript_include_tag :defaults %> This line includes the default Rails JavaScript libraries
( <td><%= link_to 'Edit', :action => 'edit', :id => movie %></td> The field in the page is now editable, but the change is not savable until we make a change in library_controller.rb (app/controllers/library_controller.rb). Add the following on line 2, just below the LibraryController class declaration. in_place_edit_for :movie, :title
Check Out a MovieOn the main library list page, each movie has four actions associated with it: "Check out", "Details", and "Remove". "Remove" (and the "Edit" action that we just removed) is a generic web/database function that Rails provides which works well enough for our library application. "Check out" and "Details" are specific to our application and will have to be defined in our Controller (library_controller.rb). Our check out function should do the following:
Here are the routines we need to add to
library_controller.rb. Put them at the bottom of the file,
just before the last def checkout @movie = Movie.find(params[:id]) end def do_checkout movie_id = params[:id] name = params[:person][:name] if name.blank? flash[:notice] = 'No name given' redirect_to :action => :checkout, :id => movie_id elsif (@name = Person.find_by_name(name)).blank? flash[:notice] = "Who is #{name}?" redirect_to :action => checkout, :id => movie_id else @movie = Movie.find(movie_id) checkout = Checkout.create(:movie_id => movie_id, :person_id => @name.id).save redirect_to :action => :list end end def register movie_id = params[:id] name_to_register = params[:person][:name] if name_to_register.blank? flash[:notice] = 'No name given' else person = Person.find_by_name(name_to_register) if person flash[:notice] = "#{person.name} is already registered" else Person.create(:name => name_to_register).save end end redirect_to :action => :checkout, :id => movie_id end Now we need to create the checkout page. Right-click on the library folder (app/views/library) and select Add|New File.... Enter the filename checkout.rhtml and click Open. Add the following in the new file: <h1>Checkout a movie</h1> <p>Title: <%= h @movie.title %></p> <% form_tag :action => 'do_checkout', :id => @movie do %> <p>Your name: <%= text_field_with_auto_complete(:person, :name) %> <%= submit_tag 'Check out' %> <% end %> <h2>Please register me</h2> <% form_tag :action => 'register', :id => @movie do %> <p><label for="movie_title">Your name</label><br/> <%= text_field 'person', 'name' %></p> <%= submit_tag 'Add me' %> <% end %> <%= link_to 'Back to the library', :action => 'list' %> Notice the auto_complete_for :person, :name The field should now give autocompletion options when you start typing a name into it. To change the main library list page to show whether a movie is
"In" or "Out". In list.rhtml, replace the placeholder line
' <% checkout = Checkout.find_by_movie_id(@movie) %> <td class="dvdlib_item"><%= Checkout.find_by_movie_id(@movie) ? "Out" : "In" %></td> Debugging Rails Komodo IDE onlyThere is a bug in the Open library_controller.rb in an editor tab. Set a
breakpoint on the '
The library_controller.rb tab should come to the
foreground in Komodo, with a yellow arrow over the breakpoint we set
earlier. While execution of the application is paused, we can examine
variables and interact with the application via the Ruby shell. On the
Locals tab on the left side of the bottom pane, we
can see the following variables from the
The The line immediately below our breakpoint has the following: redirect_to :action => checkout, :id => movie_id The You can now leave WEBrick in debugging mode, or shut it down ('Ctrl'+'C' in the console) and restart it with the run server macro. Returning a movieNow that we can check out a movie, we should add the ability to
return it. Currently we have a 'Check out' link. We can change this so
that it shows 'Check out' if the movie is in, and 'Return' if the
movie is out. Replace the entire second
<tr> <td class="dvdlib_item"> <% @movie = movie %> <%= in_place_editor_field :movie, :title %> </td> <% checkout = Checkout.find_by_movie_id(@movie) %> <td class="dvdlib_item"><%= checkout ? "Out" : "In" %></td> <td><% if checkout %> <%= link_to 'Return', :action => 'return', :id => movie %> <% else %> <%= link_to 'Check out', :action => 'checkout', :id => movie %> <% end %> </td> <td><%= link_to 'Details', :action => 'details', :id => movie %></td> <td><%= link_to 'Remove', { :action => 'destroy', :id => movie }, :confirm => 'Are you sure?', :method => :post %></td> </tr> Here is the method we need to add to library_controller.rb: def return movie_id = params[:id] checkout = Checkout.find_by_movie_id(movie_id) if checkout Checkout.delete(checkout) end redirect_to :action => :list end Viewing Checkout DetailsThe application is now mostly working. There's just one crucial component left to implement. The 'Details' link currently doesn't do anything (besides bringing up an "Unknonw action" error). We want this page to show us who has the movie, and when it was checked out. Right-click on the library folder (app/views/library) and select Add|New File.... Enter the filename details.rhtml and click Open. Add the following in the new file: <h1>Checkout details</h1> <ul> <li>Movie: <%= h @movie.title %></li> <li>Borrower: <%= h(@person.name) %></li> <li>Borrowed: <%= @checkout_date %></li> </ul> </p> <%= link_to 'Return', :action => 'return', :id => @movie %> <%= link_to 'List', :action => 'list' %> Of course, we'll need another method in library_controller.rb: def details movie_id = params[:id] @movie = Movie.find(movie_id) checkout_id = params[:checkout] checkout = Checkout.find(checkout_id) if !checkout redirect_to :action => :list else @person = Person.find(checkout.person_id) @checkout_date = checkout.created_on end end Lastly, we must pass a checkout id as a parameter when the page is
called, because we're viewing the checkout details as well as the
movie details. Modify the ' <td><% if checkout %> <%= link_to 'Details', :action => 'details', :id => movie, :checkout => checkout %> <% end %> </td> Not only does this pass the Rails ResourcesTutorials and Reference Sites
|