Skip to content

Instantly share code, notes, and snippets.

@SoxFace
Forked from amysimmons/wdi_week_4_notes.md
Last active August 29, 2015 14:14
Show Gist options
  • Save SoxFace/63bda39fa0e6ef16898e to your computer and use it in GitHub Desktop.
Save SoxFace/63bda39fa0e6ef16898e to your computer and use it in GitHub Desktop.

#WDI Week 4 Notes

##Monday

###Warmup

Bob:

https://gist.github.com/epoch/ea1798f7269f454f2445

My solution (exclusing the extension):

class Bob

    def sure
        puts "sure"
    end
    # if you ask him a question

    def whatever
        puts "whatever"
    end
    # if you tell him something

    def chill
        puts "woah, chill out!"
    end
    # if you yell at him

    def fine
        puts "fine, be that way!"
    end
    # if you address him without actually saying anything

    def loser_speak
        puts "loser speak"
    end
    #Start any sentence with "Bro, " and he'll translate the rest of it into l33t sP34k for you.

    def chat(say)
        if say.start_with?"Bro, "
            loser_speak
        elsif say.include? '?'
            sure
        elsif say.empty? || say == " "
            fine
        elsif say == say.upcase
            chill
        else
            whatever
        end  
    end

end

bob = Bob.new

bob.chat("Bro, ")
bob.chat("sup?") 
bob.chat(" ") 
bob.chat("") 
bob.chat("SUP") 
bob.chat("You're a fool")

###CRUD demos

Homework over the weekend was to create a CRUD system.

I made a blog, with no styling:

https://github.com/amysimmons/wdi8_homework/tree/master/amy/blog

###Patterns

Design Patterns: Elements of Reusable Object-Oriented Software (book)

###Rails appetiser

Movies example:

rails new movie_night

rails server

localhost:3000

rails generate scaffold movie title:string in_theatres:boolean released:date rating:string description:text

rake db:migrate (updating the database to include the movies table)

rails server

localhost:3000/movies

Intro example:

Rails has three different environments:

  • Development

  • Test

  • Production

We added the following gems to Gemfile...

group :development do
    gem 'pry-rails'
    gem 'pry-stack_explorer'
    gem 'annotate'
    gem 'quiet_assets'
    gem 'better_errors'
    gem 'binding_of_caller'
    gem 'meta_request'
end

... then ran bundle in the terminal.

in routes.rb

Rails.application.routes.draw do

  get '/home' => 'pages#home'
  # if someone makes a get request to /home
  # go and look in our pages controller and go and find the method called home

end

in pages_controller.rb

class PagesController < ApplicationController

    def home

    end
    #we need a home method here because we have a page called /home

end

In views, we created a new folder called pages, which sits alongside layout. We then created a file in the pages folder called home.html.erb

Here's how Rails will work when we run the server:

  • When I bring up the rails server it will look into my routes.rb file to see what urls are available

  • If someone visits /home, rails will go to the pages controller to find the method

  • If Rails sees that there is no code in the method, it will then go and look for a view that matches the name of this method, so it will find the view called home.html.erb

Routes:

  • Runnign rake routes in the terminal will tell you how many urls are involved in the project

  • Or you can go to localhost:3000/rails/info/routes

  • We identify the root/home page by including in the routes.rb file

root :to => 'pages#home'

Debugging:

Rather than using binding.pry, use a raise like this:

class AutoController < ApplicationController

    def color
        raise "Something bad happen"
        raise params.inspect
    end

    def engine
    end

end

###Lab: Movie Stock

https://gist.github.com/wofockham/ae2479856769f8dbc804

##Tuesday

###Warmup

Decoding messages:

https://gist.github.com/epoch/21c0133143f03226cee0

My crappy solution, but it works!

message  = "FRZDUGV GLH PDQB WLPHV EHIRUH WKHLU GHDWKV, WKH YDOLDQW QHYHU WDVWH RI GHDWK EXW RQFH."

message_arr = message.split(//)

alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

alphabet_arr = alphabet.split(//)

alphabet_shift = "DEFGHIJKLMNOPQRSTUVWXYZABC"

alphabet_shift_arr = alphabet_shift.split(//)

message_arr.each do |letter|

    if letter != " "
        index = alphabet_shift_arr.index(letter)
        correct_letter = alphabet_arr[index]
        print correct_letter
    else
        print " "
    end

end

###Single Model CRUD - Planets

Create path '/'

Define our database

Create planets table

  • id integer autoincrement

  • name text

  • mass float

  • moons integer

  • distance integer

####The long SQL process

Step 1: Setting up the database

rails new solar_systems_app

Create planets.sql in db file

CREATE TABLE planets (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT,
    image TEXT,
    orbit FLOAT,
    diameter FLOAT,
    distance FLOAT,
    mass FLOAT,
    moons INTEGER
);

Table name must be plural, the model itself must be singular

create the database by running rake db:create

it will create a file called development sqlite 3

we can then cd into the db folder

run sqlite3 development.sqlite3 < planets.sql in the terminal

this pushes the planets table into the database

to test that it worked run sqlite3 development.sqlite3 .schema and it should return the table structure

Step 2: Creating a model

Now we need to create a model to make this work

The model goes in the app folder, in a folder called models

create new file planet.rb

into that file put

class Planet < ActiveRecord::Base
end

gem install annotate

run annotate

this inserts a big comment into my planet.rb file which shows the table name and characteristics

An alternative to pry:

in order to deal with pry we can type rails console in the terminal

then we can start running commands like Planet.all

In order to be in pry rather than console,

put these into my gemfile

group :development do
    gem 'pry-rails'
    gem 'pry-stack_explorer'
    gem 'annotate'
    gem 'quiet_assets'
    gem 'better_errors'
    gem 'binding_of_caller'
    gem 'meta_request'
end

then run bundle

then run rails console again

you could do earth = Planet.new

and then set all the properties

or you can do this

venus = Planet.create :name => 'Venus', :mass => 3, :diameter => 11, :distance => 1, :moons => 2

Planet.destroy_all will destory all planets

Planet.count should now show zero

Step 3: Seed data

The seeds.rb file is for seed data

Planet.create(:name => 'Earth', :orbit => 1, :moons => 1)
Planet.create(:name => 'Mars', :orbit => 1.5, :moons => 2)
Planet.create(:name => 'Venus', :orbit => 0.7, :moons => 0)
Planet.create(:name => 'Jupiter', :orbit => 3.7, :moons => 7)
Planet.create(:name => 'Pluto', :orbit => 5, :moons => 3)

Enter some seed data and then run rake db:seed in terminal

This connects the seed data with the database

to test that it worked, in the console, run Planet.count / Planet.all and the seed data should be there

if you make a mistake while playing around with your data, you can restore the original seeded data by reseeding them

first you need to add Planet.destroy_all to the top of the seeds.rb file

then when you re-run rake db:seed it will first destroy all existing planets, then reseed the original ones

rake db:drop (deletes the database)

delete sql file

so all that's in db folder is the seeds file


####Rails generating the migration for us, without us having to write SQL

in solar_system_app run

rails generate migration create_planets

the rb file should appear in the migrate folder

it tells rails to create a table

so this is the equivalent of our sql stuff, but its a lot more rubyish

class CreatePlanets < ActiveRecord::Migration
  def change
    create_table :planets do |t|
    end
  end
end

so we want to insert into the do block our table details

class CreatePlanets < ActiveRecord::Migration
  def change
    create_table :planets do |t|
        t.string :name
        t.text :image
        t.float :orbit
        t.float :mass
        t.float :diameter
        t.float :distance
        t.integer :moons
        t.timestamps
    end
  end
end

this table works across all databases now

rake db:create (creates the db)

rake db:migrate (finds any unapplied migrations and performs them)

at this point you can run annotate, then go back to the planet.rb file to check thar the table is there

at this stage we have set up the M part of our MVC model, but we haven't set up any routes

Setting up the routes:

in the routes.rb file

get '/planets' => 'planets#index'

in terminal run rails generate controller planets index

this means rails will create the file for me and create the views folder and put an index.html.erb file in there ready for me to customize

rake db:seed

rails console

Planet.all

Recap of the above steps:

rails new something -T

cd something

rails generate migration create_whatever

subl . #fill in the migration

rake db:create

rake db:migrate

touch app/models/whatever.rb

annotate

rake db:seed


http://localhost:3000/info/routes

will show you the urls and the methods to get to those urls


we changed the new planet form so that all the name values were formatted like this - planet[moons]

this is so we can view the planets better in the controller

>> params
=> {"name"=>"", "planet"=>{"image"=>"", "orbit"=>"", "mass"=>"", "diameter"=>"", "distance"=>"", "moons"=>""}, "controller"=>"planets", "action"=>"create"}
>> params[planet]
!! #<NameError: undefined local variable or method `planet' for #<PlanetsController:0x007fc52bedecc8>>
>> params["planet"]
=> {"image"=>"", "orbit"=>"", "mass"=>"", "diameter"=>"", "distance"=>"", "moons"=>""}
>> params["planet"]["name"]
=> nil
>> params["planet"].keys
=> ["image", "orbit", "mass", "diameter", "distance", "moons"]
>>

###Lab: Single Model CRUD - Oceans or Mountains

###Reading: Active Record Helpers

http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html#method-i-image_tag

###Reading: Active Record Migrations

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

You can think of each migration as being a new 'version' of the database. A schema starts off with nothing in it, and each migration modifies it to add or remove tables, columns, or entries. Active Record knows how to update your schema along this timeline, bringing it from whatever point it is in the history to the latest version.

##Wednesday

http://postgresapp.com/ - a fancier version of sqlite3

###Art Gallery code along

Thinking through the tables:

We are going to have two tables - Artists and Works

One artist can have many works.

An artist will have:

  • name (string)
  • nationality (string)
  • dob (date)
  • period (string)
  • image (text)

An artwork will have:

  • title (string)
  • year (string)
  • medium (string)
  • style (string)
  • image (text)
  • artist_id (int) *this is the association

the above layout assumes only one artist has worked on an artwork.

if you needed to have multiple artistis on one work, then you could have a third table, a join table, that just stores the ids.

it would be called artist works, with two columns, an artistid column, and a work id column.

Setting up the rails app:

rails new moma -d postgresql -T

the above won't include the sqlite gem in gemfile and will use the pg gem instead. it's telling rails which database system to use.

-t tells rails not to include any development files

add the following gems to gemfile and run bundle

group :development do
    gem 'pry-rails'
    gem 'pry-stack_explorer'
    gem 'annotate'
    gem 'quiet_assets'
    gem 'better_errors'
    gem 'binding_of_caller'
    gem 'meta_request'
end

config database.yml file, need to make some changes to the development group

we need to specify the host and username

host: localhost
  username: amysimmons

these go under the line that says database: moma_development

then we deleted everything below those lines

run rake db:create to create the database

Creating the first table:

rails generate migration create_artists

this tells it to make an artists table in the database folder, which needs to be plural, because the table will store many artists

go and add your table elements in your migrate folder

class CreateArtists < ActiveRecord::Migration
  def change
    create_table :artists do |t|
        t.string  :name
        t.string :nationality
        t.date :dob
        t.string :period
        t.text :image
        t.timestamps
    end
  end
end

then run rake db:migrate

check your schema.rb file and the table should be there

next step is to create my model

touch app/models/artist.rb

in the artist.rb file add

class Artist < ActiveRecord::Base
end

now we need to make sure the Artist class needs to be able to find the table that is associated with it

the easiest way to test it is to run annotate

then go check the artist.rb file in models folder to check that the annotation comments are there

all annotate does is add the comment at the top of that file

Creating the second table:

rails generate migration create_works

in the migrate folder add the table elements

class CreateWorks < ActiveRecord::Migration
  def change
    create_table :works do |t|
        t.string :title
        t.string :year
        t.string :medium
        t.string :style
        t.text :image
        t.timestamps
    end
  end
end

repeat above steps to set up the model and make sure the class is connected with the new table.

Adding seed data:

Added the following to the seeds.rb file

Artist.destroy_all
Work.destroy_all

Artist.create(:name => 'Joan Miro', :nationality => 'Spanish', :dob => '1893/04/20', :period => '20th century', :image => 'http://upload.wikimedia.org/wikipedia/commons/5/5c/Portrait_of_Joan_Miro%2C_Barcelona_1935_June_13.jpg')
Work.create(:title => 'The Flight of the Dragonfly in Front of the Sun', :year => '1968', :medium => 'oil on canvas', :style => 'Abstract Art', :image => 'http://uploads0.wikipaintings.org/images/joan-miro/the-flight-of-the-dragonfly-in-front-of-the-sun.jpg')

rake db:seed to run the seed file

rails console

Artist.all should get me all artists

Work.all should get me all works

Start building the routes:

in the routes file you can say i want you to create resources for artisists, it writes all those routes for you

Rails.application.routes.draw do
  resources :artists
end

resources :artists resources :works

this creates the same seven set of routes that we have been working with previously. AMAZE!!


What if I make a mistake in my table?

rake db:rollback undoes the most recent migration

fix the code

then run rake db:migrate again

then annotate again and check that it's been fixed


###Associations

###Lab: Books and Authors

##Thursday

##Friday

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment