15 1 Overview of Rails Rails is a

  • Slides: 39
Download presentation
15. 1 Overview of Rails - Rails is a development framework for Web-based applications

15. 1 Overview of Rails - Rails is a development framework for Web-based applications - Rails is written in Ruby and uses Ruby for its applications - Ruby on Rails (Ro. R) - Based on MVC architecture for applications - MVC cleanly separates applications into three parts: - Model – the data and any restraints on it - View – prepares and presents results to the user - Controller – controls the application - One characterizing part of Rails is its approach to connecting object-oriented software with a relational database – ORM - Maps tables to classes, rows to objects, and columns to fields of the objects Chapter 15 © 2010 by Addison Wesley Longman, Inc. 1

15. 1 Overview of Rails (continued) - View documents are XHTML documents that may

15. 1 Overview of Rails (continued) - View documents are XHTML documents that may include Ruby code - Most of the controller code is provided by Rails - A Rails application is a program that provides a response when a client browser connects to a Rails-driven Web site - Rails can be used with Ajax - Two fundamental principles that guided the development of Rails: 1. DRY 2. Convention over configuration - Rails does not use a GUI - One simple way to get started with Rails is to download a complete development system http: //instantrails. rubyforge. org/wiki. pl - Includes Ruby, Rails, My. SQL, Apache and everything else that is necessary Chapter 15 © 2010 by Addison Wesley Longman, Inc. 2

15. 2 Document Requests - Instant. Rails is self-contained – not run through a

15. 2 Document Requests - Instant. Rails is self-contained – not run through a Windows command window - Static Documents - To use Rails: 1. Click the thick I in the directory where Rails was installed 2. Click the black I in the upper left part of the resulting window 3. Select Rails Application to open an other menu 4. Select Open Ruby Console Window - Opens a command-line window - If IIS is running, it must be stopped; ditto for My. SQL - After creating a directory in rails_apps for all related Rails applications, use the rails command in that directory to create a specific application (in our example, greet) >rails greet - This creates the framework for the new application (more than 45 files in 30 directories) - The app subdirectory has four subdirectories, models, views, controllers, and helpers Chapter 15 © 2010 by Addison Wesley Longman, Inc. 3

15. 2 Document Requests (continued) - Static Documents (continued) - The generate script can

15. 2 Document Requests (continued) - Static Documents (continued) - The generate script can be used to create part of the controller for the application >ruby script/generate controller say - The created controller will have the name say - There are now two files with empty classes in the controller directory, application. rb, and say_controller. rb. These contain Application. Controller and Say. Controller class Say. Controller < Application. Controller end - Next, add an empty method to the Say. Controller class def hello end - The URL of the Rails application is http: //localhost: 3000/say/hello Chapter 15 © 2010 by Addison Wesley Longman, Inc. 4

15. 2 Document Requests (continued) - Static Documents (continued) - Next, build the view

15. 2 Document Requests (continued) - Static Documents (continued) - Next, build the view file, or template, which must reside in the say subdirectory of the views directory of the application and be named hello. html. erb - This is an XHTML document with the following in its body element <h 1> Hello from Rails! </h 1> - To test the application, a Web server must be started >ruby script/server - This starts the default server, named Mongrel - Now, pointing the browser to the application produces the displayed view template content Chapter 15 © 2010 by Addison Wesley Longman, Inc. 5

15. 2 Document Requests (continued) - Static Documents (continued) - Response activities: 1. Instantiate

15. 2 Document Requests (continued) - Static Documents (continued) - Response activities: 1. Instantiate Say. Controller class 2. Call the hello action method 3. Search the views/say directory for hello. html. erb 4. Process hello. html. erb with Erb 5. Return the resulting hello. html. erb to the requesting browser Chapter 15 © 2010 by Addison Wesley Longman, Inc. 6

15. 2 Document Requests (continued) - Dynamic Documents - Dynamic documents can be built

15. 2 Document Requests (continued) - Dynamic Documents - Dynamic documents can be built with Rails by embedding Ruby code in the template document - An example: display a greeting and the current date and time and the number of seconds since midnight - Ruby code is embedded in a document by placing it between <% and %> - To insert the result of evaluating the code into the document, use <%= - The Time class has a method, now, that returns the current day of the week, month, day of the month, time zone, and year, as a string It is now <%= t = Time. now %> Number of seconds since midnight: <%= t. hour * 3600 + t. min * 60 + t. sec %> Chapter 15 © 2010 by Addison Wesley Longman, Inc. 7

