Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Ruby on Rails Barry Burd Drew University [email protected] Copy of these slides: http://www.burd.org/RoR.ppt 1 Agenda • Ruby language • Creating a Web application with Ruby on Rails • Fine tuning the Web application • Doing other neat things 2 What is …? • Ruby – A simple, elegant, loosely typed, reflective, interpreted programming language. • Rails – An add-on to Ruby for web/database handling. – Model-View-Controller – Convention over configuration – DRY philosophy 3 Ruby on Rails • Advantage – Lightning-fast prototyping • Disadvantages(?) – Development is not as fast with legacy db – Development is not as fast if you customize – Ruby programmers use Ruby idioms – Difficult to deploy – Security model isn’t as mature as Java EE 4 Hello world program C:\ruby>irb --prompt simple >> puts "Hello" Hello => nil >> exit C:\ruby> 5 Defining and calling a method C:\ruby>irb --prompt simple >> def show(what) >> "You typed " + what + "." >> end => nil >> show("Hello") => "You typed Hello.“ >> puts show("Hello") You typed Hello. => nil 6 Expression interpolation >> def show(what) >> "You typed #{what}." >> end => nil >> puts show("Hello") You typed Hello. => nil >> def show(what) >> 'You typed #{what}.' >> end => nil >> puts show("Hello") You typed #{what}. => nil 7 Ruby is dynamically typed (“duck typing”) >> i = 7 => 7 >> puts i, "\n" 7 => nil >> i = "Hello" => "Hello" >> puts i Hello => nil 8 Regular Expressions >> line = "Perl" => "Perl" >> if line =~ /Perl|Python/ >> puts "Scripting language mentioned: #{line}" >> end Scripting language mentioned: Perl => nil >> => >> >> >> => line = "Java" "Java" if line =~ /Perl|Python/ puts "Scripting language mentioned: #{line}" end nil 9 Blocks >> def call_block >> puts "1" >> yield >> yield >> puts "3" >> end => nil >> call_block {puts "2"} 1 2 2 3 => nil 10 Blocks with parameters >> def call_block >> puts "1" >> yield(42) >> yield(79) >> puts "3" >> end => nil >> call_block {|x| puts x} 1 42 79 3 => nil 11 >> 5.times {puts "*"} * * * * * => 5 >> 3.upto(6) {|i| puts i} 3 4 5 6 => 3 >> ('a'..'e').each {|char| puts char} a b c d e => "a".."e" 12 Another Ruby program C:\>type fact.rb def fact(n) return 1 if n == 0 f = 1 n.downto(1) do |i| f *= i end return f end print fact(ARGV[0].to_i), "\n" C:\>ruby fact.rb 10 3628800 C:\>ruby fact.rb 5 120 13 Ruby’s integers (and other things) are of arbitrary size C:\>ruby fact.rb 155 4789142901463393876335775239063022722 176295591337767174070096339929153381 622433264146569329274347655956110484 372311586936020749175429076661003216 274382475477806479918110524333880196 139452687559896255940215628508414806 740389616633144934400000000000000000 000000000000000000000 14 Ruby is object-oriented class Point def initialize(x, y) @x = x; @y = y self end def to_s sprintf("%d@%d", @x, @y) end end list1 = [10, 20, Point.new(2, 3), Point.new(4, 5)] list2 = [20, Point.new(4, 5), list1] print("list1: ", list1.inspect, "\n") print("list2: ", list2.inspect, "\n") C:\>ruby list3.rb list1: [10, 20, #<Point:0x2867a48 @y=3, @x=2>, <Point:0x2867a30 @y=5, @x=4>] list2: [20, #<Point:0x28679e8 @y=5, @x=4>, [10, 20, #<Point:0x2867a48 @y=3, @x=2>, #<Point:0x2867a30 @y=5, @x=4>]] 15 Ruby has unit testing class Adder def initialize(number) @number = number end def add(number) return @number + number end end require 'test/unit' require 'adder' class TC_Adder < Test::Unit::TestCase def setup @adder = Adder.new(5) end def test_add assert_equal(7, @adder.add(2), "Should have added correctly") end def teardown @adder = nil end 16 end Class with a constructor (from “Programming Ruby”) class Song def initialize(name, artist, duration) @name = name @artist = artist @duration = duration end end song = Song.new("Bicylops","Fleck",260) 17 Getters # This code can come immediately after the previous # slide’s code. class Song def name @name end def artist @artist end def duration @duration end end puts song.name 18 Quick way to create getters class Song attr_reader :name, :artist, :duration end puts song.name 19 >> class MyClass >> end => nil >> MyClass.methods => ["send", "name", "class_eval", "object_id", "new", "singleton_methods", "__se nd__", "private_method_defined?", "equal?", "taint", "frozen?", "instance_variab le_get", "constants", "kind_of?", "to_a", "instance_eval", "require", "ancestors ", "const_missing", "type", "instance_methods", "protected_methods", "extend", " protected_method_defined?", "eql?", "public_class_method", "const_get", "instanc e_variable_set", "hash", "is_a?", "autoload", "to_s", "class_variables", "class" , "tainted?", "private_methods", "public_instance_methods", "instance_method", " require_gem_with_options", "untaint", "included_modules", "private_class_method" , "const_set", "id", "<", "inspect", "<=>", "==", "method_defined?", ">", "===", "clone", "public_methods", "protected_instance_methods", ">=", "respond_to?", " display", "freeze", "<=", "module_eval", "autoload?", "allocate", "__id__", "=~" , "methods", "require_gem", "method", "public_method_defined?", "superclass", "n il?", "dup", "private_instance_methods", "instance_variables", "include?", "call 20 _block", "const_defined?", "instance_of?"] Ruby is Reflective (1) class Myclass def mymethod puts "Hello" end end x = 'mymethod' Myclass.new.send(x) Hello 21 Ruby is Reflective (2) class MyStuff def announce puts "I'm being announced.\n" end def method_missing(method_name) puts "I don't know how to do #{method_name}.\n" end end m = MyStuff.new m.announce m.xyz I'm being announced. I don't know how to do xyz. 22 Creating a web-based database application in about a dozen steps… 23 Rails naming conventions • company application • company_development database • employees table • generate model Employee • generate controller Employee • employee_controller.rb • EmployeeController class 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 Using the Model to Validate Input 43 44 45 46 47 48 49 50 51 52 53 54 55 Many-to-many relationships require "rubygems" require_gem "activerecord" ActiveRecord::Base.establish_connection( :adapter=> "mysql", :host => "localhost", :database => "company2_development") class Task<ActiveRecord::Base has_and_belongs_to_many :employees end 56 Many-to-many relationships class Employee < ActiveRecord::Base has_and_belongs_to_many :tasks def acquire_task(task) tasks.push_with_attributes(task) end def show_task(i) puts tasks.find(i).description end def show_tasks for task in tasks puts task.description end end end 57 Many-to-many relationships emp1 = Employee.new emp1.name = 'Barry Burd' emp1.salary = 100000000.0 emp1.fulltime = false emp1.level = 10 emp1.hiredate = '2006-08-22‘ emp1.save task = Task.new task.description = "Clean the office" task.save task2 = Task.new task2.description = "Scoop the cat litter" task2.save 58 Many-to-many relationships emp = Employee.find(1) emp.acquire_task(Task.find(1)) emp.acquire_task(Task.find(2)) emp2.show_tasks Clean the office Scoop the cat litter 59 Ajax 60 In the controller... def show_body @comment = Comment.find(params[:id]) render :text => @comment.body end 61 In the view... <head> <%= javascript_include_tag "prototype" %> </head> ... <% for comment in @comments %> <tr> <td><%= comment.title %></td> <td> <div id="comment_<%= comment.id.to_s %>"> <%= link_to_remote( "Show Body", :update => "comment_#{comment.id.to_s}", :url => { :action => :show_body, :id => comment }) %> </div> </td> 62 Sending Email 63 The Message Model class CreateMessages < ActiveRecord::Migration def self.up create_table :messages do |t| t.column :subject, :string t.column :custname, :string t.column :amount, :float t.column :recipients, :string t.column :sender, :string end end def self.down drop_table :messages end end 64 Configuring the mailer ActionMailer::Base.server_settings = { :address => "mail.cheapprovider.net", :domain => "burdbrain.com", } 65 The Mailer class class MyMailer < ActionMailer::Base def setup(message, sent_at = Time.now) @subject = message.subject @body['custname'] = message.custname @body['amount'] = message.amount @recipients = message.recipients @from = message.sender @sent_on = sent_at @headers = {} end end 66 Email template <head> <style type="text/css"> p.indent { margin-left: 60px } </style> </head> <h1>Third Notice!</h1> Dear <%= @custname %>,<p> Your bill is overdue. Please pay <%= number_to_currency(@amount) %> immediately.<p> <p class="indent">Signed,<br>Your <i><b>friends</b></i> at Burd Brain Consulting</p> 67 How to mail a message def create @message = Message.new(params[:message]) my_message = MyMailer::create_setup(@message) my_message.set_content_type 'text/html' MyMailer::deliver my_message if @message.save flash[:notice] = 'Message was successfully created.' redirect_to :action => 'list' else render :action => 'new' end end 68 Creating a Web Service 69 Describing the Web Service class TimeServiceApi < ActionWebService::API::Base api_method :get_time, :expects => [:bool], :returns => [:time] end 70 The Time Service require 'time' class TimeServiceController < ApplicationController wsdl_service_name 'TimeService' web_service_scaffold :use_service def get_time(gmt) (gmt)?(Time.now.getgm):(Time.now) end end 71 Add-Ons • LoginGenerator http://wiki.rubyonrails.com/rails/pages/LoginGenerator • Payment http://payment.rubyforge.org/ • ActiveSearch http://julik.nl/code/active-search/index.html • Active Merchant http://home.leetsoft.com/am/ • …and lots more! 72 References • Home: http://www.rubyonrails.com • THE books: Programming Ruby: http://www.rubycentral.com/book/index.html Agile Web Development with Rails http://www.pragmaticprogrammer.com/title/rails/ • My book: Ruby on Rails For Dummies http://www.amazon.com/blah-blah-blah... • Resources: http://www.rubyquiz.com/ http://www.ruby-doc.org/ http://www.rubycentral.com/ http://railsmanual.org/ http://www.freeonrails.com/ http://tryruby.hobix.com/ • Rails Web hosting: http://railsplayground.com/ http://www.railshosting.org/#free http://www.rubyonrailswebhost.com/ 73 END 74