Rails 101 -...

Post on 07-Oct-2020

5 views 0 download

Transcript of Rails 101 -...

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