15. 2 Document Requests (continued) - Dynamic Documents (continued) - It would be better

15. 2 Document Requests (continued) - Dynamic Documents (continued) - It would be better to put the code in the controller def hello @t = Time. now @tsec = @t. hour * 3600 + @t. min * 60 + @t. sec end - Now the Ruby code in the template is: It is now <%= @t %> Number of seconds since midnight: <%= @tsec %> Chapter 15 © 2010 by Addison Wesley Longman, Inc. 8

15. 3 Rails Applications with Databases - We will use My. SQL - Use

15. 3 Rails Applications with Databases - We will use My. SQL - Use a simple database with just one table - The application will be named cars - The application will present a welcome document to the user, including the number of cars in the database and a form to get the beginning and ending years and a body style for the desired car - Creating the application - In the subdirectory of our examples: >rails –d mysql cars - It is customary to use three databases in a Rails database application: one for development, one for testing, and one for production - To create three (empty) databases: >rake db: create: all - Creates the database. yml file in the config subdirectory of the application directory (cars) - See next page Chapter 15 © 2010 by Addison Wesley Longman, Inc. 9

15. 3 Rails Applications with Databases (continued) # My. SQL. Versions 4. 1 and

15. 3 Rails Applications with Databases (continued) # My. SQL. Versions 4. 1 and 5. 0 are recommended. # development: adapter: mysql encoding: utf 8 database: cars_development username: root password: host: localhost test: adapter: mysql encoding: utf 8 database: cars_test username: root password: host: localhost production: adapter: mysql encoding: utf 8 database: cars_production username: root password: host: localhost Chapter 15 © 2010 by Addison Wesley Longman, Inc. 10

15. 3 Rails Applications with Databases (continued) - Build the model, migration script, database

15. 3 Rails Applications with Databases (continued) - Build the model, migration script, database table, and maintenance controller for the database >ruby script/generate scaffold Corvette body_style: string miles: float year: integer - The migration class built by this in cars/db/migrate is: class Create. Corvettes < Active. Record: : Migration def self. up create_table : corvettes do |t| t. string : body_style t. float : miles t. integer : year t. timestamps end def self. down drop_table : corvettes end - We do not have a database—only the description (a migration class) of a database - To create the database, use rake again: >rake db: migrate Chapter 15 © 2010 by Addison Wesley Longman, Inc. 11

15. 3 Rails Applications with Databases (continued) - This second rake command, which executes

15. 3 Rails Applications with Databases (continued) - This second rake command, which executes the self. up method of Create. Corvettes class, produces the following response: (in C: /myrails/rails_apps/examples/cars) == 1 Create. Corvettes: migrating======= -> 0. 2030 s == 2 Create. Corvettes: migrated (0. 3440 s) ==== - The controller for the application is named corvettes, so we can see the application at http: //localhost: 3000/corvettes - Rails built the basic table maintenance operations, create, read, update, and delete (CRUD) Chapter 15 © 2010 by Addison Wesley Longman, Inc. 12

15. 3 Rails Applications with Databases (continued) - If we click New corvette, we

15. 3 Rails Applications with Databases (continued) - If we click New corvette, we get: Chapter 15 © 2010 by Addison Wesley Longman, Inc. 13

15. 3 Rails Applications with Databases (continued) - If we fill out the form,

15. 3 Rails Applications with Databases (continued) - If we fill out the form, as in: - Now we click Create, which produces: Chapter 15 © 2010 by Addison Wesley Longman, Inc. 14

15. 3 Rails Applications with Databases (continued) - Now if we click Back, we

15. 3 Rails Applications with Databases (continued) - Now if we click Back, we get: - If we click Edit, we get: Chapter 15 © 2010 by Addison Wesley Longman, Inc. 15

15. 3 Rails Applications with Databases (continued) - If we click Destroy, we get:

