Upload
others
View
5
Download
0
Embed Size (px)
Citation preview
Rails 101
605.484 – Ruby on Rails Johns Hopkins University
Kalman Hazins
History - Ruby on Rails (RoR) • Framework for making dynamic web
applications • Created in 2004 - 2005 by David Heinemeier
Hansson (a.k.a. DHH) – Recognized by Google and O’Reilly as Hacker of
the year for creating Rails (2005)
2
Who is using Rails?
3
• Twitter • Groupon, Living Social • Yellow pages, White pages • Github, Hulu • And many more…
– http://rubyonrails.gorg/applications – Not just a toy framework anymore
Why use Rails? • Convention over configuration
– Less code to write • Some code Rails automatically generates for you • Oftentimes, there is no need to write code at all
– Learn it once - know what to expect the next time • Database Abstraction Layer
– No need to deal with low-level DB details – No more SQL (Almost)
4
Why use Rails? (Continuation) • Agile-friendly
– Encourages unit, functional and integration tests • DRY principle
– Don’t repeat yourself • Cross-platform • Open Source - MIT License • Modular - swap different components in/out
5
SQLite • Rails uses SQLite as a database by default
– Self-contained, serverless, zero-configuration, transactional, relational SQL database engine.
• CLAIM: Most widely deployed SQL database engine in the world. – 300 million copies of Firefox – 20 million Mac computers – iPhone, Android phones – http://www.sqlite.org/mostdeployed.html
6
Installing Rails • In the past, needed to
– First install SQLite and Ruby – Then install Rails as a gem
• NOW: Just go to railsinstaller.org and you
are good to go with one install package
7
Verify that Rails is installed
8
MVC - Model View Controller • Invented in 1979 by Trygve Reenskaug • Well-established software pattern used by
many web and desktop frameworks • Model - represents the data the application
is working with (and possibly business logic) • View – (visual) representation of that data • Controller - orchestrates interaction
between the model and the view
9
MVC Cycle – Web • Controller receives web request (from
somewhere) and communicates with the model
• Model communicates with DB (if needed) to get the necessary data
• The data is passed to the View • The View renders the data
10
MVC Cycle
11
Controller
View Model DB
1. Browser sends request 2.Controller Interacts
with model 3.Controller invokes view 4.View renders next
browser screen
Creating first app
12
rails new appname
(rails new –h for more options)
bundler (gems manager) (…Bundler covered later…)
13
Version control your Rails app! • Rails automatically generated .gitignore • $cd my_first_app
• $git init
• $git add .
• $git commit –m “Initial commit”
• But you knew that already…
14
Running the app • Now you have my_first_app directory with
auto-generated structure/code • Rails also provides a built-in server • Time to run our app!
– (Open up another window – Go into my_first_app directory) – Run $rails server (or $rails s)
15
Running the app (Continued)
16
Development environment
localhost on port 3000
Running the app (Continued)
17
public/index.html • The page displayed is index.html from public directory
• Server looks into public directory before looking anywhere else (before Rails)
• So… if we want to add a completely static web page (or any file) to our application - we can add it under public directory
18
Adding hello_static.html to public dir <!DOCTYPE html> <html> <head><title>Totally static</title></head> <body> <h2> Will never generate dynamic content :( </h2> </body> </html>
• No need to restart the server
19
Directory structure convention
20
Controllers, Views, Models (and helpers)
Configuration files
Files related to your db and migration scripts
Third-party code or your code that isn’t directly a model view or controller (or helper)
Log files
Static files
“rails” script
Unit, functional and integration tests
External libraries, such as rails plugins
Dependencies managed by Bundler
Generating a controller • Controllers contain actions (ruby methods)
and orchestrate web requests • Rails can quickly generate a controller and 0
or more actions with their associated views • $rails generate controller controller_name [action1 action2]
• $rails g controller greeter hello – (may substitute g for generate)
21
Generating a controller (Continued)
22
Generating a controller
23
View
… app directory is where you will be spending most of
your time …
(S)CSS (…discussed later…)
Controller
What does it look like? (View) <h1>Greeter#hello</h1> <p>Find me in app/views/greeter/hello.html.erb</p>
(Notice that there is no DOCTYPE, head or body elements…)
24
ERB (Embedded Ruby) • The view file was generated and it looks like
it’s an HTML file, but it has an .erb extension • ERb is a templating library (similar to JSP)
that lets you embed Ruby into your html • 2 tag patterns to learn:
– <% …ruby code… %> - evaluate Ruby code – <%= …ruby code… %> - output evaluated Ruby code
25
New hello.html.erb <% random_names = %w{Joe Alex Harry} %> <h1>Greetings, <%= random_names.sample %></h1> <p>Time now is <%= Time.now %></p>
26
What does it look like? (Controller) class GreeterController < ApplicationController def hello end end
• hello action is just a regular (empty in this case) Ruby method
• What if we want to add a goodbye action to the greeter controller and also add a goodbye.html.erb to app/views/greeter directory?
27
Adding goodbye action
28
Routes • It turns out - we are missing an important
piece - “Routing!” • Before the Controller can orchestrate where
the web request goes - the web request needs to get routed to the Controller
• So, how did the hello action work then? • The route for hello action was
automatically generated
29
MVC(R) Cycle - Revised!
30
Controller
View
Model DB
1. Browser sends request 2.Router routes request
to Controller 3.Controller Interacts
with model 4.Controller invokes view 5.View renders next
browser screen
Router
routes.rb • All the routes need to be specified (either
generated by rails generators or manually) in the config/routes.rb file
• So, what does config/routes.rb look like?
31
config/routes.rb MyFirstApp::Application.routes.draw do get "greeter/hello"
# The priority is based upon order of creation:
# first created -> highest priority.
# You can have the root of your site routed with "root" # just remember to delete public/index.html.
# root :to => "welcome#index"
# See how all your routes lay out with "rake routes" end
• Let’s add the route for the goodbye action
32
New config/routes.rb MyFirstApp::Application.routes.draw do # get "greeter/hello"
# SAME AS ABOVE
get "greeter/hello" => "greeter#hello" get "greeter/goodbye"
# The priority is based upon order of creation:
# first created -> highest priority.
# You can have the root of your site routed with "root" # just remember to delete public/index.html.
# root :to => "welcome#index"
# See how all your routes lay out with "rake routes" end
33
Controller Action
Rake • Ruby’s build language
– (as in Ruby’s make?) – No XML - written entirely in Ruby
• Rails uses rake to automate several tasks that have to do with the database as well as running tests (and anything else you can think of)
• To see a list of rake tasks for your app – $rake --tasks
34
Rake tasks
35
Individual rake task • You can zero-in on an individual rake task
and what it does with a --describe flag • $rake --describe task_name
36
Adding your own rake task • How can you add your own rake task to a
rails app? • 2 steps:
1. Write a new ruby file with .rake extension 2. Place it under lib/tasks directory of your
rails app • Visit http://rubyrake.org/ for more info on
writing custom rake tasks
37
jhu_look_ma.rake
38
Our task is dependent on the :environment task which loads the Rails environment
Custom rake task in action
39
Rake routes • $rake routes explains your currently
defined routes
40
Action methods inside Controller • If the action method is not really doing
anything - we can remove it • As long as there is a proper route defined
and there is a properly named view file/template - the action method does not have to be there and Rails will use a convention to find the correct template
41
Controller - new look class GreeterController < ApplicationController end
42
You probably still want to leave the actions
(methods) in the Controller (to make it
easier on another person looking for
them), but the point of this slide is that you don’t *have* to have
the methods if they are empty as long as the routes are properly
defined and the views exist
Moving business logic out • Our app “works”, but business logic does not
belong in the view. The view should have as little Ruby code as possible
<% random_names = %w{Joe Alex Harry} %> <h1>Greetings, <%= random_names.sample %></h1> <p>Time now is <%= Time.now %></p>
• Let’s move some code to the controller!
43
Moving business logic out (Cont.) • Instance variables from the controller are
made available inside the view class GreeterController < ApplicationController def hello random_names = %w{Joe Alex Harry} @name = random_names.sample @time = Time.now @times_displayed ||= 0 @times_displayed += 1 end end
44
New views/greeter/hello.html.erb <h1>Greetings, <%= @name %></h1> Time now: <%= @time %><br/> This page has been displayed <%= @times_displayed %> time(s)
45
<h1>Greetings, <%= @name %></h1> <p>Time now is <%= @time %></p> This page has been displayed <%= @times_displayed %> time(s)
Instance variables in Rails • Unlike Servlets/JSP – a new instance of the
Controller is created every time a request is made
• Therefore, you can’t “store” values in the Controller’s instance variables in between requests
• Alternative? – Session – Database
46
Helpers • We’ve made the current time available
through @time instance variable (controller) • But what if we want to format how the time
looks? Should that code go in the View? Then, we can’t reuse it. So… maybe the Controller? That doesn’t seem correct either – since the Controller should be “view format” agnostic
• Helpers to the rescue!
47
Helpers (Continued) • (empty) greeter_helper.rb module
generated alongside the controller • Let’s add a helper method formatted_time
48
Helpers (Continued) – New View
49
Helper method used
Rails built-in helpers – link_to • Rails provides many built_in helpers • link_to name, path
– Hyperlink generator that displays the name and links to the path
– Path could either be a regular string or a route defined in the routes.rb file ending with _url (full path) or _path (relative path)
– _url and _path used interchangeably, but acc. to spec full path is required in cases of redirection
50
link_to in action <h1>Greetings, <%= @name %></h1> Time now: <%= formatted_time %><br/> This page has been displayed <%= @times_displayed %> time(s)
<p><%= link_to "Goodbye", greeter_goodbye_path %></p> <p><%= link_to "Google", "http://www.google.com/" %></p>
51
greeter_goodbye derived from
routes.rb ($rake routes)
Bundler • Lets you specify gems (and associated gem
dependencies) for this Rails app inside Gemfile (in the root of your Rails app)
• Preferred way to manage gem dependencies in Rails 3
• Run $bundle install or simply $bundle after specifying a new gem in the Gemfile
• Run $bundle update when modifying a version of a gem
52
Bundler (Continued) • You can instruct Rails (through Gemfile) to
only load certain gems in specific Rails environments
group :development, :test do gem 'webrat' gem 'some_other_gem' end
53
Bundler – which version of gem? • If you don’t specify – gets the latest version • Can specify an exact version or an
approximate version gem "nokogiri" gem "rails", "3.0.0.beta3" gem "rack", ">=1.0" gem "thin", ">= 1.1.0", “< 2.0" gem "thin", "~>1.1"
54
Same as above “Approximately greater than” (What?) A.k.a. Pessimistic Version Constraint
Drop the final digit, then increment to get the upper limit version number
gem “test”, “>= 2.2.0”, “< 2.3.0”
is the same as gem “test”, “~> 2.2.0”
Bundler (Continued) - require • Occasionally, the name of the gem to be
used inside require statement is different than the name of the gem
gem 'sqlite3-ruby', :require => 'sqlite3‘
• More info on Bundler http://gembundler.com/
55
Gemfile - Example source 'http://rubygems.org' gem 'rails', '3.2.8' # Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git' gem 'sqlite3'
• Our app can even use a different version of Rails if you change the version and run $bundle update
• $bundle creates a Gemfile.lock file, which contains the gem versions your app is using with their associated dependencies
56
Httparty integration • Let’s tell our app to load HTTParty gem
…
gem 'httparty‘ …
57
Need to restart the server after running bundler for changes to take effect!
After running $bundler (or $bundle install)
Reps by state example • Let’s show Reps based on state • Generate Reps Controller • $rails g controller reps index
58
Controller Action
Rep model • Create Rep class under app/models
59
By convention, controllers are named plural and model is named singular… Also, notice how HTTParty does not have to be required (thanks Bundler!)
Reps Controller • Fill in index action
60
Assume MD for now…
Notice, how the Controller did not have to require Rep…
reps/index.html.erb
61
What does it look like?
62
Layout • views/layout/application.html.erb
serves as view’s container (unless overriden)
63
Display the view
Adding some CSS
64
If you are new to CSS – go to http://www.w3schools.com/css/
Modify View to include CSS classes
65
cycle (Rails) helper to cycle thru each rep with a
different value
Final argument is a Hash, where one of the entries could be
a :class
What does it look like now?
66
One final twist – params helper • It would be nice to specify which state you
want to see the representatives for? • No problem – just pass the state in as a
request parameter and use params Hash to retrieve the value (name of parameter becomes a symbol/key in the Hash)
• Returns nil if request parameter not passed in (standard Hash behavior)
67
params helper (Continued) • No changes to the Model or the View, only to
the Controller
68
Default to Maryland if request parameter not
passed in
What does it look like now?
69
And without a request parameter?
70
Deploying to Heroku • Sign up for new account at heroku.com
71
One time setup
72
Upload your public ssh key
Install heroku gem
Final steps • Heroku uses Postgres and is allergic to sqlite • Put sqlite gem into a development group in
your Gemfile and pg (postgres) in production
• $bundle install and commit all your changes to the repo 73
Final steps
74
Final steps • $heroku open will bring up a browser with
your app
75