Learning to code for startup mvp session 3

67
Learning to Code for Startup MVP Presented by Henry Shi

Transcript of Learning to code for startup mvp session 3

Page 1: Learning to code for startup mvp session 3

Learning to Code for Startup MVP

Presented by Henry Shi

Page 2: Learning to code for startup mvp session 3

Agenda – Monday November 26

1. Review of Last Session

2. Rails Controllers

3. Rails Router

4. Rails View and Frontend

5. Followers + Relationships

6. To be Continued… (Interface, Feed)

Page 3: Learning to code for startup mvp session 3

Prework – Setup

• Windows (not recommended if possible):o http://railsinstaller.org/o Use Sublime Text for your text editor

• OSX:o http://railsinstaller.org/o This includes osx-gcc-installer (200mb)

• Linux:o http://blog.sudobits.com/2012/05/02/how-to-install-rub

y-on-rails-in-ubuntu-12-04-lts/

Page 4: Learning to code for startup mvp session 3

Prework - Git

Install git if not already included:

http://www.git-scm.com/book/en/Getting-Started-Installing-Git

Configure Git:

git config --global user.name "Your Name“

git config --global user.email [email protected]

Page 5: Learning to code for startup mvp session 3

Review of Last Session

1. The Web and How it Works

2. Ruby Basics

3. Rails Models

4. Authentication and User accounts

Page 6: Learning to code for startup mvp session 3

Ruby – Programmer’s Best Friend

• Ruby is a dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write.

• We will only cover the necessary syntax needed to create a rails app

• Thankfully, its not a lot

Page 7: Learning to code for startup mvp session 3

Interactive Ruby Shell

• For the following slides, you should follow along with the Interactive Ruby Shell (irb)

• Open a terminal, type irb and press enter

Page 8: Learning to code for startup mvp session 3

Ruby – Practice

• Tryruby.org (code in ruby on your browser and work through free exercises)

• Read Section 4.1 to 4.5 of Ruby on Rails Tutorial by Michael Hartl

Page 9: Learning to code for startup mvp session 3

Rails – Database backed Models

• Store and access massive amounts of data

• Tableo Columns (name, type, modifier)o Rows

Table:User

s

Page 10: Learning to code for startup mvp session 3

SQL

• Structured Query Languageo A way to talk to databases

• Operations (CRUD)o Createo Read (Query)o Updateo Deleteo Schema creation and modification

SELECT *FROM BookWHERE price > 100.00ORDER BY title;

Page 11: Learning to code for startup mvp session 3

Rails – Object Relational Mapping

• Maps database backend to ruby objects

• ActiveRecord (Rail’s Default ORM)

>> userVariable = User.where(name: "Bob")

>> userVariable.name=> Bob

Generates:SELECTWHERE

"users".* FROM "users"(name = 'bob')

Page 12: Learning to code for startup mvp session 3

Rails – Object Relational Mapping

>> userVariable = User.where(name: "Bob")

• Plural of Model name is table name (User -> users)

• Subclassing from ActiveRecord::Base “Connects” a model to the databaseo Provides CRUD operations on the modelo Database table column names are getters & setters for model

attributeso Model attributes automagically defined from the database table

columns

models/user.rb

class User < ActiveRecord::Base attr_accesor :name, :emailend

Page 13: Learning to code for startup mvp session 3

Rails – Creating Users - Devise

• We will use the awesome Gem: Devise

• Gems are packages/libraries for your rails project

• Before coding, always see if a gem exists at

The Rails Toolbox

Page 14: Learning to code for startup mvp session 3

Rails - Devise

• Create a new rails appo rails new MiniTwitter

• Open Gemfile (from last class)

• Add the line:Gem ‘devise’, ‘2.1.0’

• Run Bundle install from the console

• Install Devise by typing in the console: rails generate devise:install

• Generate the user by typing in the console:rails generate devise User

• Run the migration by typing in the console:Bundle exec rake db:migrate

Page 15: Learning to code for startup mvp session 3

Git Commit

git init

git add .

git commit –m “Initial Commit of MiniTwitter”

(optional) git remote add origin [email protected]:<username>/first_app.git

(optional)git push –u origin master

Page 16: Learning to code for startup mvp session 3

Rails MVC – Quick Review

•  Model: methods to get/manipulate data“ /app/models/post.rbPost.where(...), Post.find(...)

•  Controller: get data from Model, make available to View /app/controllers/posts_controller.rb

def show @movie = Post.find(params[:id])

end

•  View: display data, allow user interaction“ /app/views/users/*.html.erb

–  Show details of a Post (description, timestamp, etc)

Page 17: Learning to code for startup mvp session 3

Rails Controllers - Variables

• Some housekeeping knowledge (you’ll see this a lot in controllers)

foobar

@foobar

@@foobar

$foobar

FOOBAR

FooBar

# local variable

# instance variable, starts with @

# class variable, starts with @@

# global variable, starts with $

# Constant, starts with a capital letter

# Classes are constants

Page 18: Learning to code for startup mvp session 3

Rails Controllers - Intro

• Handles Business Logic

• Pass Data to Controller via Query String

class PostsController <

ApplicationControllerdef newend

end

http://localhost:3000/posts/new

http://localhost:3000/posts?status=posted

?status=published

?status=published&language=english

Page 19: Learning to code for startup mvp session 3

Rails Controllers - Params

• Params (hash) – get data from url

• Instance variables – pass data to view

def index

@status = params[:status]

if @status == “published"@clients = Post.published

else

@clients = Post.removed

endend

http://localhost:3000/posts?status=published

Page 20: Learning to code for startup mvp session 3

Rails Controllers – Params Hash

• Receive Hashes from Formso Great for handling data and user input

Hash

Form

{name: “Acme”, phone: “12345”, address: {postcode: “12345”}}

<form action="/clients" method="post"><input type="text" name="client[name]" value="Acme" /><input type="text" name="client[phone]" value="12345" /><input type="text" name="client[address][postcode]" value="12345" />

</form>

params[:client] # =>

<- Notice the nested hash (corresponding to nested form)

Page 21: Learning to code for startup mvp session 3

Rails Controller – Application Flow

• Can redirect to another action/url

• Rails automatically creates

names for url routes (more later)

# send to another action/urlIf not_logged_in redirect_to "/home”else if not_authorized redirect_to help_pathelse @post = Post.newend

http://localhost:3000/posts/new

Page 22: Learning to code for startup mvp session 3

Rails Controller - Rendering

• Passes instance variables and data to view to render to end user

• If don’t call render, Rails will default to view named action_name.html.erb in the controller’s view path and render it

• Lots of more info here: http://guides.rubyonrails.org/layouts_and_rendering.html

# Various rendering options

render “some_template"render layout: "awesome"render text : "foo"render json: @postrender xml: @postrender status: forbiddenrender file: filename,,content_type: ‘application/rss’'

Page 23: Learning to code for startup mvp session 3

Rails Router – Overview1.  Routes (in routes.rb) map incoming URLʼs to controlleractions and extract any optional parameters!

–  Routeʼs “wildcard” parameters (eg :id), plus any stuff after “?” in URL,are put into params[] hash accessible in controller actions"

2.  Controller actions set instance variables, visible to views"–  Subdirs and filenames of views/ match controllers & action names"

3.  Controller action eventually renders a view"

app/controllers/movies_controller.rb

def showid = params[:id]@mv=Movie.find(id)

end

app/views/movies/show.html.haml

<li>Rating:= @mv.rating

GET /movies/:id{:action=>'show',:controller=>'movies'}

config/routes.rb

Page 24: Learning to code for startup mvp session 3

Rails Router

• Handles what controller & action pair to call for given url

• Config/routes.rb is the main router file for the entire application

o Visiting /about will call static_pagers#contact method

• Can view current route setups by running:o Rake routes (in shell console)

Page 25: Learning to code for startup mvp session 3

Rails Router - REST

• REsprentational State Transfer (REST)o Way of modelling resources and keeping consistent

urls across the web – after Roy Fieldings PhD Dissertation

• Main Features:1. Resources (Nouns) addressable through URL

2. Standard Methods (Verb)o GET, POSTo PUT, DELETE

Page 26: Learning to code for startup mvp session 3

Rails Router - REST

• Rails maps HTTP Methods to Controller Actionso GET -> index, show, newo POST -> createo PUT -> updateo DELETE -> destroy

Page 27: Learning to code for startup mvp session 3

Rails Router - Resources

• Can automatically specify resources in routes.rb and Rails will create 7 url mappings

routes.rbresources: Photo Method name in photos_controller.rb

When you visit, localhost:3000/photos/2 (GET request), Rails will call PhotosController#show and will pass Params[:id] = 2

Passed to params hash

Page 28: Learning to code for startup mvp session 3

Rails Router – Helper Paths

• Creating a resource in routes.rb also automatically creates helper paths:

• photos_path #=>returns /photos

• new_photo_path  #=>returns /photos/new

• edit_photo_path(:id)  #=>returns /photos/:id/edit 

• photo_path(:id) returns  #=>/photos/:id

Note:

_path returns relative url (eg. /photos)

_url returns absolute url  (eg. www.myrailsapp.com/photos)

Page 29: Learning to code for startup mvp session 3

Rails Router – Nested Resources

• Can Nest resources to model relationships

Many more powerful routing options available:

http://guides.rubyonrails.org/routing.html

Page 30: Learning to code for startup mvp session 3

Rails Controller – Mini Twitter

• Use Scaffolding to create a Post model and controller

• Make Posts a nested resource of Users in the router

• Modify the PostsController to display all the posts of a given user when visiting/user/:id/posts

Page 31: Learning to code for startup mvp session 3

Mini Twitter – Posts Model

rails generate scaffold Post content:string user_id:integero Use rails scaffolding to generate posts!

bundle exec rake db:migrate

Edit: app/models/post.rb

Rails so Submitting a post with more than 140 chars will give

error (Automatically handled by Rails!)

Page 32: Learning to code for startup mvp session 3

Mini Twitter – Post Route

• Routes.rb:

• rake routes (to view available routes)

Page 33: Learning to code for startup mvp session 3

Mini Twitter – Post Controller

• App/controllers/post_controllers.rb:

• Visiting /users/:id/posts will return all the posts by the given user

• Correction: should be find_all_by_user_id

Page 34: Learning to code for startup mvp session 3

Rails Controller - Summary

• To add a new action, can use scaffoldingo rails g scaffold Model_Name type:Attribute…

Or:

1. Create route in config/routes.rb if needed"

2. Add the action (method) in the appropriateapp/controllers/*_controller.rb!

3. Ensure there is something for the action torender in app/views/model/action.html.erb!

Page 35: Learning to code for startup mvp session 3

Rails Views

• Views are what ends up being displayed in the user’s browser

• Separation of controls:o presentation (views) vs business logic (controller)o Usually involves the controller placing dynamically

generated data into a template and then rendering the template into the final HTML file

• We’ll use the default ERB templating systemo Many other templating systems (haml, liquid, etc)

Page 36: Learning to code for startup mvp session 3

Rails Views - ERB

• Embedded Ruby (part of Ruby standard lib)

• Ruby code that generates HTML

• <%= expression %>o Substitute code element with result of the code (as string)

• <% scriptlet %>o Executed, and most commonly used for loops/logic 

<h1>People</h1><ul>

<h1>People</h1><ul><li>Bob</li>

<li>Joe</li><li>Mary</

li></ul>

<% @people.each do |person| %><li><%= person.first_name

%></li><% end %>

</ul>

Page 37: Learning to code for startup mvp session 3

Rails Views - Forms

• Forms allow user to input and submit data

• for_for helper in Rails

Page 38: Learning to code for startup mvp session 3

Rails View - Form

• Generated HTML

Page 39: Learning to code for startup mvp session 3

Rails View – CSS, Sass

• CSS used to provide styling to HTML (not look ugly), but CSS is ugly to write

• Sass is an extension of CSS3, adding nested rules, variables,mixins, selector inheritance, and more

• Rails’ asset pipeline supports Sass and compiles it to CSS

Page 40: Learning to code for startup mvp session 3

Rails Views – Bootstrap

• CSS framework for rapid prototyping

• Make sites look non-sh***y

• Responsive design and support cross platform devices

Before After (with Bootstrap)

Page 41: Learning to code for startup mvp session 3

Rails Views – Install Bootstrap

• Download Bootstrap CSS:o http://twitter.github.com/bootstrap/assets/bootstrap.zip

• Copy bootstrap.min.css and bootstrap.min.css to /vendor/assets/stylesheets

• Copy bootstrap.min.js to /vendor/assets/javascripts

• Copy images to app/assets/images

• Edit: app/assets/stylesheets/application.csso Add: *= require bootstrap.min to third last line

• Edit: app/assets/javascripts/application.jso Add: *= require bootstrap.min to third last line

• The last 2 lines tells the Rails asset pipeline to include the bootstrap css and js files when compiling all the assets

Page 42: Learning to code for startup mvp session 3

Rails Views - Exercise

• Modify Post views so that User’s email is displayed instead of user_id

• App/views/posts/show.html.erb

Page 43: Learning to code for startup mvp session 3

Rails - Associations

• One of Rail’s most powerful features is ability to form associations between data model

• each user potentially has many microposts

• Edit: app/models/user.rb

• Edit: app/models/post.rb

Page 44: Learning to code for startup mvp session 3

Rails - Associations

• Primary Keyo Unique identifier for all objects

• Foreign Keyo Relates to another row’s primary key

Hats:

id: 557

style: "Fedora"

Hats:

id: 687

style: "Cowboy"

Hatsid: 557style: "Fedora"inspector_id: 35

Inspectorsid: 35name: "John"

Page 45: Learning to code for startup mvp session 3

Rails - Relationships

• Relationships through foreign and primary keys

Page 46: Learning to code for startup mvp session 3

Rails – Models and Relationships

• Association is a connection between two Active Record models

• Types of Associations:o belongs_too has_oneo has_manyo has_many :througho has_one :througho has_and_belongs_to_many

Page 47: Learning to code for startup mvp session 3

Rails – Belongs To

• belongs_to :parent_classo Sets foreign key to match primary key

• Convention is parent_id is foreign_key field in child class

Page 48: Learning to code for startup mvp session 3

Rails – Has Many

• has_many :child_class (plural)o Builds Association in Rails

• Related objects contain links to one another

• Can get object’s associated objects>> myCustomer = Customer.where(:id => 2)>> orders = myCustomer.orders

Page 49: Learning to code for startup mvp session 3

Rails – Has Many Through

• Question? What if Patient has many Physicians and Physician has many Patients?

• Need many-to-many connection via 3rd model

Page 50: Learning to code for startup mvp session 3

Rails – Has Many and Belongs to Many

• Creates direct many to many relationship (via implicit 3rd model)

• Still need to create assemblies_parts in db via migration!

Page 51: Learning to code for startup mvp session 3

Rails – Followers and Following

• Many-Many relationship between Users and Users!

• Relationships is the 3rd model needed for the many-many relationship

Page 52: Learning to code for startup mvp session 3

Rails – Relationship Model

• Generate relationship model:

• Add indices for faster queries

• Run migration:

Page 53: Learning to code for startup mvp session 3

Rails – Relationship

• Add belongs_to in app/models/relationship.rb

• Can now call relationship.follower to get the follower (User) in the relationship

• Same for followed

Page 54: Learning to code for startup mvp session 3

Rails – Followed User

• Add has_many association in app/models/user.rb

• User.followed_users looks up the relationship objects via matching the follower_id to the User’s id, and return the list of followed Users in the relationships (which correspond to the User’s followed users)

Page 55: Learning to code for startup mvp session 3

Rails – Followed User

• Adding some utility methods to the User model

Checks if the user is following the other user by seeing if the relationship object exists

Creates a relationship to indicate that the user is now following the other user

Page 56: Learning to code for startup mvp session 3

Rails – Followers

• Add has_many association in app/models/user.rb

• User.followers looks up the relationship objects via matching the followed_id to the User’s id, and return the list of follower in the relationships (which correspond to the User’s followers)

Relationships already exists for followed users, so need another name to indicate “reverse relationship” for followers

Page 57: Learning to code for startup mvp session 3

Rails - Followers

• We now have all the backend needed to implement followers and following

Page 58: Learning to code for startup mvp session 3

Rails – Feed (User)

• Create method to get posts from all followed Users in app/models/user.rb

• Need to implement from_users_followed_by method in the Post model

Page 59: Learning to code for startup mvp session 3

Rails – Feed (Post)

• Create from_users_followed_by method in the Post model

• Select all the posts where the user_id matches any one of the user_id’s in the followed_user_ids list or equals the original owner user’s id

Page 60: Learning to code for startup mvp session 3

Rails – Feed (Users) Optimization

• Previously, stored array of user’s followed_user_ids in memory

• Optimize by using subquery and offload to DB

• But even this won’t scale forevero May need to generate the feed asynchronously using

a background job

Page 61: Learning to code for startup mvp session 3

Rails - Feed

• We now have all the backend needed to implement the feed

Page 62: Learning to code for startup mvp session 3

Rails - Feeds

• Further Reading

Ruby on Rails Tutorial – Michael Hartl

Section 11

Page 63: Learning to code for startup mvp session 3

Git Commit

git init

git add .

git commit –m “Added followers, following and feed of MiniTwitter”

(optional) git remote add origin [email protected]:<username>/MiniTwitter.git

(optional)git push –u origin master

Page 64: Learning to code for startup mvp session 3

Heroku – New MiniTwitter App

• Sign up for Heroku (it’s Free!) http://api.heroku.com/signup

• Install the Heroku Toolbelt https://toolbelt.heroku.com/

• Heroku login

• Heroku createo This will create a heroku app and tell you the url of

your app

• Git push heroku mastero This’ll deploy your code to Heroku. Let it do its magic!

• Heroku run rake db:migrate

• Heroku open

Page 65: Learning to code for startup mvp session 3

Next Time…

• Building the front-end for followers and feed

• Implementing Ajax for follow button

• More to come...

• Stayed tuned for next term!

Page 66: Learning to code for startup mvp session 3

Thanks!

• It was a pleasure to create this course and present. I enjoyed every minute of it.

• Hopefully you were able to learn something useful and will look to using Rails in your next project!

• If these sessions helped you, please leave a positive note or testimonial

Page 67: Learning to code for startup mvp session 3

Resources

• Questions? I’d be glad to help

• henrythe9th at gmail dot com

• @henrythe9ths

• Agile Web Development with Rails—Fourth Edition

• Programming Ruby: The Pragmatic Programmers' Guide – Third Edition

• RailsCasts

• Rails main site http://www.rubyonrails.com

• CodeSchool

• Peepcode