15. 3 Rails Applications with Databases (continued) - If we click Destroy, we get: - The model file, which is in cars/models, has the empty class: class Corvette < Active. Record: : Base end - We can easily add some validation to this class validate_presence_of : body_style, : miles, : year Chapter 15 © 2010 by Addison Wesley Longman, Inc. 16

15. 3 Rails Applications with Databases (continued) - The model class is now: class

15. 3 Rails Applications with Databases (continued) - The model class is now: class Corvette < Active. Record: : Base validate_presence_of : body_style, : miles, : year validates_numericality_of : year, : greater_than => 1952, : less_than_or_equal_to => Time. now. year end - The controller built by Rails, named Corvette. Controller, provides the action methods: index – creates a list of rows of the table show – creates the data for one row new – creates a new row object edit – handles editing a row create – handles row creation update – handles updating a row delete – handles row deletion - There are four documents in the views directory, index. html. erb, new. html. erb, show. html. erb, and edit. html. erb Chapter 15 © 2010 by Addison Wesley Longman, Inc. 17

15. 3 Rails Applications with Databases (continued) <h 1>Listing corvettes</h 1> <table> <tr> <th>Body

15. 3 Rails Applications with Databases (continued) <h 1>Listing corvettes</h 1> <table> <tr> <th>Body style</th> <th>Miles</th> <th>Year</th> </tr> <% for corvette in @corvettes %> <tr> <td><%=h corvette. body_style %></td> <td><%=h corvette. miles %></td> <td><%=h corvette. year %></td> <td><%= link_to 'Show', corvette %></td> <td><%= link_to 'Edit', edit_corvette_path(corvette) %></td> <td><%= link_to 'Destroy', corvette, : confirm => 'Are you sure? ', : method => : delete %></td> </tr> <% end %> </table> <%= link_to 'New corvette', new_corvette_path %> Chapter 15 © 2010 by Addison Wesley Longman, Inc. 18

15. 3 Rails Applications with Databases (continued) - Notice that index. html. erb is

15. 3 Rails Applications with Databases (continued) - Notice that index. html. erb is only the content of the body element - The rest of the document comes from a layout document, which is stored in the layout subdirectory of views – built by scaffold <!DOCTYPE html PUBLIC "-//W 3 C//DTD XHTML 1. 0 Transitional//EN" "http: //www. w 3. org/TR/xhtml 1/DTD/ xhtml 1 -transitional. dtd"> <html xmlns="http: //www. w 3. org/1999/xhtml" xml: lang="en"> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <title>Corvettes: <%= controller. action_name %></title> <%= stylesheet_link_tag 'scaffold' %> </head> <body> <p style="color: green"><%= flash[: notice] %> </p> <%= yield %> </body> </html> Chapter 15 © 2010 by Addison Wesley Longman, Inc. 19

15. 3 Rails Applications with Databases (continued) - The new. html. erb document is:

15. 3 Rails Applications with Databases (continued) - The new. html. erb document is: <h 1>New corvette</h 1> <%= error_messages_for : corvette %> <% form_for(@corvette) do |f| %> <p> <b>Body style</b> <%= f. text_field : body_style %> </p> <b>Miles</b> <%= f. text_field : miles %> </p> <b>Year</b> <%= f. text_field : year %> </p> <b>State</b> <%= f. text_field : state %> </p> <%= f. submit "Create" %> </p> <% end %> <%= link_to 'Back', corvettes_path %> Chapter 15 © 2010 by Addison Wesley Longman, Inc. 20

15. 3 Rails Applications with Databases (continued) - The show. html. erb document is:

15. 3 Rails Applications with Databases (continued) - The show. html. erb document is: <p> <b>Body style: </b> <%=h @corvette. body_style %> </p> <b>Miles: </b> <%=h @corvette. miles %> </p> <b>Year: </b> <%=h @corvette. year %> </p> <b>State: </b> <%=h @corvette. state %> </p> <%= link_to 'Edit', edit_corvette_path(@corvette) %> <%= link_to 'Back', corvettes_path %> Chapter 15 © 2010 by Addison Wesley Longman, Inc. 21

15. 3 Rails Applications with Databases (continued) - The edit. html. erb document is:

