• Like

Loading…

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

Ruby on Rails: an introduction

  • 1,437 views
Uploaded on

 

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,437
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
15
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide
  • David Heinemeier Hanson extracted this framework from his work on 37signals’ Basecamp (a hosted project collaboration tool) Makes Web development easy through simple conventions (rather than extensive configuration), and the “Don’t Repeat Yourself” principle (localize change): Examples: order records are known to be stored in an Orders table, no mapping required (in numerous .xml configuration files) http://localhost/order/list/100 is pointing to an Order processing component, and its list() method will be called with a value = 100 View partials contain reusable snippets to be reused over many web pages. Makes maintenance and deployment easy through enforced code structure and built-in plumbing: MVC, ORM, testing.
  • Controller: accepts HTTP requests, parses URL, extracts parameters, forwards to specific Action (bridge between Controller and Model) Model: retrieves/persists data encapsulating access and domain logic View: render and present the model in an HTML (or XML) format
  • Controller (DispatchServlet) orchestrates the application: extracts parameters from request and interacts with the model through a specific action (ActionController subclass) based solely on the URL pattern: Example: http://localhost/order/list/100 directs to OrderController (defined in order_controller.rb) and passes to the method list() the value 100. That would display row with id=100. Change list with delete and the same row gets deleted invokes the view providing the presentation and rendering of the model ActionController along with ActionView (the Action Pack) form the core processing of incoming requests and generating responses.
  • View : a combination of templates, partials and layouts all using plain Ruby code tag libraries It presents the user with various ways to display/input data but it never handles incoming data ActionView module encapsulates required functionality to render templates (i.e. generate HTML or XML) in response to user requests Writing a view = writing a template associated with an action result (i.e. HTML fragments interwoven with Ruby code statements placed between <% %>) Controller instance variables are also available in templates (actions communicating data to templates), and a template can also call any public methods on the controller .rxml templates render XML pages, while .rhtml templates render HTML pages
  • Model : ActiveRecord wrapping framework An ActiveRecord subclass wraps a row in a database table/view and encapsulates access and domain logic, and acts as the gatekeeper of the datastore. Starts with the database table, as opposed to starting with the object model as mapping frameworks usually do (i.e. Hibernate) Wraps class hierarchies to relational tables through single table inheritance: adding a string column ‘TYPE’ to the table persisting the hierarchy. Note: column name can be overridden using inheritance_column() Wraps the following table relationships ( one-to-one , one-to-many , many-to-many ) through declarations in the model ( belongs-to , has-one , has-many , has-and-belongs-to-many ), and also supports: acts_as_tree , acts_as_list Differs from other ORM implementations through its “convention over configuration” principle which implies a sensible set of defaults
  • A one-to-many aggregation representing a collection: a given order’s line item rows contain a foreign key column referring back to order. In Rails one just needs to add the has_many declaration in the parent object (logically containing the collection of child objects) showing its relationship to the child table declaring the belongs_to for its parent:
  • An act-as-tree structure can often be found in Category listings where entries have subentries, and those subentries may have their own subentries.
  • create_table :parents, :force => true do |t| end create_table :children, :force => true do |t| t.column :parent_id, :integer t.column :name, :string t.column :position, :integer end
  • Wrapping an object view of some data to certain tables in a relational database: wraps tables to classes, rows to objects, and columns to object attributes implicit conventions (customizable): Active Record expects the table name to be the plural form for the class name Active Record reflects on the database schema to configure the classes that wrap tables Active Record instance attributes generally correspond to the data in the corresponding database table row each table associated with a class has an integer primary key column named id Active Record abstracts the concept of a database connection, delegating the details to a set of database-specific adapters
  • Rails encourages an agile, iterative style of development in a Rails application the database schema constantly evolves (i.e. adding a new class/table, renaming an attribute/column), while in sync with the application’s code. ActiveRecord::Migration abstracts the data manipulation in a database table and allows reversible actions: creation: up() method removal: down() method A migration is simply a Ruby source file placed under version control alongside all our other application files. Each migration file’s name starts with (by default) three digits and an underscore, the version which defines the sequence in which the migrations are applied. Warning: migrations do not currently feature transactional support (i.e. an atomic failure inside up() may not allow the migration to be reapplied or even rolled back)
  • Scaffold , the ActionController feature providing a series of standardized actions for listing, showing, creating, updating, and destroying objects of a class/table. Static scaffold: $ ruby script/generate scaffold product admin Scaffold generator takes the model and controller names and renders standardized actions containing both controller logic and default templates (introspection provides the fields to display and types) Scaffold generator automatically creates code that will respond appropriate to requests for HTML or XML content. Scaffold-generated applications use the scaffold.css stylesheet (public/stylesheets) which could be customized/replaced. Dynamic scaffold: scaffold :product declaration tells Rails to generate the application code at runtime for immediate use in testing of a newly added model and controller web_service_scaffold() :invoke provides a way to execute web service methods from a web browser while in development.
  • Applying “tough love” on our beloved applications even before they are written: Rails framework has the support for testing baked right in from the start of every project (i.e. any top-level project directory created contains a subdirectory called test), plus a special database just for test (see database.yml ) By convention, Rails calls things testing models: unit tests things testing a single action in a controller: functional tests things testing the flow through controllers: integration tests Rails even creates the files to hold the unit tests for the models and the functional tests for the controllers created with the generate script The testing starts from the data (unit test the models) and moves up closer to where the user interaction (functional and integration)
  • Assertion : a method call stating the expectations (i.e. the simplest assertion is the method assert(), expecting its argument to be true). Unit Tests : collection of assertions that validate a model Functional Tests : collection of assertions that validate a controller’s action (example: test_delete_item) Fixtures : simply a specification of the initial contents of a model(s) under test ( test/fixtures directory). Mocks : a simple replacement for a known object that frees the tests from needing some sort of resource (network connection) while ensuring more consistent and repeatable results.
  • Webrick is sufficient in development for the single-threaded Rails Highly concurrent production environments require a front-end server (i.e. Apache, Lighttpd, or Zeus), and a proxy to distribute requests to Rails processes running on any number of back-end machines: FastCGI with its long-running processes can handle multiple sequential requests, therefore Ruby interpreter and Rails framework is loaded once per process and turn around requests for the host web server quickly. Mongrel (Ruby-based web-server) could be HTTP proxied by the front-end directly and makes for a better solution that is considered future proof and extensible It’s better to start doing deployment: early (as soon as few views already display) in order to identify any deployment issues often (after any major commit) in order to have early feedback from management and customers Capistrano, a RubyGem utility, provides reliable and repeatable deployment for Rails applications on remote servers.

Transcript

  • 1. Building a Ruby on Rails application with DB2 Express-C 9 An introduction to a sweet and trendy Web framework: Rails Markham Oct 17, 2006 Antonio Cangiano Alex Pitigoi IBM Toronto Lab
  • 2. Agenda
    • On Rails ?
    • Model – View – Controller (MVC) aspects in Rails
    • Object Relation Mapping (ORM) flavors in Rails
    • Schema evolution through Rails migrations
    • Using a scaffold to build a prototype
    • Test “contaminated” development environment
    • Deployment
  • 3. On Rails ? Moving smooth and guided.
    • Extracted from the 37signals’ project collaboration tool: Basecamp
    • Makes Web development easy through simple conventions, and the “Don’t Repeat Yourself” principle:
      • Examples:
        • order records are stored in an Orders table
        • http://localhost/order/list/100 is how you request to display the Order with ID = 100 (change list with delete and it gets removed)
        • View partials can be reused over many web pages.
    • Maintenance and deployment simplified by built-in plumbing: MVC, ORM, testing.
  • 4.
    • J2EE on Struts versus Ruby on Rails
      • stack comparison
    • Controller: processes HTTP requests extracting parameters to be passed to Action
    • Model: retrieves and persists data encapsulating access and domain logic
    • View: renders and presents the model in an HTML format
    Moving smooth on known tracks Webrick DispatchServlet Apache Tomcat Servlet Container JSP ActionForm Action Hibernate Datastore Datastore ActionServlet RHTML ActionController ActiveRecord Model Controller View
  • 5. MVC the Rails way
    • Controller (DispatchServlet) orchestrates the application:
      • extracts parameters and interacts with the Model through an ActionController subclass:
        • Example: http://localhost/item/delete/100 directs to ItemController (defined in item_controller.rb) and passes to the method delete the value 100
      • invokes the View providing the rendering of the Model
      • ActionController and ActionView form the Action Pack: core requests processing and responses generation.
  • 6. MVC the Rails way
    • View : a combination of templates, partials and layouts using Ruby code tag libraries (similar to Java tag libraries):
      • Allows data display and input, but never handles incoming data
      • ActionView module provides templates rendering (HTML or XML):
        • .rxml templates render XML pages, while
        • .rhtml templates render HTML pages
      • writing a view = writing a template (i.e. HTML fragments are interwoven with Ruby code statements)
      • Controller instance variables and public methods accessible from templates (actions communicate data to templates)
  • 7. MVC the Rails way:
    • Model : ActiveRecord wrapping framework
      • ActiveRecord subclass wraps a row in a database table/view, encapsulates access/domain logic, and acts as the gatekeeper.
      • Wraps class hierarchies to relational tables through single table inheritance (a string column ‘TYPE’ is added to every table).
      • Wraps classic table relationships ( one-to-one , one-to-many , many-to-many ) through declarations in the model ( belongs-to , has-one , has-many , has-and-belongs-to-many ), and also supports: acts_as_tree , acts_as_list
      • Differs from other ORM implementations through its “convention over configuration” principle which implies a sensible set of defaults.
  • 8. ActiveRecord: implementing one-to-one
    • A one-to-one association (one-to-zero-or-one relationship): a foreign key in a table’s row references at most a single row in another table.
    • In Rails one just adds a has_one declaration to the Order model, and a belongs_to declaration to the Invoice model:
      • class Invoice < ActiveRecord::Base
      • belongs_to :order
      • . . .
      • end
      • class Order < ActiveRecord::Base
      • has_one :invoice
      • . . .
      • end
  • 9. ActiveRecord: implementing one-to-many
    • A one-to-many aggregation representing a collection: a given order’s line item rows contain a foreign key column referring back to order.
    • In Rails one just needs to add the has_many declaration in the parent object, while the child table declares the belongs_to for its parent:
      • class LineItem < ActiveRecord::Base
      • belongs_to :order
      • . . .
      • end
      • class Order < ActiveRecord::Base
      • has_many :line_items
      • . . .
      • end
  • 10. ActiveRecord: implementing many-to-many
    • A many-to-many association where each side of the relationship contains a collection of things on the other side.
    • In Rails one just needs to add the has_and_belongs_to_many declaration to both models:
      • class Category< ActiveRecord::Base
      • has_and_belongs_to_many :products
      • . . .
      • end
      • class Product< ActiveRecord::Base
      • has_and_belongs_to_many :categories
      • . . .
      • end
  • 11. ActiveRecord: implementing act-as-tree
    • An act-as-tree structure can be achieved by adding a single column (parent_id) to a table to act as a foreign key reference back to the same table (linking child rows to their parent row).
    • In Rails one just needs to declare such structure using an acts_as_tree declaration for a table which defines the parent_id column:
      • create_table :categories, :force => true do |t|
        • t.column :name, :string
        • t.column :parent_id, :integer
        • . . .
      • end
      • class Category < ActiveRecord::Base
        • acts_as_tree :order => &quot;name“
        • . . .
      • end
  • 12. ActiveRecord: implementing act-as-list
    • An act-as-list structure defines a relation between a parent table and some children tables through a column recording position in the list and allowing: traversal, addition, removal, position change
    • In Rails one just needs to declare the belongs_to and has_many to define parent-child relation, and then add acts_as_list to define the list:
      • class Parent < ActiveRecord::Base
        • has_many :children, :order => :position
        • . . .
      • end
      • class Child < ActiveRecord::Base
        • belongs_to :parent
        • acts_as_list :scope => :parent_id
        • . . .
      • end
  • 13. ORM the Rails way: ActiveRecord
    • Wrapping an object view of some data to certain tables in a relational database:
      • wraps tables to classes, rows to objects, and columns to object attributes
      • implicit ActiveRecord conventions (customizable):
        • table name is the plural form for the class name
        • database schema reflexion configures classes that wrap tables
        • instance attributes generally correspond to the table row data
        • tables associated with a class have an integer id primary key column
        • the database connection is abstracted while the details are delegated to a set of database-specific adapters
  • 14. ActiveRecord: the intermediator
    • Makes it easy to implement the basic operations on database tables: Create , Read , Update , Delete ( CRUD )
    • Abstracts and generates dynamic SQL
      • where or like clause represented by :conditions parameter
        • Item.find(:all, :conditions => “item_type = ‘new‘” and &quot;name like ?&quot;, pa+&quot;%&quot;)
      • order clause represented by :order param
        • Item.find(:all, :order => “part_type, shipped_at DESC&quot; )
      • Similarly, it provides :limit , :offset , :joins , :select , :readonly , :from , :group , :lock
      • Built-in statistics: average , maximum , minimum , sum , count
      • Built-in common searches: find_by_ <name>, find_all_by_ <name>, etc.
  • 15. Migrations to eradicate evolution migraines
    • Rails encourages an agile, iterative style of development:
      • If a database schema constantly evolves (adding a new class/table, changing attributes/columns) it’s easy to sync the application’s code.
      • ActiveRecord::Migration interface abstracts data manipulation in a database table and allows reversible actions:
        • for creation: up() method
        • for removal: down() method
      • Migration == Ruby source file (also under version control) prefixed with the schema version ID (example: 022_add_email_column.rb ) and implementing the 2 class methods: up and down
      • Warning: migrations do not currently feature transactional support (i.e. an atomic failure inside up() may not allow the migration to be reapplied or even rolled back)
  • 16. Migrate up and down at will
    • Example:
      • class AddEmailColumnToCustomer < ActiveRecord::Migration
        • def self.up
          • add_column :customers, :e_mail, :string
        • end
        • def self.down
          • remove_column :customers, :e_mail
        • end
      • end
    • While the above code is in available in 022_add_email.rb
      • to apply: $ rake db:migrate VERSION=22
      • to roll-back: $ rake db:migrate VERSION=21
  • 17. Raise a scaffold, build the edifice
    • Scaffold: an ActionController feature to generate standardized actions for a class wrapping a table.
    • Static scaffold:
      • $ ruby script/generate scaffold product admin
      • Scaffold generator takes the model and controller names and
        • renders standardized actions
        • code generated responds to requests for HTML or XML content.
        • provides a customizable scaffold.css stylesheet in public/stylesheets
    • Dynamic scaffold:
      • scaffold :product declaration does runtime code generation for immediate use in testing of a newly added model and controller
      • web_service_scaffold() :invoke provides the simplest execution for a web service method from a web page in development.
  • 18. From scaffold to prototype
    • $ ruby script/generate scaffold product admin
      • dependency model
      • skip app/models/product.rb
      • identical test/unit/product_test.rb
      • identical test/fixtures/products.yml
      • create app/views/admin/_form.rhtml
      • create app/views/admin/list.rhtml
      • create app/views/admin/show.rhtml
      • create app/views/admin/new.rhtml
      • create app/views/admin/edit.rhtml
      • overwrite app/controllers/admin_controller.rb? [Ynaq] y
      • force app/controllers/admin_controller.rb
      • overwrite test/functional/admin_controller_test.rb? [Ynaq] y
      • force test/functional/admin_controller_test.rb
      • identical app/helpers/admin_helper.rb
      • create app/views/layouts/admin.rhtml
      • create public/stylesheets/scaffold.css
    Source: Agile Web Development with Rails 2 nd edition, Dave Thomas
  • 19. Test environment: tests pass, work done
    • Applying “tough love” on our beloved applications before they are even written:
      • Rails framework testing support baked into every project: new projects are created with a test subdirectory (and associated database)
      • By convention, Rails calls:
        • testing models: unit tests
        • testing a single action in a controller: functional tests
        • testing the flow through controllers: integration tests
      • Rails generate script creates the unit tests files for the models and the functional tests files for the controllers
      • testing starts from the data (unit test) and moves up closer to the user interaction (functional and integration)
  • 20. Assertion, test, case, suite… results
    • Assertion : a method call stating the expectations (i.e. the simplest assertion is the method assert(), expecting its argument to be true).
    • Unit Tests : collection of assertions that validate a model
    • Functional Tests : collection of assertions that validate a controller’s action (example: test_delete_item)
    • Fixtures : specification of the initial contents of a model(s) under test ( test/fixtures directory).
    • Mocks : replacement for a known object simplifying the needing for some real complex resource (network connection), while ensuring more consistent and repeatable results.
  • 21. Deployment: is there an easy way?
    • Webrick: development server for the single-threaded Rails
    • production environments (highly concurrent) require a front-end server (i.e. Apache, Lighttpd, or Zeus), + proxy to distribute requests to Rails processes running on several of back-end machines:
      • FastCGI proxy can handle multiple sequential requests to Ruby interpreter and Rails framework (one per process)
      • Mongrel (Ruby-based web-server) can proxy directly and considered a better, more extensible and scalable solution
    • Deployment principles:
      • start early (as soon as few views already display) in order to identify any deployment issues
      • do it often (after any major commit) in order to have early feedback from management and customers
    • Capistrano (RubyGem utility) provides reliable and repeatable deployment for Rails applications on remote servers.
  • 22. Deployment: few real life lessons from James Duncan
    • Make use of Capistrano, it’s better then you would first think
    • Make use of before and after hooks for the various tasks in Capistrano, to avoid overloading the deploy task
    • Ruby versions change. Set RubyGems in a GEM_HOME (e.g. /usr/local/rubygems/) to be able to reuse while upgrading Ruby
    • Don't even consider running your Rails app in CGI mode. Too slow.
    • The SCGI support in Rails is not quite ready for primetime, better use Lighty (with built in FastCGI and SCGI support)
    • For RubyGems that need to do native compilation of code the libraries should be kept in bundles outside of RubyGems if there is a need to manage multiple variants of the _same_ version.
    • If you do use Apache httpd, your options are 1.3.x or 2.0.x.
    • Don't use Ruby 1.8.3 with Rails on Mac OS X
    Source: http://blog.duncandavidson.com/2005/12/real_lessons_fo.html
  • 23. Credits and References
    • Many thanks to all of those who wrote about Rails in books and blogs and articles:
      • David Heinemeier Hanson
      • Dave Thomas
      • James Duncan
      • Bruce Tate
      • Patrick Peak
      • Aaron Rustad
    • References:
      • Agile Web Development using Rails, 2 nd edition
      • http://www.theserverside.com/tt/articles/article.tss?l=RailsHibernate
      • http://www-128.ibm.com/developerworks/java/library/j-cb03076/index.html
      • http://weblogs.java.net/blog/batate/archive/2006/01/we_should_learn.html
      • http://www-128.ibm.com/developerworks/web/library/wa-rubyonrails/
  • 24. “ Show me the code!”: Rails development environment
    • Ruby Development Tools ( RDT ) plug-in for Eclipse
      • http://updatesite.rubypeople.org/release
    • RadRails: free opensource IDE for Ruby on Rails
      • built on the Eclipse Rich Client Platform as IDE feature
        • RadRails feature: http://radrails.sourceforge.net/update
      • Includes also:
        • RDT plug-in http://updatesite.rubypeople.org/release
        • Subclipse plug-in http://subclipse.tigris.org/update_1.0.x
      • download complete setup from http://www.radrails.org/
    • Note: the lab workstations are already setup using the Starter Toolkit for DB2 on Rails : http://www.alphaworks.ibm.com/tech/db2onrails
      • Ruby, Rails, DB2 driver for Ruby, DB2 adapter for Rails, DB2 Express C
  • 25.  
  • 26. Creating a Rails project on Linux (shell commands)
    • Creating a Rails Web application:
      • <ruby_path>/bin/rails /path/to/your/app [options]
      • Example:
        • $ rails myblog
        • $ cd blog/
        • $ vi config/database.yml
          • development:
            • adapter: ibm_db2
            • database: Blog_dev
            • username: userID
            • password: passwd
            • schema: myschema
        • $ ruby ./script/generate migration InitialSchema
        • $ vi db/migrate 001_initial_schema.rb
        • $ rake migrate
        • $ ruby script/generate scaffold post
  • 27. Creating a Rails project on Windows
    • Rails perspective:
      • File / New …
      • Rails / Rails project
    • Defaults will generate also the Web application tree and the WEBrick test server
    Rails tutorials http://manuals.rubyonrails.com/