laravel and django and rails, oh my!

60
Caddis Interactive Chris Roberts @thechrisroberts Laravel and Django and Rails, Oh My! Become a web artisan with the Laravel PHP framework 1

Upload: chris-roberts

Post on 29-Nov-2014

600 views

Category:

Software


1 download

DESCRIPTION

The Laravel Framework. Showing Laravel alongside Rails and Django. A presentation at CoderFaire 2014.

TRANSCRIPT

Page 1: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

Laravel and Django and Rails, Oh My!Become a web artisan with the Laravel PHP framework

1

Page 2: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts 2

Page 3: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

Compare Apples to ApplesWhich of these is your favorite Doctor?

3

Page 4: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

Apples to Apples

4

Page 5: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

• Pick what fits you and learn it inside and out.

• Always be ready to try new things.

• Find the right tool for the job.

Choosing Your EnvironmentIn some ways, it doesn’t matter

5

Page 6: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

• What does your server environment support?

• Will your chosen framework scale up when your work goes viral?

• Are your developers familiar with the tools?

• How is the community support?

• Does it have the third-party utilities you need?

Choosing Your EnvironmentWhen it matters

6

Page 7: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

• Ruby is generally considered more human-readable

• Python is more script-like and white space significant

• PHP uses a C-style syntax

Looking at the details: Language SyntaxLanguage Overview

7

Page 8: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

• Each language supports closures

• Ruby: blocks, procs, and lambdas

• Python and PHP: nested functions

• PHP closures introduced in PHP 5.3

Looking at the details: Language SyntaxLanguage Overview

8

Page 9: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

• Each language supports OO code.

• PHP is not what it used to be.

• Namespaces, inheritance, autoloading

• PSR standards

Looking at the details: Object OrientedLanguage Overview

9

Page 10: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

• Each framework has options for unit testing

• Django uses Python’s unittest

• Rails has unit testing baked in

• Laravel has out-of-the-box support for PHPUnit with the ability to run assertions on your routes

Find your bugs before your users find themUnit Testing

10

Page 11: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

• Ruby: gem packages

• Python: pip (official support in Python 3.4)

• PHP: composer

Looking at the details: Third-party PackagesLanguage Overview

11

Page 12: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

• Ruby: Github (Rails and Erlang), original Twitter

• Python: Disqus, Instagram

• PHP: Wikipedia, many CMS’s, Facebook uses their own variant

Who uses itLanguage Overview

12

Page 13: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

• Numerous frameworks per language

• Rails and Django are the most popular for their languages

• PHP has many contenders: Yii, Zend, CakePHP, CodeIgniter, Symfony, Aura, Slim, Silex, numerous others.

• Pick the one that fits your project

Rails, Django, and LaravelFramework Overview

13

Page 14: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

• Follows PSR-0/PSR-4 for namespacing and autoloading

• Flexible configuration system with multiple environment support

• Powerful ORM tied to a comprehensive query builder

• Highly extensible through service providers

• MVC design pattern in Laravel 4

• Excellent documentation

Laravel for PHPThe PHP Framework for Web Artisans

14

Page 15: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

DWRM (Doctor Who Relationship Management)

15

Page 16: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

Getting up and running

16

Page 17: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

• Models: doctors, companions, enemies, episodes

• Also prepare for users, comments, and ratings

• Need pivot tables to track relationships

• Set up migrations to easily create and update our data structure

• Add seed data for testing

Pieces for a DWRMSetting things up

17

Page 18: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

• Laravel Migrations: versionable table schemas.

• Puts your schema inside source control

• Easily built out with Laravel’s command line utility: artisan

MigrationsBuilding out your database in code

18

Page 19: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

Laravel ArtisanThis command line tool provides numerous helpers from generating classes to running migrations to seeding data.

19

Page 20: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

use Illuminate\Database\Schema\Blueprint;use Illuminate\Database\Migrations\Migration;

class CreateDoctorsTable extends Migration {

public function up(){

Schema::create('doctors', function($table) {$table->increments('id')

->integer('number') ->string('image') ->text('description') ->timestamps();

});}

public function down(){

Schema::drop('doctors');}

}

20

Page 21: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

use Illuminate\Database\Schema\Blueprint;use Illuminate\Database\Migrations\Migration;

class ModifyDoctorsTable extends Migration {

public function up(){

Schema::table('doctors', function($table) {$table->string('name');

});}

public function down(){

Schema::table('doctors', function($table) {$table->dropColumn('name');

});}

}

21

Page 22: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

Run the Migration

22

Page 23: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

class CreateDoctors < ActiveRecord::Migration def change create_table :doctors do |t| t.integer :number t.string :name t.string :image t.text :description t.timestamps end endend

Rails MigrationRails provides a similar mechanism for setting up your data structure

23

Page 24: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

Django MigrationDjango also provides migrations, though they work a bit differently than Rails or Laravel

24

• Changes are made on the model class file

• Migrations are automatically generated based on model changes

Page 25: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

• Laravel seeding makes use of its ORM methods to easily create and store model data.

• The query builder can also be used to manipulate data directly.

• DB seeds are run using Artisan.

Loading test dataLaravel data seeding makes it easy to bootstrap your website or load data for testing.

25

Page 26: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

class DoctorTableSeeder extends Seeder {

public function run(){

Doctor::delete();

Doctor::create(array('name' => 'Christopher Eccleston', 'number' => '9', 'description' => '...', 'image' => '...' ));

Doctor::create(array('name' => 'David Tennant', 'number' => '10', 'description' => '...', 'image' => '...' ));

Doctor::create(array('name' => 'Matt Smith', 'number' => '11', 'description' => '...', 'image' => '...' ));

Doctor::create(array('name' => 'Peter Capaldi', 'number' => '12', 'description' => '...', 'image' => '...' ));

}}

26

Page 27: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

class CompanionTableSeeder extends Seeder {

public function run(){

Companion::delete();

$doctorNine = Doctor::where('number', 9)->first();$doctorTen = Doctor::where('number', 10)->first();

Companion::create(array(‘name' => 'Rose Tyler','description' => '...','image' => '...'

)) ->doctors() ->attach(array($doctorNine->id, $doctorTen->id));

}}

27

Page 28: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

Running php artisan db:seed

28

Page 29: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

• Similar in Rails

Doctor.create(name: "David Tennant", number: 10, description: "...")

• Different in Django

• Can import from structured data (XML, JSON, etc)

• Primarily imported via data migration

Django and RailsOther ways to do the same

29

Page 30: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

• Class that provides additional abstraction between you and data

• A model represents an object in the database

• The framework provides ways to manipulate those models

• Laravel, Rails, and Django each follow the Active Record pattern

Data ModelWriting code that represents “things”

30

Page 31: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

• Laravel’s ORM (called Eloquent) makes it easy to connect related models.

• In our demo, each doctor has a companion, each episode a doctor, companion, and enemy, etc.

• We also have comments and ratings that can attach to any of these.

Model relationshipsConnecting related pieces

31

Page 32: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

Modeling the Doctorclass Doctor extends Eloquent {

public function companions(){

return $this->belongsToMany('Companion');}

public function enemies(){

return $this->belongsToMany('Enemy');}

public function episodes(){

return $this->belongsToMany('Episode');}

}

32

Page 33: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

Modeling the Companionclass Companion extends Eloquent {

public function doctors(){

return $this->belongsToMany('Doctor');}

public function episodes(){

return $this->belongsToMany('Episode');}

}

33

Page 34: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

Relationships

There are many ways models might relate to each other. Laravel provides methods for interacting with each option. This includes nested relations, ie, accessing a grandparent model through a child.

• one-to-one

• hasOne(…)

• belongsTo(…)

• one-to-many

• hasMany(…)

• belongsTo(…)

• many-to-many

• belongsToMany(…)

34

Page 35: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

• Our tables are defined and created

• We’ve loaded seed data

• We have pieced together our models and their relations

• Time to get something on screen

• First step: connecting the URL to our code

Stepping backReviewing the state of our application

35

Page 36: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

• Routing is finding out where a user once to go and directing them to the appropriate place in your code.

• Laravel provides several ways to define your application routes.

• It also provides filters to allow you to lock routes based on certain situations, ie, keep guests away from routes requiring authentication.

Laravel RoutingProvides a powerful interface to direct users based on their url path and depending on your defined filters

36

Page 37: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

Routing the DoctorRoute::get('/', 'IndexController@index');

