topic n: ruby on rails
TRANSCRIPT
![Page 1: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/1.jpg)
SEG4110 – Advanced Software Design and Reengineering
TOPIC NRuby on Rails
![Page 2: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/2.jpg)
SEG4110 - Topic N - Ruby on Rails 2
What is Ruby on Rails?
•Ruby is an object-oriented programming language-Incorporates ideas from Smalltalk, Java, etc.
-Very pure
•Rails is a Ruby framework for creating web applications quickly and easily
![Page 3: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/3.jpg)
SEG4110 - Topic N - Ruby on Rails 3
The Ruby language - basicsAn open-source, dynamic language•Created by Yukihiro “matz” Matsumoto
—Originated in 2001, Public release in 2005
•Supported by a large community
Main website:•www.ruby-lang.org
Rapidly growing library and online resources•http://rubyforge.org/softwaremap/trove_list.php
•http://www.sapphiresteel.com/The-Little-Book-Of-Ruby
Store programs in files with extension .rb•Or run the irb interpreter
![Page 4: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/4.jpg)
SEG4110 - Topic N - Ruby on Rails 4
Until last year, the fastest growing language http://www.tiobe.com/tpci.htm
![Page 5: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/5.jpg)
SEG4110 - Topic N - Ruby on Rails 5
Ruby: Flexibility, simplicity and power• Everything is an object•Inherits from the Smalltalk legacy
• No variable declarations needed
• Dynamic typing
• ‘Blocks’ allow you to define new control structures
• ‘Mixins’ (modules) give power of multiple inheritance without the drawbacks.
• Code can be added to a class dynamically
• Easy to•Add C code (or code in another language)•Extend the language
![Page 6: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/6.jpg)
SEG4110 - Topic N - Ruby on Rails 6
Defining functions
def helloworld puts "Hello World"end
def hello(arg) puts "hello "+argend
Example runshello "Tim”hello ("Tim") # preferred - usually helps prevent bugs
![Page 7: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/7.jpg)
SEG4110 - Topic N - Ruby on Rails 7
A few more details 1
Placeholder substitution – works with "", but not with ' ' puts "hello #{arg} Your argument is #{arg.length} long!"
Default argument to a method – and concatenationdef hello(arg="World") puts "hello "+argend
Defining an arrayx=[1, 2 ,3]y= %w(an array of strings with the words of this phrase)
Sorting - the ! Means alter (side-effect) the objectx.sort!
![Page 8: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/8.jpg)
SEG4110 - Topic N - Ruby on Rails 8
A few more details 2To access array elementsx [1..3] #elements 0 to 3x [1,3] # elements 0 for 3x [-3,1] # from 3rd-from-the-end for 1
Non numeric collections are called hashesz = Hash.newz [‘SEG4210’] = ‘Advanced Software Engineering’anotherhash = {‘test’ => 12334, ‘test2’ => 98776}
A Ruby method will always return the value of the last expression evaluated•Although using ‘return’ is good practice for clarity
Use ` to execute a program in the operating system`ls`
![Page 9: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/9.jpg)
SEG4110 - Topic N - Ruby on Rails 9
A few more details 3
Symbols•E.g. :all•Represent specific language keywords used in various contexts
![Page 10: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/10.jpg)
SEG4110 - Topic N - Ruby on Rails 10
Iteration
@names.each do |name| print nameend
For number in [1,2,3] do print numberend
while tired sleepend
Ruby has various other allowed syntaxes, including allowing { }
![Page 11: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/11.jpg)
SEG4110 - Topic N - Ruby on Rails 11
“Duck typing”
In Ruby you don't declare the type of a variable•You can put any object in a variable.•You can determine the type in order to make a decision
if @names.respond_to?("join")
“if it talks like a duck, it is a duck”
![Page 12: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/12.jpg)
SEG4110 - Topic N - Ruby on Rails 12
Defining a class The initialize method is used to construct the object•@name is an instance variable•all instance variables are private by default
class Greeter def initialize(name = "World") @name = name end
def say_hi puts "Hi #{@name}!" endend
To create an objectg = Greeter.new("Pat")
![Page 13: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/13.jpg)
SEG4110 - Topic N - Ruby on Rails 13
Attributes: To make instance variables public
attr_accessor :name, :studentNumber
Now I can say in another classg.name="Tim"
andg.name
I can also separately sayattr_reader :studentNumberattr_writer :age
![Page 14: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/14.jpg)
SEG4110 - Topic N - Ruby on Rails 14
Creating a subclass
def specialGreeter < greeter
To call the same method with same arguments in a superclasssuper
![Page 15: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/15.jpg)
SEG4110 - Topic N - Ruby on Rails 15
Class variables (static variables)
@@defaultSize = 5
![Page 16: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/16.jpg)
SEG4110 - Topic N - Ruby on Rails 16
Introspection
Greeter.instance_methods
["method", "send", "object_id", "singleton_methods", "say_hi", "__send__", "equal?", "taint", "frozen?", "instance_variable_get", "kind_of?", "to_a", "hello", "instance_eval", "type", "protected_methods", "extend", "eql?", "display", "instance_variable_set", "hash", "is_a?", "to_s", "class", "tainted?", "private_methods", "untaint", "id", "inspect", "dello", "==", "===", "clone", "public_methods", "respond_to?", "freeze", "__id__", "=~", "methods", "nil?", "dup", "instance_variables", "instance_of?"]
Note that the "hello" method we defined earlier is here•It is inherited from class Object
Inspecting an objectg.inspect or p(g)
![Page 17: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/17.jpg)
SEG4110 - Topic N - Ruby on Rails 17
Dynamic classes
Ruby is a very dynamic language•You can modify a class at any time!•Add new methods, variables, etc.
![Page 18: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/18.jpg)
SEG4110 - Topic N - Ruby on Rails 18
Modules - have some similarities to interfaces
You can achieve multiple inheritance by simply adding “mixin” modules to several classes
module MyModule def func(arg) doSomethingWith arg endend
def myclass include MyModule …end
Modules also provide namespaces
![Page 19: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/19.jpg)
SEG4110 - Topic N - Ruby on Rails 19
Loading modules from files
require (MyModule.rb)
Standard modules already loaded in every Ruby class
Comparable, EnumerableFileTestGC, KernelMathObjectSpace, Precision, Process, Signal
Use notation: X::Y to refer to class X in module Y
![Page 20: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/20.jpg)
SEG4110 - Topic N - Ruby on Rails 20
The Ruby on Rails frameworkMakes it easy to develop web applications•Most manipulate data in a database such as MySQL or Postgres
•Can also manipulate flat files
Integrates with AJAX
Suggested book: Agile Web Development with Rails•By
—Dave Thomas—and David Heinemeier Hansson (creater of Rails)
•Second edition Jan 2007, www.pragprog.com
![Page 21: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/21.jpg)
SEG4110 - Topic N - Ruby on Rails 21
Rails philosophies
Model-View-Controller (MVC)•Separation of the data from the presentation from the control logic
Don’t Repeat Yourself•E.g. define your database structure in just one place
Convention over Configuration•Sensible defaults
Agility•The application can be quickly changed
![Page 22: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/22.jpg)
SEG4110 - Topic N - Ruby on Rails 22
Models MVC
Models•Whatever is shown in the class diagram plus business rules
•The Ruby model and the Database are separated using ORM (Object Relational Mapping)
•Avoids any need to embed SQL code in an application
![Page 23: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/23.jpg)
SEG4110 - Topic N - Ruby on Rails 23
Active Record as the basis for the Model
Database tables map to Rails classes•Rows map to objects
require 'active_record’
# The following is generated from the database and attributes are filled # in from database columnsclass Order < ActiveRecord::Base end
order = Order.find(1)order.discount = 0.5order.save
![Page 24: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/24.jpg)
SEG4110 - Topic N - Ruby on Rails 24
Querying the model in Ruby code
Order.find(:all, :conditions => "name='dave'" ).each do |order| puts order.amountend
![Page 25: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/25.jpg)
SEG4110 - Topic N - Ruby on Rails 25
The View - Three mechanisms
rhtml•Embedded Ruby code in html, using Erb (embedded Ruby)
rxml•Construct XML using Ruby code
rjs•Create javascript in Ruby code to create AJAX applications
•The JavaScript runs in the client, of course
![Page 26: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/26.jpg)
SEG4110 - Topic N - Ruby on Rails 26
The Controller
Routes http requests to Ruby methods•Allows you to create people-friendly URLs
Manages Caching•Database data stored in memory for a speed boost
Manages Sessions•E.g. a shopping session
![Page 27: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/27.jpg)
SEG4110 - Topic N - Ruby on Rails 27
Getting started
You need to install•Ruby•Rails•A database•I leave it to the TA and/or reference manuals to do that
The hard part of application development is now done!!
![Page 28: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/28.jpg)
SEG4110 - Topic N - Ruby on Rails 28
Really getting startedCreate a new empty default application with the commandrails myapplication
This will install directories neededREADME components/ doc/ public/ tmp/Rakefile config/ lib/ script/ vendor/app/ db/ log/ test/
app contains controllers/, models/ and views/
Start the built-in serverruby script/server
![Page 29: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/29.jpg)
SEG4110 - Topic N - Ruby on Rails 29
Here’s what the default application looks like
![Page 30: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/30.jpg)
SEG4110 - Topic N - Ruby on Rails 30
Next step: Add a controller
ruby script/generate controller Airline
This will generate an empty (hook, or stub) class •airline_controller.rb
class AirlineController < ApplicationControllerend
Now let us add a method addflight to the Airline class def addflight end
We would call this from a URL as followshttp://www.mysite.ca/airline/addflight
![Page 31: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/31.jpg)
SEG4110 - Topic N - Ruby on Rails 31
Next step: Add a view using the Erb/rhtml approach
We need a ‘template’ file called addflight.rhtml
<html> <head> <title>Add a flight/title> </head> <body> <h1>Add a flight</h1> <%= AirlineView.addFlightForm %> </body></html>
![Page 32: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/32.jpg)
SEG4110 - Topic N - Ruby on Rails 32
Some things you can embed in rhtml code
Create an href to another ruby action <%= link_to "Airline help", :action => "help" %>
![Page 33: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/33.jpg)
SEG4110 - Topic N - Ruby on Rails 33
We need to actually build a database to go any further
It is possible that the database is already there•But Ruby provides nice facilities for setting up a database incrementally in Ruby code
First create an empty database using your database package•MySQL is the easiest
Next test that Ruby can connectrake db:migrate
![Page 34: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/34.jpg)
SEG4110 - Topic N - Ruby on Rails 34
Creating a simple database
The rule is one table per classruby script/generate model regularflight
You will then find a filedb/migrate/file 001_create_regularflights.rb
class CreateRegularflights < ActiveRecord::Migration def self.up create_table :regularFlights do |t| t.column :number, :integer t.column :departuretime, :string t.column :origin, :string t.column :destination, :string endend
![Page 35: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/35.jpg)
SEG4110 - Topic N - Ruby on Rails 35
Next steps
Make Ruby upgrade the databaserake db:migrate
Now create a controller adminruby script/generate controller admin
And edit app/controllers/admin_controller.rbclass AdminController < ApplicationControllerscaffold :regularflightend
Go to http://www.mysite.ca/airline/adminAnd you will see a page where you can add flights
![Page 36: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/36.jpg)
SEG4110 - Topic N - Ruby on Rails 36
Making Ruby upgrade the database:Adding a new column
class AddPrice < ActiveRecord::Migration def self.up add_column :products, :price, :decimal, :precision => 8, :scale => 2, :default => 0 end
def self.down remove_column :products, :price end
end
![Page 37: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/37.jpg)
SEG4110 - Topic N - Ruby on Rails 37
Ruby on Rails’ naming
If you have a table called People, RoR will generate a class called Person and vice-versa
Other transformations:•Specific_flights <-> SpecificFlight•Person_roles <-> PersonRole
![Page 38: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/38.jpg)
SEG4110 - Topic N - Ruby on Rails 38
Enhancing model classes
When we create a new class/table the model code for the class is empty:
class Product < ActiveRecord::Baseend
![Page 39: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/39.jpg)
SEG4110 - Topic N - Ruby on Rails 39
Validation
If we want to force certain data to be present
class Product < ActiveRecord::Base
validates_presence_of :title, :description, :image_url
end
The generated web page for adding products will automatically ensure this data is filled in•Fields with errors are highlighted•Errors are summarized at the top of the form
![Page 40: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/40.jpg)
SEG4110 - Topic N - Ruby on Rails 40
Example generated web page
![Page 41: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/41.jpg)
SEG4110 - Topic N - Ruby on Rails 41
Other validationsvalidates_numericality_of :price
validates_uniqueness_of :title
def validate errors.add(:price, "should be at least 0.01" ) if price.nil? || price < 0.01end
validates_format_of :image_url, :with => %r{\.(gif|jpg|png)$}i, :message => "must be a URL for a GIF, JPG, or PNG image"
![Page 42: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/42.jpg)
SEG4110 - Topic N - Ruby on Rails 42
Class methods in the model to return a set of instances
class Product < ActiveRecord::Base # The self. Means it is a class (static) method def self.find_products_for_sale find(:all, :order => "title" ) end# validation stuff...end
![Page 43: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/43.jpg)
SEG4110 - Topic N - Ruby on Rails 43
Specifying associations in model classesclass Order < ActiveRecord::Base has_many :line_items …end
class Product < ActiveRecord::Base has_many :line_items has_many :orders, :through => :line_items …end
class LineItem < ActiveRecord::Base belongs_to :order belongs_to :product …end
![Page 44: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/44.jpg)
SEG4110 - Topic N - Ruby on Rails 44
Generating automatic documentationrake doc:app
rake stats(in /Users/dave/Work/depot)+----------------------+-------+-------+---------+---------+-----+-------+| Name | Lines | LOC | Classes | Methods | M/C | LOC/M |+----------------------+-------+-------+---------+---------+-----+-------+| Helpers | 17 | 15 | 0 | 1 | 0 | 13 || Controllers | 229 | 154 | 5 | 23 | 4 | 4 || Components | 0 | 0 | 0 | 0 | 0 | 0 || Functional tests | 206 | 141 | 8 | 25 | 3 | 3 || Models | 261 | 130 | 6 | 18 | 3 | 5 || Unit tests | 178 | 120 | 5 | 13 | 2 | 7 || Libraries | 0 | 0 | 0 | 0 | 0 | 0 || Integration tests | 192 | 130 | 2 | 10 | 5 | 11 |+----------------------+-------+-------+---------+---------+-----+-------+| Total | 1083 | 690 | 26 | 90 | 3 | 5 |+----------------------+-------+-------+---------+---------+-----+-------+Code LOC: 299 Test LOC: 391 Code to Test Ratio: 1:1.3
![Page 45: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/45.jpg)
SEG4110 - Topic N - Ruby on Rails 45
Automatic testing in RoR
Unit tests - test the model•In test/unit
Functional tests - test a controller action•In test/functional
Integration tests - test flow through the system•In test/integration
![Page 46: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/46.jpg)
SEG4110 - Topic N - Ruby on Rails 46
Sample initially generated test for Product
require File.dirname(__FILE__) + '/../test_helper'class ProductTest < Test::Unit::TestCase #load test data fixtures :products def test_truth assert true endend
![Page 47: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/47.jpg)
SEG4110 - Topic N - Ruby on Rails 47
A test to verify that an empty product is not valid and that empty variables are invalid
def test_invalid_with_empty_attributes product = Product.new assert !product.valid? assert product.errors.invalid?(:title) assert product.errors.invalid?(:description) assert product.errors.invalid?(:price) assert product.errors.invalid?(:image_url)end
![Page 48: Topic N: Ruby on Rails](https://reader034.vdocuments.mx/reader034/viewer/2022042714/554f5865b4c905b9508b5223/html5/thumbnails/48.jpg)
SEG4110 - Topic N - Ruby on Rails 48
Checking some other propertiesdef test_positive_price product = Product.new(:title => "My Book Title" , :description => "yyy" , :image_url => "zzz.jpg" ) product.price = -1 assert !product.valid? assert_equal "should be at least 0.01" , product.errors.on(:price)
product.price = 0 assert !product.valid? assert_equal "should be at least 0.01" , product.errors.on(:price)
product.price = 1 assert product.valid?end