RoR 101: Session 3

Preview:

DESCRIPTION

Part 3 of 6

Citation preview

Building Web Apps with Rails

III

● Rails Console● ActiveRecord Queries

● Views● Embedded Ruby Syntax● Layouts● Helper Methods

Recap

Recap: ActiveRecord

DBModels Controllers

In stations_controller.rb (show):

@stations = Station.find(params[:id])

The Rails Console

1. Open the terminal 2. Navigate to the 'firstfm' directory3. Run the commands:

rails console@stations = Station.all

<%= link_to 'Edit', edit_station_path(@station) %> |<%= link_to 'Back', stations_path %>

show.html.erb:

These are both view helpers.

<!DOCTYPE html><html><head> <title>Firstfm</title> <%= stylesheet_link_tag "application" %> <%= javascript_include_tag "application" %> <%= csrf_meta_tags %></head><body>

<%= yield %>

</body></html>

The default layouttemplate.

DB

Web Browser

Models

Routing SystemRails

Controllers

Views

Session 3

DB

Web Browser

Models

Routing SystemRails

Controllers

Views

Session 3: Routing

DB

Web Browser

Models

Routing SystemRails

Controllers

Views

Session 3: Validations & Testing

DB

Web Browser

Models

Routing SystemRails

Controllers

Views

Session 3: Associations& The 'Stream' Model

Routing in Rails

Routing in Rails

●Which controller to instantiate

●Which action to invoke

●Parameter(s) to pass

Web Browser

?

Routing in Rails

●Follows routing rules defined in:

●config/routes.rb

Web Browser

Routing System

Controllers

Views

Config/Routes.rb:

Firstfm::Application.routes.draw do resources :stations #commentsend

Routing in Rails

Generates RESTful routes for the 'Station' resource

Config/Routes.rb:

Firstfm::Application.routes.draw do resources :stations #commentsend

Routing in Rails

Representational State Transfer Principles:

Use HTTP methods explicitlyBe stateless

Expose directory structure-like URIsHandle multiple formats e.g. XML, JSON

Config/Routes.rb:

Firstfm::Application.routes.draw do resources :stations #commentsend

Routing in Rails

This means we can acceptrequests for all the CRUD

actions

Routing in Rails: Terminal Time!

1. Open the terminal 2. Navigate to the 'firstfm' directory3. Run the commands:

rake routes

Routing in Rails: Writing Rules

Config/Routes.rb:

resources :stations

Routing in Rails: Writing Rules

Config/Routes.rb (rewritten):

get 'statations' => 'stations#index'get 'statations/:id' => 'stations#show'get 'statations/new' => 'stations#new'post 'statations' => 'stations#create'put 'statations/:id' => 'stations#update'delete 'statations/:id' => 'stations#destroy'

Routing in Rails: Writing Rules

Config/Routes.rb:

resources :stations

Generates URL helpers for us e.g.

stations_pathstation_path(:id)new_station_pathEtc...

Routing in Rails: Task

1. Define a root controller and action

2. Add a new action

2.1 Write a new method in the controller2.2 Write a view file for it2.3 Write a routing rule so we can access it

For docs on routing: guides.rubyonrails.org/routing.html

Tests and Validations

We have a problem...

Our app accepts empty station data

Solution:

Write validations to prevent erroneous data

Tests and Validations

But First!

Let's write tests.

Tests and Validations

Tests and Validations

Scaffolding has generated testfiles for us

require 'test_helper'

class StationTest < ActiveSupport::TestCase  # test "the truth" do  #   assert true  # endend

In firstfm/test/unit/station_test.rb:

We write tests by writing out 'assertions'

Tests and Validations: Unit Testing

require 'test_helper'

class StationTest < ActiveSupport::TestCase  test "the truth" do     assert 10 > 9  endend

Tests and Validations: Unit Testing

'assertions' evaluate whether an object is what we expect it to be

Tests and Validations: Unit Testing

ruby -Itest <script_name>

Running test scripts

ruby -Itest test/unit/station_test.rb

e.g.

Tests and Validations: Unit Testing

Script report example:

ruby -Itest test/unit/station_test.rb

pass: 1, fail: 1, error: 0total: 2 tests with 2 assertions in 0.215168805 seconds

test "shouldnt save without name" dostation = Station.newstation.url = “http://myradio.com”station.description = “A cool radio 

station”assert !station.save

end

Tests and Validations: Unit Testing

test "should save" dostation = Station.newStation.name = “My Radio”station.url = “http://myradio.com”station.description = “A cool radio 

station”assert station.save

end

Tests and Validations: Unit Testing

Tests and Validations: Task!

Write test cases for your validations

Consider more than just presence of data e.g.

● Name shouldn't be longer than x characters

● URL should start with 'http://'

● Description shouldn't be less than x characters

Tests and Validations: Validate

● We write validation code in the model

● Rails provides us with several built in validation methods

● For example: 'validates_presence_of'

Tests and Validations: Validate

Example: Using validates_presence_of In models/station.rb:

class Station < ActiveRecord::Base

validates_presence_of :name, :url, :description

end

Tests and Validations: Task!

Make your tests pass by implementing validations like below

class Station < ActiveRecord::Base

validates_presence_of :name, :url, :description

end

Associations in RoRAdding 'Streams'

Station

First FM

Station Stream

First FM

Station Streams

First FM

Has many

First FM

Let's generate the stream model

rails generate model stream url:string name:string

Create the db table by running the migration script...

rake db:migrate

First FM

Let's check out our new stream model

rails c

mystream = Stream.new

Station Stream

First FM

Station Streams

First FM

Has many

Station Streams

First FM

Has many

has_many :streams

belongs_to :station

First FM

Let's see if our models are associated

rails c

mystation = Station.first

mystation.streams

First FM

OH NOES!

We need to add a secondary key.

rails generate migration AddStationIdToStreams station_id:integer

First FM

OH YEA!

We've got a secondary key!

rake db:migrate

rails c

mystation = Station.first

mystation.streams

First FM

Build

Build and save a new stream

stream = mystation.streams.build