15. 3 Rails Applications with Databases (continued) - The edit. html. erb document is: <h 1>Editing corvette</h 1> <%= error_messages_for : corvette %> <% form_for(@corvette) do |f| %> <p> <b>Body style</b> <%= f. text_field : body_style %> </p> <b>Miles</b> <%= f. text_field : miles %> </p> <b>Year</b> <%= f. text_field : year %> </p> <b>State</b> <%= f. text_field : state %> </p> <%= f. submit "Update" %> </p> <% end %> <%= link_to 'Show', @corvette %> | <%= link_to 'Back', corvettes_path %> Chapter 15 © 2010 by Addison Wesley Longman, Inc. 22

15. 3 Rails Applications with Databases (continued) - Now we must build the actual

15. 3 Rails Applications with Databases (continued) - Now we must build the actual application - Build a second controller for the required processes >ruby script/generate controller main - Add an action method for the welcome screen # main_controller. rb - for the cars application class Main. Controller < Application. Controller # welcome method # fetches the value for the initial view def welcome @num_cars = Corvette. count end - The count method of the table classes returns the number of rows in the table Chapter 15 © 2010 by Addison Wesley Longman, Inc. 23

15. 3 Rails Applications with Databases (continued) - To implement the searches of the

15. 3 Rails Applications with Databases (continued) - To implement the searches of the table, use find - The find method searches a table for a specific row mycar = Corvette. find(8) list_five = [1, 2, 3, 4, 5] first_five = Corvette. find(list_five) The Record. Not. Found exception is thrown if find is asked to do something it cannot do The find method can take more complex parameters sixty_five_conv = find(: all, : conditions => "year = 1965 and body_style = 'convertible'") - To use find with non-literal conditions, a different parameter form is needed some_year_conv = find(: all, : conditions => ["year = ? and body_style = 'convertible'", @year]) - If the first parameter is : first, it gets only the first row that meets the specified condition Chapter 15 © 2010 by Addison Wesley Longman, Inc. 24

15. 3 Rails Applications with Databases (continued) - Next, design the welcome template, which

15. 3 Rails Applications with Databases (continued) - Next, design the welcome template, which has two tasks: 1. Display text boxes to get the model years and body style of interest from the user 2. Display the number of cars furnished by the welcome action method in the controller <!– welcome. html. erb – initial view for the cars application --> <!– The initial information --> <p> <h 1> Aidan’s Used Car Lot </h 1> <h 2> Welcome to our home document </h 2> We currently have <%= @num_cars %> used Corvettes listed To request information on available cars, please fill out the following form and submit it </p> <!– The form to collect input from the user about their interests --> <form action = "result" method = "post"> From year: <input type = "text" size = "4" name = "year 1" /> To year: <input type = "text" size = "4" name = "year 2" /> Body style: <input type = "text" size = "12" name = "body" /> <input type = "submit" value = "Submit" /> <input type = "reset" value = "Reset" /> </form> Chapter 15 © 2010 by Addison Wesley Longman, Inc. 25

15. 3 Rails Applications with Databases (continued) - Next, design the result action method,

15. 3 Rails Applications with Databases (continued) - Next, design the result action method, which is named result in the welcome template form - Task: get form data and use find to compute the required output data for the result template - The form data is made available by Rails through a hash-like object params - params can be indexed by either keys or symbols If phone is the name of a control, we can use: @phone = params[: phone] - The result method of the main controller is: # result method - fetches values for the result # template def result @year 1 = params[: year 1]. to_i @year 2 = params[: year 2]. to_i @body = params[: body] @selected_cars = Corvette. find(: all, : conditions => ["year >= ? and year <= ? and body_style = ? ", @year 1, @year 2, @body]) end Chapter 15 © 2010 by Addison Wesley Longman, Inc. 26

15. 3 Rails Applications with Databases (continued) - Last step: build the result template

15. 3 Rails Applications with Databases (continued) - Last step: build the result template document - Put the information about cars from @selected_cars in a table <!-- Display what the user asked for --> <p> Cars from <%= h(@year 1) %> to <%= h(@year 2) %> with the <%= h(@body) %> body style </p> <!-- Display the results in a table --> <table border = "border"> <tr> <th> Body Style </th> <th> Miles </th> <th> Year </th> </tr> <!-- Put the cars of @selected_cars in table --> <% @selected_cars. each do |car| <tr> <td> <%= car. body_style %> </td> <%= car. miles %> </td> <%= car. year %> </td> </tr> <% end %> <!-- end of do loop --> </table> Chapter 15 © 2010 by Addison Wesley Longman, Inc. 27

15. 3 Rails Applications with Databases (continued) - A filled out request: - The

15. 3 Rails Applications with Databases (continued) - A filled out request: - The result document: Chapter 15 © 2010 by Addison Wesley Longman, Inc. 28

15. 3 Rails Applications with Databases (continued) - Modifying a database - Rails was

15. 3 Rails Applications with Databases (continued) - Modifying a database - Rails was designed for agile development, so it makes it easy to change to new versions of databases, and also to revert back to earlier versions - The name of the initial version of the migration for the corvettes table was 20091018031809_create_corvettes. rb (it is in db/migrate) - To change a database table, a new migration file is created and rake is used to update the table - To illustrate a change, we add a state column to the corvettes table - To create the new migration file: >ruby script/generate migration Add. State. To. Corvette state: string - Produces the response: exists db/migrate create db/migrate/ 20091018033700_add_state_to_corvettes. rb Chapter 15 © 2010 by Addison Wesley Longman, Inc. 29

15. 3 Rails Applications with Databases (continued) - Modifying a database (continued) - The

15. 3 Rails Applications with Databases (continued) - Modifying a database (continued) - The resulting migration class, named 20091018033700_add_state_to_corvette. rb: class Add. State. To. Corvette < Active. Record: : Migration def self. up add_column : corvettes, : state, : string end def self. down remove_column : corvettes, : state end - Now use rake to apply the migration to the table: >rake db: migrate - Rails response: (in c: myrailsrails_appsexamplescars) == 1 Add. State. To. Corvette: migrating ====== -- add_column(: corvettes, : state, : string) -> 0. 3750 s == 2 Add. State. To. Corvette: migrated (0. 5160 s) === Chapter 15 © 2010 by Addison Wesley Longman, Inc. 30

15. 3 Rails Applications with Databases (continued) - Modifying a database (continued) - Now

15. 3 Rails Applications with Databases (continued) - Modifying a database (continued) - Now the display of corvettes is: - To go back to the last migration form: >rake db: rollback - To go back to any migration: >rake db: migrate VERSION=1 - Layouts - Rails provided one for the corvettes controller - We could build one for the main controller - Include the DOCTYPE, some headings, and a footer for a copyright Chapter 15 © 2010 by Addison Wesley Longman, Inc. 31

15. 3 Rails Applications with Databases (continued) <!DOCTYPE html PUBLIC "-//W 3 C//DTD XHTML

15. 3 Rails Applications with Databases (continued) <!DOCTYPE html PUBLIC "-//W 3 C//DTD XHTML 1. 0 Transitional//EN" "http: //www. w 3. org/TR/xhtml 1/DTD /xhtml 1 -transitional. dtd"> <html xmlns="http: //www. w 3. org/1999/xhtml" xml: lang="en"> <head> <title> Main </title> </head> <body> <h 1> Aidan's Used Car Lot </h 1> <h 2> Welcome to our home document </h 2> <%= yield %> <hr/> <p> Copyright 2009, AUCL, Inc. </p> </body> </html> - We could also add a stylesheet for the templates of main - Could be used for both the actual template file and the layout /* mainstyles. css - a style sheet for the main controller */ h 1 {font-style: italic; color: blue; } h 2 {color: blue; }. labels {font-style: italic; color: red; } - Stored in the cars/public/stylesheets directory Chapter 15 © 2010 by Addison Wesley Longman, Inc. 32

15. 3 Rails Applications with Databases (continued) - To reference the stylesheet in the

15. 3 Rails Applications with Databases (continued) - To reference the stylesheet in the layout, add the following to the head of the layout document <%= stylesheet_link_tag "mainstyles" %> - The form of the main template must be changed to use the styles <form action = "result" method = "post" > <span class = "labels"> From year: </span> <input type = "text" size = "4" name = "year 1" /> <span class = "labels"> To year: </span> <input type = "text" size = "4" name = "year 2" /> <span class = "labels"> Body style: </span> <input type = "text" size = "12" name = "body" /> <input type = "submit" value = "Submit request" /> <input type = "reset" value = "Reset form" /> </form> Chapter 15 © 2010 by Addison Wesley Longman, Inc. 33

15. 3 Rails Applications with Databases (continued) - Now the welcome template appears as:

15. 3 Rails Applications with Databases (continued) - Now the welcome template appears as: Chapter 15 © 2010 by Addison Wesley Longman, Inc. 34

15. 4 Rails with Ajax - There is a library of Java. Script utilities

15. 4 Rails with Ajax - There is a library of Java. Script utilities named Prototype, which has much of what is needed - To access it, place the following in the Rails template document: <%= javascript_include_tag "prototype" %> - Problems with using Rails and Ajax - Not all elements can be modified or replaced on all browsers using only the Rails tools - A simple solution: Use div elements for content that is to be replaced using Ajax - Rails implements Ajax as follows: 1. Triggered by a user event or a timer 2. Data associated with the event is sent asynchronously to a controller method (an action handler) on the server using an XHR object 3. The controller action handler performs some operation and returns text or markup 4. Java. Script on the browser receives the response and performs the update to the document Chapter 15 © 2010 by Addison Wesley Longman, Inc. 35

15. 4 Rails with Ajax (continued) - Example – popcorn form, again - The

15. 4 Rails with Ajax (continued) - Example – popcorn form, again - The application is named popcorn. A, the controller is named popcorn, and the controller class is named Popcorn. Controller - The initial action method (and the view template) are named show_form SHOW show_form. html. erb - Rails uses several different helper methods to trigger the Ajax process, most commonly link_to_remote and observe_field - These are Java. Script functions wrapped in Ruby methods - observe_field can take many parameters - First parameter - a literal string with the id of the control element to watch - Other parameters appear as the elements of a hash literal - The name of the action method: : url => (: action => process_form) Chapter 15 © 2010 by Addison Wesley Longman, Inc. 36

15. 4 Rails with Ajax (continued) - Example (continued) - More parameters : update

15. 4 Rails with Ajax (continued) - Example (continued) - More parameters : update - When : update is specified, the controller action given in : url produces the response using the render method - The : text parameter is passed to render : text is set (with =>) to a string value render : text => " <p> … </p>" : with - A Java. Script expression giving the first parameter for the XHR request object e. g. , "’zip’=value" : frequency - The frequency in seconds at which changes to the specified widget will be detected - Not setting a frequency causes an event to be used, instead of a timer (changed for text boxes and click for buttons), rather than time-based observations. Chapter 15 © 2010 by Addison Wesley Longman, Inc. 37

15. 4 Rails with Ajax (continued) - Example (continued) : complete, : success, :

15. 4 Rails with Ajax (continued) - Example (continued) : complete, : success, : failure - To specify the callback function to be called when the Ajax operation is completed - Complete example call to observer_field: <%= observe_field("my_button", : update => "name" : url => {: action => process_form}) %> - Recall that the controller action method for the application gets the response, splits it, and updates the text boxes for city and state - This code is the content of a javascript_tag, because it will be in a view template, which is an html. erb file <%= javascript_tag <<-END function update_city_state(xhr) { result = xhr. response. Text. split(', '); document. get. Element. By. Id('city'). value = result[0]; document. get. Element. By. Id('state'). value = result[1]; } END %> Chapter 15 © 2010 by Addison Wesley Longman, Inc. 38

15. 4 Rails with Ajax (continued) - Example (continued) - Because this application updates

15. 4 Rails with Ajax (continued) - Example (continued) - Because this application updates two elements, : update is not used; rather, the name of the update function is given with complete <$= observe_field("zip", : url => {: action => : fill_city_state}, : complete => 'update_city_state(request); ', : with => 'zip' ) %> - The Controller - The action method, fill_city_state, generates the city and state for the form, given the zip code as a POST parameter SHOW popcorn_controller. rb - In a Rails application, the new partial document could be produced by either the controller method or in the template document - If the template does it, the action method of the controller must include render(: layout => false) - If the action method does it, it uses render Chapter 15 © 2010 by Addison Wesley Longman, Inc. 39