Skip to content

Instantly share code, notes, and snippets.

@JoshCheek
Last active August 29, 2015 13:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoshCheek/9953933 to your computer and use it in GitHub Desktop.
Save JoshCheek/9953933 to your computer and use it in GitHub Desktop.
bloomberg day 2
The roster is in the back, sign in or we'll have to hunt you down!
implement scaffold
guides at guides.rubyonrails.org
docs at api.rubyonrails.org
new rails project
looking around ($ rails server)
generate the scaffold (articles with a title, body, and timestamps)
show how it works
go over the request to response flow
implement routes
get each route to work (migration, controller, model, view)
show the console
Bundler
http://bundler.io/
http://semver.org/
Gemfile - where you specify your dependencies
Gemfile.lock - the resolved dependencies (what will actually be installed and loaded)
haml:
whitespace sensitive (like python and coffeescript)
tags get a percent sign
`<h1>` becomes `%h1`
anything inside of the tag will be intented
if there is one child line, you can put it on the same line as the tag
`.something` becomes `<div class="something">`
`#something` becomes `<div id="something">`
classes and ids can be added to tags
e.g. `%h3.settings` becomes `<h3 class="settings">`
text with no prefix is rendered as-is
embeding Ruby
`<% ruby code %>` becomes `- ruby code`
`<%= ruby code %>` becomes `= ruby code`
You can also do interpolation into haml
e.g.`%p Hello, #{user.name}!`
project organization on rails
Gemfile and Gemfile.lock - Bundler files for managing dependencies
Rakefile - Quick way to add scripts you want to run from the command line (rake -T to see what is available)
app/ - Core of your application: models, views, controllers, assets
bin/ - bundler aware versions of the binaries
config/ - routes, configuration (esp config/database.yml), initializers
config.ru - hooks your app into rack (interface used by Ruby servers)
db/ - migrations, schema, seeds
lib/ - code not specific to the rails-ness of your application
log/ - logs
public/ - files served directly to user without preprocessing
test/ - tests
tmp/ - a temp dir to be used by your app/gems in your app
vendor/ - third party libraries
active record api
http://guides.rubyonrails.org/active_record_basics.html
http://guides.rubyonrails.org/migrations.html
http://guides.rubyonrails.org/association_basics.html
http://guides.rubyonrails.org/active_record_querying.html
what is ORM
provides: querying, persistence, validation, data model
how the class maps to the table
how the attributes are set
errors/validations
conventions: primary_keys, foreign_keys, timestamps
migrations:
rails g migration CreateUsers
https://gist.github.com/amejiarosario/2950888
migration methods:
add_column, add_index, change_column, change_table, create_table, drop_table,
remove_column, remove_index, rename_column
types:
binary, boolean,
string, text,
decimal, float, integer,
date, datetime, time, timestamp
tasks:
rake db:migrate - run all migrations that haven't been run yet
rake db:rollback - undo last migration
rake db:reset - drop the database, create it, run migrations
rake db:test:prepare - reset the test database
instantiation: .new and .build
querying:
.all
.first
.last
.where
.where(attribute: value)
.where(attribute: [value1, value2])
.where("id < ?", id), NEVER .where("id < #{id}") it can allow sql injection
.find_by(username: 'Mario')
.select
.pluck
.includes
callbacks and concerns:
don't use these :D
persistence:
.update_all
.create
.create!
.destroy
associations:
show a has many through
.build
validations:
http://guides.rubyonrails.org/active_record_validations.html
validates :name, presence: true
has errors, valid/invalid, won't save
some exercises
https://github.com/JoshCheek/active_record_exercises
ActiveRecord exercises:
https://github.com/JoshCheek/active_record_exercises
replace webrick with unicorn
https://devcenter.heroku.com/articles/rails-unicorn
http://unicorn.bogomips.org/Unicorn/Configurator.html
Add unicorn to Gemfile
bundle install
bundle exec unicorn
also check out bundle exec unicorn -h:
rackup file connects rails to the server,
-p to specify port
-c to specify unicorn configuration file
blogger
http://tutorials.jumpstartlab.com/projects/blogger.html
do I go through this, or they work through it from where we leave off?
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :null_session
end
# app/controllers/articles_controller.rb
require 'pp'
class ArticlesController < ApplicationController
before_action :set_article, only: [:show, :edit, :update, :destroy]
# GET /articles
# GET /articles.json
def index
@articles = Article.all
respond_to do |format|
format.html {}
format.json {}
format.xml { render xml: @articles }
end
end
# GET /articles/1
# GET /articles/1.json
def show
respond_to do |format|
format.html {}
format.json {}
format.xml { render xml: @article }
end
end
# GET /articles/new
def new
@article = Article.new
end
# GET /articles/1/edit
def edit
end
# POST /articles
# POST /articles.json
def create
@article = Article.new(article_params)
respond_to do |format|
if @article.save
format.html { redirect_to @article, notice: 'Article was successfully created.' }
format.json { render action: 'show', status: :created, location: @article }
else
format.html { render action: 'new' }
format.json { render json: @article.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /articles/1
# PATCH/PUT /articles/1.json
def update
respond_to do |format|
if @article.update(article_params)
format.html { redirect_to @article, notice: 'Article was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: @article.errors, status: :unprocessable_entity }
end
end
end
# DELETE /articles/1
# DELETE /articles/1.json
def destroy
@article.destroy
respond_to do |format|
format.html { redirect_to articles_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_article
@article = Article.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def article_params
params.require(:article).permit(:title, :body)
end
end
require 'rest-client' # => true
require 'nokogiri' # => true
# lib/blogger.rb
module Blogger
class << self
attr_accessor :base_url # => nil
end
# lib/blogger/article.rb
class Article
def self.all
raw_xml = RestClient.get Blogger.base_url + '/articles.xml' # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<articles type=\"array\">\n <article>\n <id type=\"integer\">1</id>\n <title>Title 0</title>\n <body>Body 0</body>\n <created-at type=...
xml = Nokogiri::XML(raw_xml) # => #<Nokogiri::XML::Document:0x3fc4ec65e744 name="document" children=[#<Nokogiri::XML::Element:0x3fc4ec65e26c name="articles" attributes=[#<Nokogiri::XML::Attr:0x3fc4ec65e1f4 name="type" value="a...
xml.css('articles article').map do |article_xml| # => [#<Nokogiri::XML::Element:0x3fc4ec65b5bc name="article" children=[#<Nokogiri::XML::Text:0x3fc4ec65b1d4 "\n ">, #<Nokogiri::XML::Element:0x3fc4ec65b01c name="id" attributes=[#<Nokogiri::XML:...
extract_article_from_xml article_xml # => #<Blogger::Article:0x007f89d8b77d70 @id=1, @title="Title 0", @body="Body 0">, #<Blogger::Article:0x007f89d8b752c8 @id=2, @title="Title 1", @body="Body 1">, #<Blogger::Article:0x007f89d8b6eb58 ...
end # => [#<Blogger::Article:0x007f89d8b77d70 @id=1, @title="Title 0", @body="Body 0">, #<Blogger::Article:0x007f89d8b752c8 @id=2, @title="Title 1", @body="Body 1">, #<Blogger::Article:0x007f89d8b6eb58...
end
def self.extract_article_from_xml(xml)
id = xml.at_css('id').text.to_i # => 1, 2, 3, 4, 5, 6, 7, 1, 1, 2, 3, 4, 5, 6, 7, 8
title = xml.at_css('title').text # => "Title 0", "Title 1", "Title 2", "Awesome blog!", "Awesome blog!", "Awesome blog!", "Awesome blog!", "Title 0", "Title 0", "Title 1", "Title 2", "Awesome blog!", "Awesome blog!", "Awesome blog...
body = xml.at_css('body').text # => "Body 0", "Body 1", "Body 2", "Awesome body!!", "Awesome body!!", "Awesome body!!", "Awesome body!!", "Body 0", "Body 0", "Body 1", "Body 2", "Awesome body!!", "Awesome body!!", "Awesome body!...
new id: id, title: title, body: body # => #<Blogger::Article:0x007f89d8b77d70 @id=1, @title="Title 0", @body="Body 0">, #<Blogger::Article:0x007f89d8b752c8 @id=2, @title="Title 1", @body="Body 1">, #<Blogger::Article:0x007f89d8b6eb58 ...
end
def self.find(id)
raw_xml = RestClient.get Blogger.base_url + "/articles/#{id}.xml" # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<article>\n <id type=\"integer\">1</id>\n <title>Title 0</title>\n <body>Body 0</body>\n <created-at type=\"dateTime\">2014-04-03T21:24:07Z</cr...
extract_article_from_xml Nokogiri::XML(raw_xml) # => #<Blogger::Article:0x007f89d8b3e278 @id=1, @title="Title 0", @body="Body 0">
end
attr_accessor :id, :title, :body # => nil
def initialize(attributes={})
self.id = attributes[:id] # => 1, 2, 3, 4, 5, 6, 7, 1, nil, 1, 2, 3, 4, 5, 6, 7, 8
self.title = attributes[:title] # => "Title 0", "Title 1", "Title 2", "Awesome blog!", "Awesome blog!", "Awesome blog!", "Awesome blog!", "Title 0", "Awesome blog!", "Title 0", "Title 1", "Title 2", "Awesome blog!", "Awesome blog...
self.body = attributes[:body] # => "Body 0", "Body 1", "Body 2", "Awesome body!!", "Awesome body!!", "Awesome body!!", "Awesome body!!", "Body 0", "Awesome body!!", "Body 0", "Body 1", "Body 2", "Awesome body!!", "Awesome body!...
end
def save
if new_record? # => true
create_url = Blogger.base_url + "/articles" # => "http://localhost:3000/articles"
RestClient.post create_url, article: {title: title, body: body}
else
# update
end
rescue RestClient::Found
end
def new_record?
!id # => true
end
end
end
# config/initializers/blogger.rb
Blogger.base_url = 'http://localhost:3000' # => "http://localhost:3000"
articles = Blogger::Article.all # => [#<Blogger::Article:0x007f89d8b77d70 @id=1, @title="Title 0", @body="Body 0">, #<Blogger::Article:0x007f89d8b752c8 @id=2, @title="Title 1", @body="Body 1">, #<Blogger::Article:0x007f89d8b6eb58...
articles.map { |article| article.title } # => ["Title 0", "Title 1", "Title 2", "Awesome blog!", "Awesome blog!", "Awesome blog!", "Awesome blog!"]
article = Blogger::Article.find 1 # => #<Blogger::Article:0x007f89d8b3e278 @id=1, @title="Title 0", @body="Body 0">
article.id # => 1
article.title # => "Title 0"
article.body # => "Body 0"
new_article = Blogger::Article.new title: 'Awesome blog!', body: "Awesome body!!" # => #<Blogger::Article:0x007f89d8b37130 @id=nil, @title="Awesome blog!", @body="Awesome body!!">
new_article.save # => nil
Blogger::Article.all.count # => 8
%h1 Listing articles
%table
%thead
%tr
%th Title
%th Body
%th
%th
%th
%tbody
- @articles.each do |article|
%tr
%td= article.title
%td= article.body
%td= link_to 'Show', article
%td= link_to 'Edit', edit_article_path(article)
%td= link_to 'Destroy', article, method: :delete, data: { confirm: 'Are you sure?' }
%br
= link_to 'New Article', new_article_path
%p#notice= notice
%p
%strong Title:
= @article.title
%p
%strong Body:
= @article.body
= link_to 'Edit', edit_article_path(@article)
|
= link_to 'Back', articles_path
= form_for(@article) do |f|
- if @article.errors.any?
#error_explanation
%h2
= pluralize(@article.errors.count, "error")
prohibited this article from being saved:
%ul
- @article.errors.full_messages.each do |msg|
%li= msg
.field
= f.label :title
%br
= f.text_field :title
.field
= f.label :body
%br
= f.text_area :body
.actions
= f.submit
%h1 Editing article
= render 'form'
= link_to 'Show', @article
|
= link_to 'Back', articles_path
%h1 New article
= render 'form'
= link_to 'Back', articles_path
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment