Upload
malina
View
37
Download
0
Embed Size (px)
DESCRIPTION
Developing Web Application using Ruby on Rails. Ben Curren CTO and Founder. Agenda. What is Ruby on Rails? Overview of Rails Create a Todo List Web Application using Rails Introduction to Ruby More Information Questions. My Background. Started developing Java in 1996 - PowerPoint PPT Presentation
Citation preview
Developing Web Application using Ruby on Rails
Ben CurrenCTO and Founder
AgendaAgenda What is Ruby on Rails?
Overview of Rails
Create a Todo List Web Application using Rails
Introduction to Ruby
More Information
Questions
My BackgroundMy Background Started developing Java in 1996
Developed many web based applications using Java / J2EE, PHP and ASP.net.
Have worked extensively with C++ / C developing Windows desktop applications.
Developed desktop application using WinForms and .Net 1.1.
Have been working with Ruby on Rails for about months.
CTO and Founder of Esomnie. We develop web applications using Ruby on Rails, Java, and ASP.net.
Assumptions about the audienceAssumptions about the audience
I have made a couple assumptions about the audience: You have experience with an object-oriented programming language. You understand the basics of HTTP. You understand XHTML / HTML
What is Ruby on Rails?What is Ruby on Rails?
Rails is a web development framework
Ruby is a programming language
Rails is developed in Ruby.
Overview of Rails
What is Rails?What is Rails?
Full stack web application framework
Open source and Free
Active and growing community
What does Rails Provide?What does Rails Provide? MVC
ActiveRecord
Unit Testing Framework
Migrations
And ActiveResource, ActionWebService, ActiveSupport, ActionMailer, ActionPack
Rails OpinionsRails Opinions
Convention over configuration
Agile software development
Test driven development
Create a Todo List Web Application using Rails
The applicationThe application
A web application that allows a user to create a todo list
Users will be able to view a list of their todo lists.
Users will be able to create new todo lists.
They will be able to add items to the list. (not today, we will not have time)
Create the projectCreate the project
Create a new rails project named todo.
Creates the rails directory structure and initial configuration.
rails todo
Directory StructureDirectory Structuretodo
app
controllers
helpers
models
views
layouts
config
db
public
script
test
functional
unit
integration
vendor
…
Create the databases Create the databases
Create a file called db/create.sql
Run the script with mysql -uroot -p < db/create.sql
create database todo_development;
create database todo_test;
create database todo_production;
grant all on todo_development.* to 'tododev'@'localhost' identified by 'tododev';
grant all on todo_test.* to 'todotest'@'localhost' identified by 'todotest';
grant all on todo_production.* to 'todo'@'localhost' identified by 'todo';
Update the Database ConfigurationUpdate the Database Configuration Supply the username and password in config/database.yml
development: adapter: mysql database: todo_development username: tododev password: tododev host: localhost
test: adapter: mysql database: todo_test username: todotest password: todotest host: localhost
production: adapter: mysql database: todo_production username: todo password: todo host: localhost
Generate the List modelGenerate the List model
Create the List model.
It will hold the name of the todo list.
script/generate model list exists app/models/ exists test/unit/ exists test/fixtures/ create app/models/list.rb create test/unit/list_test.rb create test/fixtures/lists.yml create db/migrate create db/migrate/001_create_lists.rb
Create the List MigrationCreate the List Migration A migration allows you to modify the database schema using Ruby.
Migrations provide versioning.
Update the file called db/migrate/001_create_lists.rb
class CreateLists < ActiveRecord::Migration def self.up create_table :lists do |t| t.column "name", :string t.column "created_at", :string t.column "updated_at", :string end end
def self.down drop_table :lists endend
Run the MigrationsRun the Migrations
rake migrate
(in /Users/bcurren/projects/todo)
== CreateLists: migrating ================================
-- create_table(:lists)
-> 0.4252s
== CreateLists: migrated (0.4269s) =======================
The List ModelThe List Model Without writing any mapping code, you can start using the List model.
Here are the contents of app/model/list.rb
class List < ActiveRecord::Baseend
Create and Store a List ObjectCreate and Store a List Objectscript/console
Loading development environment.
>> list = List.new
=> #<List:0x256680c @attributes={"name"=>nil, "updated_at"=>nil, "created_at"=>nil}, @new_record=true>
>> list.name = "Ben's Todo List"
=> "Ben's Todo List"
>> list.save
=> true
Require List.nameRequire List.name
Make the name of the list required.
Update the contents of app/model/list.rb
class List < ActiveRecord::Base
validates_presence_of :name
end
Test that List.name is requiredTest that List.name is required Add a test to make sure name is required. (test/unit/list_test.rb)
class ListTest < Test::Unit::TestCase
fixtures :lists
def test_name_required
List.new do |list|
list.name
assert !list.valid?
assert list.errors.on(:name)
end
end
end
Run the Unit TestsRun the Unit Testsrake test:unit
(in /Users/bcurren/projects/todo)
/usr/local/bin/ruby -Ilib:test "/usr/local/lib/ruby/gems/1.8/gems/rake-0.7.1/lib/rake/rake_test_loader.rb" "test/unit/list_test.rb"
Loaded suite /usr/local/lib/ruby/gems/1.8/gems/rake-0.7.1/lib/rake/rake_test_loader
Started
Finished in 0.103404 seconds.
1 tests, 2 assertions, 0 failures, 0 errors
Rails MVC OverviewRails MVC Overview
Create the list of todo listsCreate the list of todo lists
Create a list controller with an action named list
The action list uses the model to get all the todo lists and places them in a variable called @lists
Create a view the loops over the @lists and renders the html view
Create the ListControllerCreate the ListController
script/generate controller List list
exists app/controllers/
exists app/helpers/
create app/views/list
exists test/functional/
create app/controllers/list_controller.rb
create test/functional/list_controller_test.rb
create app/helpers/list_helper.rb
create app/views/list/list.rhtml
The ListController The ListController
The generated file app/controllers/list_controller.rb
class ListController < ApplicationController
def list
end
end
The list actionThe list action Need to create an array of List objects in the database.
app/controllers/list_controller.rb
class ListController < ApplicationController
def list
@lists = List.find :all
end
end
The ListControllerTestThe ListControllerTest The generated list controller test in
test/functionals/list_controller_test.rb
class ListControllerTest < Test::Unit::TestCase
def setup
@controller = ListController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end
end
The test for the list actionThe test for the list action I added the test for the list action in The generated list
controller test in test/functionals/list_controller_test.rb.
def test_list
get :list
assert_response :success
assert_template 'list'
assert_not_nil assigns(:lists)
end
Run the functional testsRun the functional testsrake test:functionals
(in /Users/bcurren/projects/todo)
/usr/local/bin/ruby -Ilib:test"/usr/local/lib/ruby/gems/1.8/gems/rake-0.7.1/lib/rake/rake_test_loader.rb" "test/functional/list_controller_test.rb"
Loaded suite /usr/local/lib/ruby/gems/1.8/gems/rake-0.7.1/lib/rake/rake_test_loader
Started
Finished in 0.095025 seconds.
1 tests, 3 assertions, 0 failures, 0 errors
The list viewThe list view
Update the template app/views/list/list.rhtml to display a list of the todo lists.
<h1>Todo Lists</h1>
<ul id="todo_list">
<%= render :partial => 'list',
:collection => @lists %>
</ul>
The list partialThe list partial
Create a file name app/views/list/_list.rhtml to display each list item.
<li><%= list.name %></li>
Check your workCheck your work Start up the web server. WEBrick comes with Rails and is great for
testing.
script/server &
[1] 6686
harley:~/projects/todo bcurren$ => Booting WEBrick...
=> Rails application started on http://0.0.0.0:3000
=> Ctrl-C to shutdown server; call with --help for options
[2006-10-08 09:50:46] INFO WEBrick 1.3.1
[2006-10-08 09:50:46] INFO ruby 1.8.4 (2005-12-24) [powerpc-darwin8.6.0]
[2006-10-08 09:50:46] INFO WEBrick::HTTPServer#start: pid=6686 port=3000
View the list in the browserView the list in the browser
Open your browser and type in the URL http://localhost:3000/list/list
Add a default layout to your pagesAdd a default layout to your pages Create a layout named app/views/layouts/default.rhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<%= javascript_include_tag :defaults %>
</head>
<body>
<%= @content_for_layout %>
</body>
</html>
Add the layout to the ApplicationControllerAdd the layout to the ApplicationController
Open the file app/controllers/application_controller.rb
All of the controllers in the app will now use the layout default. You can override this in each controller.
class ApplicationController < ActionController::Base
layout 'default'
end
Create a new todo list using AJAXCreate a new todo list using AJAX First, let’s create the form on the app/views/list.rtml page.
<div>
<%= form_remote_tag(
:url => {:controller => 'list', :action => 'add'},
:html => {:id => 'add_item_form',}) %>
<label for="list_name">Name:</label>
<%= text_field 'list', 'name', :size => 20 %>
<%= submit_tag 'Create' %>
<%= end_form_tag %>
</div>
Create the add actionCreate the add action
Add the following action to app/controllers/list_controller.rb
def add
@list = List.new(params[:list])
@list.save!
end
Create the add rjs fileCreate the add rjs file
Create a file named app/views/list/add.rjs
page.insert_html :bottom, "todo_list", :partial => 'list'
page.visual_effect :highlight, "todo_list"
page.form.reset 'add_item_form'
Test the AJAX addTest the AJAX add
The functional test requires a plugin and I don’t have time to include it here. See http://glu.ttono.us/articles/2006/05/29/guide-test-driven-rjs-with-arts for a good example.
http://localhost:3000/list/list
The application statsThe application statsrake stats
(in /Users/bcurren/projects/todo)
+----------------------+-------+-------+---------+---------+-----+-------+
| Name | Lines | LOC | Classes | Methods | M/C | LOC/M |
+----------------------+-------+-------+---------+---------+-----+-------+
| Helpers | 5 | 4 | 0 | 0 | 0 | 0 |
| Controllers | 16 | 12 | 2 | 2 | 1 | 4 |
| Components | 0 | 0 | 0 | 0 | 0 | 0 |
| Functional tests | 20 | 16 | 2 | 3 | 1 | 3 |
| Models | 3 | 3 | 1 | 0 | 0 | 0 |
| Unit tests | 13 | 11 | 1 | 1 | 1 | 9 |
| Libraries | 0 | 0 | 0 | 0 | 0 | 0 |
| Integration tests | 0 | 0 | 0 | 0 | 0 | 0 |
+----------------------+-------+-------+---------+---------+-----+-------+
| Total | 57 | 46 | 6 | 6 | 1 | 5 |
+----------------------+-------+-------+---------+---------+-----+-------+
Code LOC: 19 Test LOC: 27 Code to Test Ratio: 1:1.4
Introduction to Ruby
What is RubyWhat is Ruby
Object-oriented, dynamic scripting language
Developed by Yukihiro Matsumoto in 1995
Flexible and simple syntax
Based on Perl, Smalltalk, Eiffel, Ada and Lisp
Ruby is Object-OrientedRuby is Object-Oriented default_expiration_date is a public static method of CreditCard
day is a method of FixNum
day returns the number of seconds in x days
from_now is a method of FixNum
from_now returns the x seconds from now
class CreditCard
def self.default_expiration_date
1.day.from_now
end
end
Ruby is DynamicRuby is Dynamic Ruby has open classes.
You can open up a class and add or override methods.
The methods day and from_now are not part of the Ruby FixNum class. Rails adds them with the ActionPack module.
class FixNum
def days
self * 24.hours
end
alias :day :days
end
Ruby is Really DynamicRuby is Really Dynamic Add methods, instance, methods and more at runtime.
This can create an accessor and instance variable like this.
class CreditCard
attr_writer :number
end
Adding methods and variables at runtimeAdding methods and variables at runtime
attr_writer could be implemented like this.
class Object
def self.attr_writer(method)
eval %Q{
def #{method.to_s}=(value)
@#{method.to_s} = value
end
}
end
end
The Magic of method_missingThe Magic of method_missing
How would you write a method that prints out its name if the method name starts with print_?
For example: Example.print_my_name prints “print_my_name”
class Example
def self.method_missing(method_name, *args)
puts method_name if method_name =~ /^print_/
end
end
Ruby’s Closures (Blocks)Ruby’s Closures (Blocks) A closure allows a programmer to provide a block of code for a
method to run.
This example prints out each search engine. (taken from www.ruby-lang.org)
search_engines =
%w[Google Yahoo MSN].map do |engine|
“http://www.” + engine.downcase + “.com”
end
Implementation of Array.mapImplementation of Array.map
Here is an implementation of Array.map
class Array
def map(array)
new_array = Array.new
array.each {|element| new_array << yield element }
new_array
end
end
Ruby has Much More … Ruby has Much More …
Mixins - a collection of methods you can include into any class
Exception handling
Garbage collection
Single inheritance
Duck typing (no interfaces)
More Information
Deploying Rails ApplicationsDeploying Rails Applications
Rails apps are compatible with Unix and Windows environments
Rails apps can be deployed on multiple web server configurations Mongrel - Ruby web server, high performace and is currently the recommended
server WEBrick – a standalone Ruby web server, easy for development FastCGI – running behind Apache or LightTPD. Many problems with this.
Easy control of the deployment with Capistrano A scripting tool to control the deployment of the application on multiple sites
Easy control of schema migration rake migrate VERSION=3
More InformationMore Information Books
Agile Web Development With Rails
(get the second edition) Rails Recipes The Ruby Pick Axe Book
Active and growing community wiki.rubyonrails.com api.rubyonrails.com
FeedbackFeedback
Please provide feedback. Was this too detailed? Should I give more of an overview? Did I move to quickly / slow? Do you like a presentation with this much code? Did you like that I deveoped an example?
Here is how: Log into your account Go to the “Session Details” page Click on the link name "Session Evaluation” on my presentation page Submit your feedback
My Contact InformationMy Contact Information
Ben Curren
Web site: www.esomnie.com
Blog: www.jotthought.com
Interested in a contract or full-time job? Email [email protected].
Questions?Questions?