Route::get('/doctors', 'DoctorController@index');Route::get('/companions', 'CompanionController@index');Route::get('/enemies', 'EnemyController@index');Route::get('/episodes', 'EpisodeController@index');

Route::get('/doctor/{id}', 'DoctorController@get');Route::get('/companion/{id}', 'CompanionController@get');Route::get('/enemy/{id}', 'EnemyController@get');Route::get('/episode/{season}/{show}', 'EpisodeController@get');

Route::post('/comment', 'CommentController@post');

37

Page 38: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

Django Routing• Django handles routes via a URL dispatcher which matches

routs through regular expressions.

• Does not match against GET, POST, etc. from django.conf.urls import patterns, urlfrom . import views

urlpatterns = patterns('', url(r'^doctors/$', views.list_doctors) url(r'^doctor/(\d+)$', views.view_doctor))

38

Page 39: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

Rails Routing• Routes defined in application routes.db

• Out of the box, no route filtering

• Able to define specific routes to specific controller methods

• Able to automatically route to controllers and methods

Rails.application.routes.draw do root 'index#index' get 'doctors' => 'doctor#index' get 'doctor/:id' => 'doctor#get' resources :enemyend

39

Page 40: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

• Performs data validation

• Interacts with necessary models

• Generates views

• Returns responses to the client or redirects to an alternate route

Laravel ControllersMediating between your model and view

40

Page 41: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

DoctorController.phpclass DoctorController extends BaseController {

public function index(){

$doctors = Doctor::orderBy('number')->get();return View::make('doctors', array(‘doctors' => $doctors));

}

public function get($id){

$doctor = Doctor::with(array(‘companions', ‘episodes'))->find($id);$ratings = RatingController::getRating('doctor', $id);$comments = Comment::where('item_id', $id)

->where('item_type', 'doctor') ->with('user') ->orderBy('created_at', 'desc') ->get();

return View::make('items.doctor', array( 'doctor' => $doctor, 'ratings' => $ratings, 'comments' => $comments ));

}}

41

Page 42: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

Blade Tempting@extends('layouts.structure')

@section('content') <h1>The Modern Doctor</h1> <div class="row doctor"> @foreach ($doctors as $doctor) <div class="item"> <a href="/doctor/{{ $doctor->id }}"> <img src="{{ $doctor->image }}"> <h3>{{ $doctor->name }}</h3> </a> </div> @endforeach </div>@stop

42

Page 43: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

Blade Tempting<!DOCTYPE html><html lang="en"> <head> <meta charset="utf-8"> <title> @if (isset($title)) {{ $title }} | @endif The Doctor </title> <link rel="stylesheet" href="/assets/css/style.css"> </head>

<body> <header class="container"> <h1 class="site"><a href="/">The Island of Doctor Who</a></h1> </header>

<div class="container"> @yield('content') </div> </body> <script src="/assets/js/script.min.js"></script></html>

43

Page 44: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

Blade Tempting@extends('layouts.structure')

@section('content') <h1>The Modern Doctor</h1> <div class="row doctor"> @foreach ($doctors as $doctor) <div class="item"> <a href="/doctor/{{ $doctor->id }}"> <img src="{{ $doctor->image }}"> <h3>{{ $doctor->name }}</h3> </a> </div> @endforeach </div>@stop

44

Page 45: Laravel and Django and Rails, Oh My!

Chris Roberts Caddis Interactive 45

Page 46: Laravel and Django and Rails, Oh My!

Chris Roberts Caddis Interactive 46

Page 47: Laravel and Django and Rails, Oh My!

Chris Roberts Caddis Interactive 47

Page 48: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

public function get($id){

$doctor = Doctor::with(array(‘companions', ‘episodes’))->find($id);

$ratings = Rating::getRating('doctor', $id);$comments = Comment::where('item_id', $id)

->where('item_type', 'doctor') ->with('user') ->orderBy('created_at', 'desc') ->get();

return View::make('items.doctor', array('doctor' => $doctor, 'ratings' => $ratings, 'comments' => $comments ));

}

Retrieving individual modelsLaravel makes it easy to retrieve a model, any related data, and pass it to a view for presentation.

48

Page 49: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

@extends('layouts.structure')

@section('content') <h1 class="title">{{ $doctor['name'] }}</h1> <div class="hero"> <img src="{{ $doctor['image'] }}"> </div>

<div class="rating"> Rated {{ $ratings['rating'] }} out of 5 with {{ $ratings['numRatings'] }} votes </div>

<p class="description"> {{ $doctor['description'] }} </p>

49

Page 50: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

<h2>Companions</h2> <div class="row companion"> @foreach ($doctor['companions'] as $companion) <div class="item"> <a href="/companion/{{ $companion->id }}"> <img src="{{ $companion->image }}"> <h3>{{ $companion->name }}</h3> </a> </div> @endforeach </div>

<h2>Episodes</h2> <div class="row episode"> @foreach ($doctor['episodes'] as $episode) <div class="item"> <a href="/episode/{{ $episode->season }}/{{ $episode->episode }}"> <img src="{{ $episode->image }}"> <h3>Season {{ $episode->season }} episode {{ $episode->episode }}</h3> <h3>{{ $episode->name }}</h3> </a> </div> @endforeach </div>

@include('layouts.comment', array('type' => 'doctor', 'id' => $doctor['id'], 'comments' => $comments))@stop

50

Page 51: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

<a name="comments"></a><h1>Comments</h1>

@if($errors->has())Display errors

@endif

<h2>Add Comment</h2>

{{ Form::open(array('url' => '/comment/')) }} {{ Form::hidden('type', $type) }} {{ Form::hidden('id', $id) }} {{ Form::label('title', 'Comment title'); }} {{ Form::text('title'); }} {{ Form::label('email', 'Email address'); }} {{ Form::text('email'); }} {{ Form::label('content', 'Comment text'); }} {{ Form::textarea('content'); }} {{ Form::submit('Submit'); }}{{ Form::close() }}

@if ($comments && sizeof($comments) > 0) @foreach ($comments as $comment) <div class="comment"> <h3>{{{ $comment['title'] }}}</h3> <div class="meta">Comment by {{ $comment['user']['name'] }} at {{ date('m-d-Y H:i:s', strtotime($comment['created_at'])) }}</div> <p> {{{ $comment['content'] }}} </p> </div> @endforeach@endif

51

Page 52: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

class BaseController extends Controller {

public function __construct(){

$this->beforeFilter('csrf', array('on' => 'post'));}

}

CSRF ProtectionLaravel comes with filters to help protect you and your users from CSRF attacks

52

Page 53: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

$validator = Validator::make(Input::all(),array(

'type' => 'in:doctor,companion,enemy,episode','title' => 'required|min:5','email' => 'required|email','content' => 'required',

));

ValidationOnce user data is received, Laravel provides tools to simplify validation and storage.

53

Page 54: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

When the test failsif ($validator->fails()) {

return Redirect::to(URL::previous() . '#comments')->withErrors($validator)->withInput();

}

54

Page 55: Laravel and Django and Rails, Oh My!

Chris Roberts Caddis Interactive 55

Page 56: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

If valid, store the comment$comment = new Comment();$comment->user_id = Auth::id();$comment->item_id = Input::get('id');$comment->item_type = Input::get('type');$comment->title = Input::get('title');$comment->content = Input::get('content');$comment->save();

return Redirect::to(URL::previous() . '#comments')->with('message', 'Comment posted');

56

Page 57: Laravel and Django and Rails, Oh My!

Chris Roberts Caddis Interactive 57

Page 58: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

• Laravel provides a powerful, flexible framework for application development.

• Based on PHP, Laravel has broad support from most hosts.

• Language features and framework methods are on par with or better than other popular frameworks.

FinFrom start to end, Laravel provides a full-featured framework to make your development elegant and efficient

58

Page 59: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

Recommended Resources• Laracasts: https://laracasts.com/

• Laravel Podcast and Forums: http://laravel.io/forum

• Code Bright by Dayle Rees

• #Laravel on Freenode

• https://github.com/JeffreyWay/Laravel-Generators

• Homestead: http://laravel.com/docs/homestead

59

Page 60: Laravel and Django and Rails, Oh My!

Caddis InteractiveChris Roberts @thechrisroberts

Thank you!Chris Roberts [email protected]@thechrisroberts

60

Caddis is hiring let’s talk