Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rails, Postgres, Angular, and Bootstrap: The Power Stack

Rails, Postgres, Angular, and Bootstrap: The Power Stack

Rails, Postgres, Angular, and Bootstrap are all powerful technologies in and of themselves. When used together, however, you get a powerful web application development stack that reduces friction between what you want for your users and what you can deliver.

David Copeland

November 14, 2015
Tweet

More Decks by David Copeland

Other Decks in Programming

Transcript

  1. Rails, Postgres,
    Angular, and Bootstrap
    The Power Stack
    David Bryant Copeland
    @davetron5000

    View Slide

  2. Journey through the
    “stack”

    View Slide

  3. Full Stack is important

    View Slide

  4. “Jack of all trades,
    master of none…
    …oftentimes better
    than master of one”

    View Slide

  5. UI

    View Slide

  6. View Slide

  7. View Slide

  8. Learn about design

    View Slide

  9. View Slide

  10. MY AMAZING APP!

    View Slide

  11. MY AMAZING APP!

    View Slide

  12. Text

    View Slide

  13. Modular Type Scale

    View Slide

  14. Subhead 1
    Subhead 2
    Subhead 3
    Body Text
    Captions & Secondary Text
    Heading

    View Slide

  15. About Us
    The place for all your needs
    We’ve got everything you could
    ever want and then some. It’s
    just that simple to be as awesome
    as we are, and it shows.
    You can’t find this much great
    stuff anywhere else, so what are
    you waiting for? Sign up Now!
    MY APP
    Sign Up
    Log In
    Help

    View Slide

  16. View Slide

  17. View Slide


  18. .col-md-1
    .col-md-1
    .col-md-1
    .col-md-1
    .col-md-1
    .col-md-1
    .col-md-1
    .col-md-1
    .col-md-1
    .col-md-1
    .col-md-1
    .col-md-1


    .col-md-8
    .col-md-4

    View Slide



  19. Email





    Password








    Remember me






    Sign in




    Email

    Password


    Remember me

    Sign in

    View Slide

  20. Default
    Primary
    Large
    XS
    Default
    Default
    Default
    Default

    View Slide


  21. alert-info
    alert-warning
    alert-danger

    View Slide

  22. Panel
    Icons
    Sub-panel
    Well
    Disabled
    Badge

    View Slide

  23. Interaction

    View Slide

  24. JavaScript & jQuery

    View Slide

  25. You shouldn’t think about
    locating DOM elements and
    firing or responding to events

    OK?

    Close
    OK


    $(“.js-dimissable”).find(“[data-ok]”).click(function() {
    // ...
    });

    View Slide

  26. Components &
    Behavior

    OK?
    Close
    OK

    dialog.on_confirm(function() {
    // ...

    });

    View Slide

  27. View Slide

  28. Some
    Documentation
    Kinda
    Works
    No
    Support
    Yeah, there’s probably some
    code comments, and it’s
    entirely possible I used great
    variable names. Functions and
    objects should be consistent,
    but probably aren’t. I think
    there was a demo page
    somewhere, maybe?
    It still doesn’t handle that weird
    case on IE 8, and I never tested
    what happens if you use two
    containers in the same DOM
    subtree, but CSS polyfills
    mostly work for major browsers.
    No, there’s no test suite.
    I’m moving onto a project using
    Node, Elixir, Redis, Mongo, and
    Kubernetes, so the best thing
    to do is hang out on the Slack
    channel. I live in New Orleans,
    but work Amsterdam hours, so
    I’m not always around.
    JS

    View Slide

  29. View Slide


  30. {{ title }}

    {{ message }}

    Close
    OK
    Maybe

    View Slide

  31. angular.module(‘controllers’).controller(
    “DialogController”,
    function($scope, $dialog, opts) {
    $scope.title = opts.title;
    $scope.message = opts.message;
    $scope.ok = function(data) {
    if (data == ‘ok’) {
    $dialog.confirm();
    }
    else {
    $dialog.confirm(withData: data)
    }

    }
    $scope.dismiss = function() {
    $dialog.cancel();

    }

    });

    View Slide

  32. User = $resource(“/users/:id”);
    $scope.user = User.get(id: 1234);

    {{ user.name }}
    {{ user.email }}


    {{ login.date }} -
    {{ login.ipAddress }}



    View Slide

  33. angular.module(‘controllers’).controller(
    “DialogController”,
    function($scope, $dialog, opts) {
    $scope.title = opts.title;
    $scope.message = opts.message;
    $scope.ok = function(data) {
    if (data == ‘ok’) {
    $dialog.confirm();
    }
    else {
    $dialog.confirm(withData: data)
    }

    }
    $scope.dismiss = function() {
    $dialog.cancel();

    }

    });

    View Slide

  34. angular.module(“app”).factory(
    “customConfirmation”,
    function() {
    return {
    confirm: function($dialog,data) {
    if (data == ‘ok’) {
    $dialog.confirm();
    }
    else {
    $dialog.confirm(withData: data);
    }

    }
    }

    }
    );
    angular.module(‘controllers’).controller(
    “DialogController”,
    function($scope, $dialog, opts, customConfirmation) {
    $scope.title = opts.title;
    $scope.message = opts.message;
    $scope.ok = customConfirmation.confirm;
    $scope.dismiss = function() {
    $dialog.cancel();

    }

    });

    View Slide

  35. Angular is Popular

    View Slide

  36. The “Back End”

    View Slide

  37. Middleware

    View Slide

  38. Parse HTTP
    Extract params, headers,
    cookies, etc
    Route to code
    Read result
    Generate response, cookies,
    headers, etc.
    Database Access
    Package Assets
    Run Tests
    Schema Management
    Configuration & Deployment
    YOUR
    CODE

    View Slide

  39. Parse HTTP
    Extract params, headers,
    cookies, etc
    Route to code
    Read result
    Generate response, cookies,
    headers, etc.
    Database Access
    Package Assets
    Run Tests
    Schema Management
    Configuration & Deployment
    Plumbing

    View Slide

  40. Your Code

    View Slide

  41. Don’t make decisions

    View Slide

  42. View Slide

  43. View Slide

  44. View Slide

  45. Data

    View Slide

  46. Durability

    View Slide

  47. Integrity

    View Slide

  48. Speed

    View Slide

  49. Modeling

    View Slide

  50. SQL RDBMS

    View Slide

  51. First: Learn SQL. You
    won’t regret it.

    View Slide

  52. View Slide

  53. ALTER TABLE
    users
    ADD CONSTRAINT
    valid_emails
    CHECK (
    ( guest = true AND
    email ! ‘[A-Za-z0-9._%-][email protected]’)
    OR
    ( guest = false AND
    email ~ ‘[A-Za-z0-9._%-][email protected]’)
    )

    View Slide

  54. CREATE INDEX
    users_name_index
    ON
    users (lower(name))
    SELECT * FROM users
    WHERE lower(name) = ‘bob’;

    View Slide

  55. UPDATE users
    SET config = ‘auto_save => true,
    color => default’::hstore;
    CREATE INDEX user_config
    ON users USING GIN(config);
    ALTER TABLE
    users
    ADD COLUMN
    config HSTORE;
    SELECT * FROM users
    WHERE config @> ‘auto_save => true’;

    View Slide

  56. ALTER TABLE
    users
    ADD COLUMN
    roles text[];
    UPDATE users
    SET roles = ‘{staff,admin}’;
    CREATE INDEX user_roles
    ON users USING GIN(roles);
    SELECT * FROM users
    WHERE roles @> ‘{admin}’;

    View Slide

  57. ALTER TABLE
    transactions
    ADD COLUMN
    braintree_response JSONB;
    UPDATE transactions
    SET braintree_response = ‘{
    “processor_response”: “decline”,
    “processor_code”: 1234,
    “details”: {
    “charge_type”: “authorization”,
    “amount”: 12.45,
    “zip”: “20002”
    }
    ‘;

    View Slide

  58. CREATE INDEX txn_responses
    ON transactions
    USING GIN(braintree_response);
    SELECT * FROM
    transactions
    WHERE
    braintree_response @>
    ‘{“processor_response”: “decline”}’::jsonb;

    View Slide

  59. SQL Knowledge + Postgres
    == Powerful data layer

    View Slide

  60. Putting it all Together

    View Slide

  61. Be Honest about
    Weaknesses

    View Slide

  62. Bootstrap
    • JS-based components require jQuery
    • Angular-UI-Bootstrap

    View Slide

  63. Angular
    • Protractor (end-to-end testing) totally disconnected
    from Rails/back-end
    • Use Capybara/PhantomJS for E2E testing

    View Slide

  64. Rails
    • Strange view/front-end/JS/AJAX design
    • Avoid
    • Disable turbolinks
    • Asset Pipeline oddities
    • Learn to use it—it’s actually powerful

    View Slide

  65. Rails
    • Database Migrations “DSL”
    • You are not making a database-agnostic app
    • Use execute
    • Use SQL-based schema
    config.active_record.schema_format = :sql

    View Slide

  66. Rails
    • ActiveRecord
    • Examine queries in the log—look for
    optimizations
    • Let SQL shine
    • Don’t fear .where() or
    ActiveRecord::Base.connection.exec_query()

    View Slide

  67. Postgres
    • Stored Procedures
    • Triggers
    • Avoid putting business logic here

    View Slide

  68. You don’t have to use
    every feature

    View Slide

  69. These are powerful
    tools

    View Slide

  70. The reduce the decisions
    you have to make to only
    what’s important.

    View Slide

  71. If you are making decisions
    not related to your
    product…

    View Slide

  72. …consider Bootstrap,
    Angular, Rails, or Postgres

    View Slide

  73. If you want to know the details…
    http://full-stack-rails.com

    View Slide