SlideShare a Scribd company logo
1 of 162
Hello
Robert Dempsey
adsdevshop.com
adsdevshop.com/apps
rdempsey
A-Z Intro To
Ruby on Rails
Always
Be
Learning
Teach Others
Be Bold
Whatʼs Going On
• Introduction to Ruby
• Introduction to Rails
• Hands-on Lab
• Breaks interspersed
Ruby
1995
2006
Perl
  SmallTalk
  Eiffel
  Ada
+ Lisp
  Ruby
#10 baby!
5.times { print “We love Ruby” }
class Numeric
 def plus(x)
   self.+(x)
 end
end

y = 5.plus 6
# y is now equal to 11
Rails
2005
Image copyright 2008 Yoshiko314 (Flickr)
MVC
Model
View
Controller
Model
View
Controller
Model
View
Controller
Model
View
Controller
map.root :controller => ʻemployersʼ
Action    HTTP Method URL           XML
index     GET        /jobs          /jobs.xml

show      GET        /jobs/1        /jobs/1.xml

new       GET        /jobs/new

edit      GET        /jobs/1;edit

create    POST       /jobs          /jobs.xml

update    PUT        /jobs/1        /jobs/1.xml

destroy   DELETE     /jobs/1        /jobs/1.xml
Letʼs Build
Something
The Project
• Employers
• Jobs
rails jobby -d postgresql
rails jobby -d mysql
README
Rakefile
app/
config/
db/
doc/
lib/
log/
public/
script/
test/
tmp/
vendor/
README
Rakefile
app/
config/
db/
doc/
lib/
log/
public/
script/
test/
tmp/
vendor/
README
Rakefile
app/
config/
db/
doc/
lib/
log/
public/
script/
test/
tmp/
vendor/
README
Rakefile
app/
config/
db/
doc/
lib/
log/
public/
script/
test/
tmp/
vendor/
app/
 controllers/
 helpers/
 models/
 views/
README
Rakefile
app/
config/
db/
doc/
lib/
log/
public/
script/
test/
tmp/
vendor/
README
Rakefile
app/
config/
db/
doc/
lib/
log/
public/
script/
test/
tmp/
vendor/
README
Rakefile
app/
config/
db/
doc/
lib/
log/
public/
script/
test/
tmp/
vendor/
README
Rakefile
app/
config/
db/
doc/
lib/
log/
public/
script/
test/
tmp/
vendor/
README
Rakefile
app/
config/
db/
doc/
lib/
log/
public/
script/
test/
tmp/
vendor/
README
Rakefile
app/
config/
db/
doc/
lib/
log/
public/
script/
test/
tmp/
vendor/
README
Rakefile
app/
config/
db/
doc/
lib/
log/
public/
script/
test/
tmp/
vendor/
README
Rakefile
app/
config/
db/
doc/
lib/
log/
public/
script/
test/
tmp/
vendor/
README
Rakefile
app/
config/
db/
doc/
lib/
log/
public/
script/
test/
tmp/
vendor/
README
Rakefile
app/
config/
db/
doc/
lib/
log/
public/
script/
test/
tmp/
vendor/
development:
   adapter: postgresql
   encoding: unicode
   database: jobby_development
   pool: 5
   username: root
   password:




config/database.yml
development:
   adapter: mysql
   encoding: utf8
   database: jobby_development
   pool: 5
   username: root
   password:
   socket: /tmp/mysql.sock



config/database.yml
rake db:create
script/server
rm public/index.html
map.connect ʻ:controller/:action/:idʼ

map.connect ʻ:controller/:action/:id.:formatʼ




config/routes.rb
script/generate model Employer
script/generate scaffold Employer
   name:string
   address:string
   city:string
   state:string
   zipcode:string
exists app/models/
  exists app/controllers/
  exists app/helpers/
  create app/views/employers
  exists app/views/layouts/
  exists test/functional/
  exists test/unit/
  create test/unit/helpers/
  exists public/stylesheets/
  create app/views/employers/index.html.erb
  create app/views/employers/show.html.erb
  create app/views/employers/new.html.erb
  create app/views/employers/edit.html.erb
  create app/views/layouts/employers.html.erb
  create public/stylesheets/scaffold.css
  create app/controllers/employers_controller.rb
  create test/functional/employers_controller_test.rb
  create app/helpers/employers_helper.rb
  create test/unit/helpers/employers_helper_test.rb
   route map.resources :employers
dependency model
  exists app/models/
  exists test/unit/
  exists test/fixtures/
  create app/models/employer.rb
  create test/unit/employer_test.rb
  create test/fixtures/employers.yml
  create db/migrate
  create db/migrate/20090501175821_create_employers.rb
app/models/employer.rb
db/migrate/20090...1_create_employers.rb
app/views/employers/index.html.erb
app/views/employers/show.html.erb
app/views/employers/new.html.erb
app/views/employers/edit.html.erb
app/views/layouts/employers.html.erb
public/stylesheets/scaffold.css
app/controllers/employers_controller.rb
app/helpers/employers_helper.rb
test/functional/employers_controller_test.rb
test/unit/helpers/employers_helper_test.rb
test/unit/employer_test.rb
test/fixtures/employers.yml
route map.resources :employers
class CreateEmployers < ActiveRecord::Migration
 def self.up
   create_table :employers do |t|
    t.string :name
    t.string :address
    t.string :city
    t.string :state
    t.string :zipcode
    t.timestamps
   end
 end

 def self.down
  drop_table :employers
 end
end

db/migrations/2009...create_employers.rb
rake db:migrate
map.root :controller => ʻemployersʼ




config/routes.rb
http://localhost:3000/
class Employer < ActiveRecord::Base
end




app/models/employer.rb
class Employer < ActiveRecord::Base
   validates_presence_of :name
   validates_length_of :city, :minimum => 3
end




app/models/employer.rb
http://localhost:3000/employers/new
Controller => CRUD
Model => Logic
script/console
# GET /employers
# GET /employers.xml
def index
 @employers = Employer.all

 respond_to do |format|
  format.html # index.html.erb
  format.xml { render :xml => @employers }
 end
end


app/controllers/employers_controller.rb
# GET /employers
# GET /employers.xml
def index
 @employers = Employer.all

 respond_to do |format|
  format.html # index.html.erb
  format.xml { render :xml => @employers }
 end
end



app/controllers/employers_controller.rb
# GET /employers
# GET /employers.xml
def index
 @employers = Employer.all

   respond_to do |format|
     format.html # index.html.erb
     format.xml { render :xml =>
       @employers }
  end
end

app/controllers/employers_controller.rb
app/views/employers/index.html.erb
<%=h employer.name %>




app/views/employers/index.html.erb
<%= link_to 'New employer', ... %>




app/views/employers/index.html.erb
edit_employer_path(employer)




app/views/employers/index.html.erb
app/views/layouts/employers.html.erb
# GET /employers/new
# GET /employers/new.xml
def new
 @employer = Employer.new

 respond_to do |format|
  format.html # new.html.erb
  format.xml { render :xml => @employer }
 end
end


app/controllers/employers_controller.rb
app/views/employers/new.html.erb
# POST /employers
# POST /employers.xml
def create
 @employer = Employer.new(params[:employer])

 respond_to do |format|
  if @employer.save
    flash[:notice] = 'Employer was successfully created.'
    format.html { redirect_to(@employer) }
    format.xml { render :xml => @employer,
                         :status => :created, :location => @employer }
  else
    format.html { render :action => quot;newquot; }
    format.xml { render :xml => @employer.errors, :status
=> :unprocessable_entity }
  end
 end
end

app/controllers/employers_controller.rb
# GET /employers/1
# GET /employers/1.xml
def show
 @employer = Employer.find(params[:id])

 respond_to do |format|
  format.html # show.html.erb
  format.xml { render :xml => @employer }
 end
end




app/controllers/employers_controller.rb
app/views/employers/show.html.erb
# GET /employers/1/edit
def edit
 @employer = Employer.find(params[:id])
end




app/controllers/employers_controller.rb
app/views/employers/edit.html.erb
# PUT /employers/1
# PUT /employers/1.xml
def update
 @employer = Employer.find(params[:id])

 respond_to do |format|
  if @employer.update_attributes(params[:employer])
    flash[:notice] = 'Employer was successfully updated.'
    format.html { redirect_to(@employer) }
    format.xml { head :ok }
  else
    format.html { render :action => quot;editquot; }
    format.xml { render :xml => @employer.errors,
                         :status => :unprocessable_entity }
  end
 end
end
app/controllers/employers_controller.rb
# DELETE /employers/1
# DELETE /employers/1.xml
def destroy
 @employer = Employer.find(params[:id])
 @employer.destroy

 respond_to do |format|
  format.html { redirect_to(employers_url) }
  format.xml { head :ok }
 end
end




app/controllers/employers_controller.rb
Donʼt
Repeat
Yourself
Partials
_form.html.erb



app/views/employers/_form.html.erb
app/views/employers/_form.html.erb
<%= render :partial => 'form' %>
app/views/employers/new.html.erb
app/views/employers/edit.html.erb
<%= render :partial => 'shared/form' %>
@employer = Employer.find(params[:id])




app/controllers/employers_controller.erb
before_filter :find_employer,
   :only => [:show, :edit, :update, :destroy]




app/controllers/employers_controller.rb
app/controllers/employers_controller.rb
private
   def find_employer
    @employer = Employer.find(params[:id])
   end




app/controllers/employers_controller.rb
app/controllers/employers_controller.rb
script/generate scaffold Job
name:string
description:text
class CreateJobs < ActiveRecord::Migration
 def self.up
   create_table :jobs do |t|
    t.integer :employer_id
    t.string :name
    t.text :description
    t.timestamps
   end
 end

 def self.down
  drop_table :jobs
 end
end
db/migrations/2009...create_jobs.rb
rake db:migrate
belongs_to
has_one
has_many
has_many :through
has_one :through
has_and_belongs_to_many
jobs                employers
Model: Job             Model: Employer
belongs_to :employer   has_many :jobs
id          integer    id               integer
employer_id integer    name             string
name        string     address          string
employers                   jobs
Model: Employer          Model: Job
has_one :job             belongs_to :employer
id             integer   id          integer
name           string    employer_id integer
address        string    name        string
employers                  jobs
Model: Employer         Model: Job
has_many :jobs          belongs_to :employer
id            integer   id          integer
name          string    employer_id integer
address       string    name        string
physicians
Model: Physician
has_many :appointments
has_many :patients,
:through => :appointments
                                    appointments
id          integer
                            Model: Appointment
name        string          belongs_to :physician
                            belongs_to :patient

                            id           integer
       patients
                            physician_id integer
Model: Patient
                            patient_id   integer
has_many :appointments
has_many :physicians,
:through => :appointments

id          integer
name        string
physicians
Model: Physician
has_and_belongs_to_many :patients



id               integer               physicians_patients
name             string
                                    physician_id integer
           patients
                                    patient_id   integer
Model: Patient
has_and_belongs_to_many
:physicians


id               integer
name             string
class Job < ActiveRecord::Base
end




app/models/job.rb
class Job < ActiveRecord::Base
      belongs_to :employer

  validates_presence_of :name
  validates_presence_of :description
end




app/models/job.rb
class Job < ActiveRecord::Base
   belongs_to :employer

     validates_presence_of :name
     validates_presence_of :description
end




app/models/job.rb
class Employer < ActiveRecord::Base
     has_many :jobs

  validates_presence_of :name
  validates_length_of :city, :minimum => 3
end




app/models/employer.rb
map.resources :employers


map.resources :employers,
  :has_many => :jobs

map.resources :jobs



app/controllers/employers_controller.rb
before_filter :find_employer




app/controllers/jobs_controller.rb
app/controllers/jobs_controller.rb
private
   def find_employer
    @employer = Employer.find(params[:employer_id])
   end




app/controllers/jobs_controller.rb
app/controllers/jobs_controller.rb
# GET /jobs
# GET /jobs.xml
def index
 @jobs = @employer.jobs

 respond_to do |format|
  format.html # index.html.erb
  format.xml { render :xml => @jobs }
 end
end




app/controllers/jobs_controller.rb
# GET /jobs/new
# GET /jobs/new.xml
def new
 @job = Job.new
 @job = @employer.jobs.build

 respond_to do |format|
  format.html # new.html.erb
  format.xml { render :xml => @job }
 end
end




app/controllers/jobs_controller.rb
@job = @employer.jobs.build
app/views/jobs/index.html.erb
# POST /jobs
# POST /jobs.xml
def create
 @employer = Employer.find(params[:employer_id])
 @job = @employer.jobs.build(params[:job])

 respond_to do |format|
  if @job.save
    flash[:notice] = 'Job was successfully created.'
    format.html { redirect_to employer_job_url(@employer, @job) }
    format.xml { render :xml => @job, :status => :created, :location => @job }
  else
    format.html { render :action => quot;newquot; }
    format.xml { render :xml => @job.errors, :status => :unprocessable_entity }
  end
 end
end




app/controllers/jobs_controller.rb
# GET /jobs/1
# GET /jobs/1.xml
def show
 @job = @employer.jobs.find(params[:id])

 respond_to do |format|
  format.html # show.html.erb
  format.xml { render :xml => @job }
 end
end




app/controllers/jobs_controller.rb
app/views/jobs/show.html.erb
# GET /jobs/1/edit
def edit
 @job = @employer.jobs.find(params[:id])
end




app/controllers/jobs_controller.rb
app/views/jobs/edit.html.erb
# PUT /jobs/1
# PUT /jobs/1.xml
def update
 @job = Job.find(params[:id])

 respond_to do |format|
  if @job.update_attributes(params[:job])
    flash[:notice] = 'Job was successfully updated.'
    format.html { redirect_to employer_job_url(@employer, @job) }
    format.xml { head :ok }
  else
    format.html { render :action => quot;editquot; }
    format.xml { render :xml => @job.errors, :status
=> :unprocessable_entity }
  end
 end
end

app/controllers/jobs_controller.rb
# DELETE /jobs/1
# DELETE /jobs/1.xml
def destroy
 @job = Job.find(params[:id])
 @job.destroy

 respond_to do |format|
  format.html { redirect_to employer_jobs_url(@employer) }
  format.xml { head :ok }
 end
end




app/controllers/jobs_controller.rb
app/views/employers/show.html.erb
app/views/jobs/index.html.erb
app/views/jobs/index.html.erb
app/views/employers/index.html.erb
app/views/employers/index.html.erb
app/controllers/employers_controller.rb
app/controllers/employers_controller.rb
app/views/employers/index.html.erb
app/views/employers/index.html.erb
app/controllers/jobs_controller.rb
app/controllers/employers_controller.rb
app/views/employers/index.html.erb
Next Steps
DRY up our Job views

Add search to our jobs

Add a logins for employers

Add tags to our jobs
Resources
Rails Guides

Agile Web Development (PP)

Intro to Ruby 1.9

Cucumber + RSpec
Contest!
Letʼs Chat

More Related Content

What's hot

Introduction To Angular's reactive forms
Introduction To Angular's reactive formsIntroduction To Angular's reactive forms
Introduction To Angular's reactive formsNir Kaufman
 
BDD with Behat and Symfony2
BDD with Behat and Symfony2BDD with Behat and Symfony2
BDD with Behat and Symfony2katalisha
 
Advisor Jumpstart: JavaScript
Advisor Jumpstart: JavaScriptAdvisor Jumpstart: JavaScript
Advisor Jumpstart: JavaScriptdominion
 
Best practices for crafting high quality PHP apps (PHP Yorkshire 2018)
Best practices for crafting high quality PHP apps (PHP Yorkshire 2018)Best practices for crafting high quality PHP apps (PHP Yorkshire 2018)
Best practices for crafting high quality PHP apps (PHP Yorkshire 2018)James Titcumb
 
Polymer 2.0 codelab for extreme beginners
Polymer 2.0 codelab for extreme beginnersPolymer 2.0 codelab for extreme beginners
Polymer 2.0 codelab for extreme beginnersSylia Baraka
 
Fixture Replacement Plugins
Fixture Replacement PluginsFixture Replacement Plugins
Fixture Replacement PluginsPaul Klipp
 
Form validation client side
Form validation client side Form validation client side
Form validation client side Mudasir Syed
 
Symfony 4 Workshop - Limenius
Symfony 4 Workshop - LimeniusSymfony 4 Workshop - Limenius
Symfony 4 Workshop - LimeniusIgnacio Martín
 

What's hot (20)

Introduction To Angular's reactive forms
Introduction To Angular's reactive formsIntroduction To Angular's reactive forms
Introduction To Angular's reactive forms
 
Java script
Java scriptJava script
Java script
 
Design attern in php
Design attern in phpDesign attern in php
Design attern in php
 
BDD with Behat and Symfony2
BDD with Behat and Symfony2BDD with Behat and Symfony2
BDD with Behat and Symfony2
 
Java script basics
Java script basicsJava script basics
Java script basics
 
R3 tosrm attach
R3 tosrm attachR3 tosrm attach
R3 tosrm attach
 
TDD, BDD, RSpec
TDD, BDD, RSpecTDD, BDD, RSpec
TDD, BDD, RSpec
 
CRUD with Dojo
CRUD with DojoCRUD with Dojo
CRUD with Dojo
 
Web programming
Web programmingWeb programming
Web programming
 
Java script
Java scriptJava script
Java script
 
2. attributes
2. attributes2. attributes
2. attributes
 
Rich faces
Rich facesRich faces
Rich faces
 
Advisor Jumpstart: JavaScript
Advisor Jumpstart: JavaScriptAdvisor Jumpstart: JavaScript
Advisor Jumpstart: JavaScript
 
Best practices for crafting high quality PHP apps (PHP Yorkshire 2018)
Best practices for crafting high quality PHP apps (PHP Yorkshire 2018)Best practices for crafting high quality PHP apps (PHP Yorkshire 2018)
Best practices for crafting high quality PHP apps (PHP Yorkshire 2018)
 
Clean Code
Clean CodeClean Code
Clean Code
 
Polymer 2.0 codelab for extreme beginners
Polymer 2.0 codelab for extreme beginnersPolymer 2.0 codelab for extreme beginners
Polymer 2.0 codelab for extreme beginners
 
Java script
Java scriptJava script
Java script
 
Fixture Replacement Plugins
Fixture Replacement PluginsFixture Replacement Plugins
Fixture Replacement Plugins
 
Form validation client side
Form validation client side Form validation client side
Form validation client side
 
Symfony 4 Workshop - Limenius
Symfony 4 Workshop - LimeniusSymfony 4 Workshop - Limenius
Symfony 4 Workshop - Limenius
 

Similar to Introduction to Ruby on Rails development with MVC architecture

Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11Pedro Cunha
 
RoR 101: Session 2
RoR 101: Session 2RoR 101: Session 2
RoR 101: Session 2Rory Gianni
 
Integrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby AmfIntegrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby Amfrailsconf
 
Debugging on Rails. Mykhaylo Sorochan
Debugging on Rails. Mykhaylo SorochanDebugging on Rails. Mykhaylo Sorochan
Debugging on Rails. Mykhaylo SorochanSphere Consulting Inc
 
Crossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end FrameworkCrossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end FrameworkDaniel Spector
 
PHP 5.3 Part 2 - Lambda Functions & Closures
PHP 5.3 Part 2 - Lambda Functions & ClosuresPHP 5.3 Part 2 - Lambda Functions & Closures
PHP 5.3 Part 2 - Lambda Functions & Closuresmelechi
 
Ruby on Rails introduction
Ruby on Rails introduction Ruby on Rails introduction
Ruby on Rails introduction Tran Hung
 
Ruby On Rails Tutorial
Ruby On Rails TutorialRuby On Rails Tutorial
Ruby On Rails Tutorialsunniboy
 
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...Matt Gauger
 
Ruby on Rails - Introduction
Ruby on Rails - IntroductionRuby on Rails - Introduction
Ruby on Rails - IntroductionVagmi Mudumbai
 
Rails MVC by Sergiy Koshovyi
Rails MVC by Sergiy KoshovyiRails MVC by Sergiy Koshovyi
Rails MVC by Sergiy KoshovyiPivorak MeetUp
 
Adventurous Merb
Adventurous MerbAdventurous Merb
Adventurous MerbMatt Todd
 

Similar to Introduction to Ruby on Rails development with MVC architecture (20)

Merb
MerbMerb
Merb
 
Workshop 16: EmberJS Parte I
Workshop 16: EmberJS Parte IWorkshop 16: EmberJS Parte I
Workshop 16: EmberJS Parte I
 
Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11
 
RoR 101: Session 2
RoR 101: Session 2RoR 101: Session 2
RoR 101: Session 2
 
Integrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby AmfIntegrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby Amf
 
Flex With Rubyamf
Flex With RubyamfFlex With Rubyamf
Flex With Rubyamf
 
Red5 - PHUG Workshops
Red5 - PHUG WorkshopsRed5 - PHUG Workshops
Red5 - PHUG Workshops
 
Debugging on Rails. Mykhaylo Sorochan
Debugging on Rails. Mykhaylo SorochanDebugging on Rails. Mykhaylo Sorochan
Debugging on Rails. Mykhaylo Sorochan
 
Debugging on rails
Debugging on railsDebugging on rails
Debugging on rails
 
Crossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end FrameworkCrossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end Framework
 
PHP 5.3 Part 2 - Lambda Functions & Closures
PHP 5.3 Part 2 - Lambda Functions & ClosuresPHP 5.3 Part 2 - Lambda Functions & Closures
PHP 5.3 Part 2 - Lambda Functions & Closures
 
Ruby on Rails introduction
Ruby on Rails introduction Ruby on Rails introduction
Ruby on Rails introduction
 
Php
PhpPhp
Php
 
Ruby On Rails Tutorial
Ruby On Rails TutorialRuby On Rails Tutorial
Ruby On Rails Tutorial
 
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
 
Ruby on Rails - Introduction
Ruby on Rails - IntroductionRuby on Rails - Introduction
Ruby on Rails - Introduction
 
Ruby On Rails Introduction
Ruby On Rails IntroductionRuby On Rails Introduction
Ruby On Rails Introduction
 
Rails MVC by Sergiy Koshovyi
Rails MVC by Sergiy KoshovyiRails MVC by Sergiy Koshovyi
Rails MVC by Sergiy Koshovyi
 
Adventurous Merb
Adventurous MerbAdventurous Merb
Adventurous Merb
 
Redmine Betabeers SVQ
Redmine Betabeers SVQRedmine Betabeers SVQ
Redmine Betabeers SVQ
 

More from Robert Dempsey

Building A Production-Level Machine Learning Pipeline
Building A Production-Level Machine Learning PipelineBuilding A Production-Level Machine Learning Pipeline
Building A Production-Level Machine Learning PipelineRobert Dempsey
 
Using PySpark to Process Boat Loads of Data
Using PySpark to Process Boat Loads of DataUsing PySpark to Process Boat Loads of Data
Using PySpark to Process Boat Loads of DataRobert Dempsey
 
Analyzing Semi-Structured Data At Volume In The Cloud
Analyzing Semi-Structured Data At Volume In The CloudAnalyzing Semi-Structured Data At Volume In The Cloud
Analyzing Semi-Structured Data At Volume In The CloudRobert Dempsey
 
Practical Predictive Modeling in Python
Practical Predictive Modeling in PythonPractical Predictive Modeling in Python
Practical Predictive Modeling in PythonRobert Dempsey
 
Creating Your First Predictive Model In Python
Creating Your First Predictive Model In PythonCreating Your First Predictive Model In Python
Creating Your First Predictive Model In PythonRobert Dempsey
 
Web Scraping With Python
Web Scraping With PythonWeb Scraping With Python
Web Scraping With PythonRobert Dempsey
 
DC Python Intro Slides - Rob's Version
DC Python Intro Slides - Rob's VersionDC Python Intro Slides - Rob's Version
DC Python Intro Slides - Rob's VersionRobert Dempsey
 
Content Marketing Strategy for 2013
Content Marketing Strategy for 2013Content Marketing Strategy for 2013
Content Marketing Strategy for 2013Robert Dempsey
 
Creating Lead-Generating Social Media Campaigns
Creating Lead-Generating Social Media CampaignsCreating Lead-Generating Social Media Campaigns
Creating Lead-Generating Social Media CampaignsRobert Dempsey
 
Google AdWords Introduction
Google AdWords IntroductionGoogle AdWords Introduction
Google AdWords IntroductionRobert Dempsey
 
20 Tips For Freelance Success
20 Tips For Freelance Success20 Tips For Freelance Success
20 Tips For Freelance SuccessRobert Dempsey
 
How To Turn Your Business Into A Media Powerhouse
How To Turn Your Business Into A Media PowerhouseHow To Turn Your Business Into A Media Powerhouse
How To Turn Your Business Into A Media PowerhouseRobert Dempsey
 
Agile Teams as Innovation Teams
Agile Teams as Innovation TeamsAgile Teams as Innovation Teams
Agile Teams as Innovation TeamsRobert Dempsey
 
Introduction to kanban
Introduction to kanbanIntroduction to kanban
Introduction to kanbanRobert Dempsey
 
Get The **** Up And Market
Get The **** Up And MarketGet The **** Up And Market
Get The **** Up And MarketRobert Dempsey
 
Introduction To Inbound Marketing
Introduction To Inbound MarketingIntroduction To Inbound Marketing
Introduction To Inbound MarketingRobert Dempsey
 
Writing Agile Requirements
Writing  Agile  RequirementsWriting  Agile  Requirements
Writing Agile RequirementsRobert Dempsey
 

More from Robert Dempsey (20)

Building A Production-Level Machine Learning Pipeline
Building A Production-Level Machine Learning PipelineBuilding A Production-Level Machine Learning Pipeline
Building A Production-Level Machine Learning Pipeline
 
Using PySpark to Process Boat Loads of Data
Using PySpark to Process Boat Loads of DataUsing PySpark to Process Boat Loads of Data
Using PySpark to Process Boat Loads of Data
 
Analyzing Semi-Structured Data At Volume In The Cloud
Analyzing Semi-Structured Data At Volume In The CloudAnalyzing Semi-Structured Data At Volume In The Cloud
Analyzing Semi-Structured Data At Volume In The Cloud
 
Practical Predictive Modeling in Python
Practical Predictive Modeling in PythonPractical Predictive Modeling in Python
Practical Predictive Modeling in Python
 
Creating Your First Predictive Model In Python
Creating Your First Predictive Model In PythonCreating Your First Predictive Model In Python
Creating Your First Predictive Model In Python
 
Growth Hacking 101
Growth Hacking 101Growth Hacking 101
Growth Hacking 101
 
Web Scraping With Python
Web Scraping With PythonWeb Scraping With Python
Web Scraping With Python
 
DC Python Intro Slides - Rob's Version
DC Python Intro Slides - Rob's VersionDC Python Intro Slides - Rob's Version
DC Python Intro Slides - Rob's Version
 
Content Marketing Strategy for 2013
Content Marketing Strategy for 2013Content Marketing Strategy for 2013
Content Marketing Strategy for 2013
 
Creating Lead-Generating Social Media Campaigns
Creating Lead-Generating Social Media CampaignsCreating Lead-Generating Social Media Campaigns
Creating Lead-Generating Social Media Campaigns
 
Goal Writing Workshop
Goal Writing WorkshopGoal Writing Workshop
Goal Writing Workshop
 
Google AdWords Introduction
Google AdWords IntroductionGoogle AdWords Introduction
Google AdWords Introduction
 
20 Tips For Freelance Success
20 Tips For Freelance Success20 Tips For Freelance Success
20 Tips For Freelance Success
 
How To Turn Your Business Into A Media Powerhouse
How To Turn Your Business Into A Media PowerhouseHow To Turn Your Business Into A Media Powerhouse
How To Turn Your Business Into A Media Powerhouse
 
Agile Teams as Innovation Teams
Agile Teams as Innovation TeamsAgile Teams as Innovation Teams
Agile Teams as Innovation Teams
 
Introduction to kanban
Introduction to kanbanIntroduction to kanban
Introduction to kanban
 
Get The **** Up And Market
Get The **** Up And MarketGet The **** Up And Market
Get The **** Up And Market
 
Introduction To Inbound Marketing
Introduction To Inbound MarketingIntroduction To Inbound Marketing
Introduction To Inbound Marketing
 
Writing Agile Requirements
Writing  Agile  RequirementsWriting  Agile  Requirements
Writing Agile Requirements
 
Twitter For Business
Twitter For BusinessTwitter For Business
Twitter For Business
 

Recently uploaded

The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 

Recently uploaded (20)

The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 

Introduction to Ruby on Rails development with MVC architecture

Editor's Notes

  1. My name is Robert Dempsey
  2. I&#x2019;ll be graduating with an MBA from Crummer in August.
  3. Certified ScrumMaster
  4. I&#x2019;m the CEO of ADS, a web development shop in Orlando
  5. We develop an online suite of apps Scrum&#x2019;d: simple project management for agile teams Expens&#x2019;d: simple expense tracking Prioritiz&#x2019;d: all about getting things done
  6. Find me on Twitter
  7. My wife and daughter are here in Las Vegas
  8. Two quick movies I want to share
  9. A few people commented on our blog I can provide specific help after the tutorial
  10. Ruby
  11. Created by Yukihiro &#x201C;matz&#x201D; Matsumoto
  12. 1995 - public release
  13. 2006 - gained mass acceptance
  14. Blending of languages: Perl, Smalltalk, Eiffel, Ada, and Lisp
  15. Ranked #10 in the world on the Tiobe index, April 2009
  16. Open source
  17. Everything is an object Everything can be given it&#x2019;s own properties (instance variables) and actions (methods) All types have methods and instance variables The same rules apply everywhere
  18. Ruby is Flexible Freely alter Ruby&#x2019;s parts Remove, redefine, and extend at will
  19. Ruby is Easy on the Eyes and Brain Very limited punctuation Preference for English keywords Enhanced readability and reduced learning curve
  20. Created by David Heinemeier Hansson Extracted from Basecamp - 37signals
  21. Released to the public
  22. Full-stack framework for developing database-backed web applications Uses the Model-View-Controller pattern Builds on the power of Ruby Stresses convention over configuration
  23. Productivity gains: smaller teams, faster time to market, more concurrent projects Code management: less code = easier management Faster development Simpler solution for a common problem: web-front end to a database
  24. Data warehousing and data mining Statistics reporting Management systems Collaborative applications Community sites E-commerce applications Content management systems
  25. Open source
  26. A model represents the information (data) of the application and the rules to manipulate that data. In the case of Rails, models are primarily used for managing the rules of interaction with a corresponding database table. In most cases, one table in your database will correspond to one model in your application. The bulk of your application&#x2019;s business logic will be concentrated in the models.
  27. Views represent the user interface of your application. In Rails, views are often HTML files with embedded Ruby code that performs tasks related solely to the presentation of the data. Views handle the job of providing data to the web browser or other tool that is used to make requests from your application.
  28. Controllers provide the &#x201C;glue&#x201D; between models and views. In Rails, controllers are responsible for processing the incoming requests from the web browser, interrogating the models for data, and passing that data on to the views for presentation.
  29. One route in our app
  30. REST Maps actions to HTTP methods
  31. In the course of building this app I will explain the basics: Directory structure Migrations Models, views, controllers Routes More
  32. Generate a Rails app with the Postgres database
  33. Generate a Rails app with the MySQL database
  34. Rails directory structure
  35. This is a brief instruction manual for your application. Use it to tell others what your application does, how to set it up, and so on. On GitHub, many devs use this as the home page
  36. This file contains batch jobs that can be run from the terminal.
  37. Contains the controllers, models, and views for your application. You&#x2019;ll focus on this folder for the remainder of this tutorial.
  38. Looking into the app directory, where lot&#x2019;s of our code goes
  39. Configure your application&#x2019;s runtime rules, routes, database, and more.
  40. Shows your current database schema, as well as the database migrations.
  41. In-depth documentation for your application.
  42. Extended modules for your application (more advanced than we&#x2019;ll go today)
  43. Application log files.
  44. The only folder seen to the world as-is. This is where your images, javascript, stylesheets (CSS), and other static files go.
  45. Scripts provided by Rails to do recurring tasks, such as benchmarking, plugin installation, and starting the console or the web server.
  46. Unit tests, fixtures, and other test apparatus.
  47. Temporary files
  48. Third-party code. Gems, plugins, Rails, etc.
  49. Configure the database - Postgres
  50. Configure the database - MySQL
  51. Create the database
  52. Fire up the server Starts our application in development mode (by default) Can start the local server in development, testing, or production * Highly suggest running in production mode for testing OR set up a staging server
  53. Browse to http://localhost:3000 Should see something like this The default Rails page, located at public/index.html
  54. Remove the public index file
  55. The basic way to create the employer model
  56. Use scaffolding to create an Employer - Typically you&#x2019;d get rid of this later - You&#x2019;ll need to customize what has been generated - The better you get, the less scaffold you&#x2019;ll use
  57. Directories and files created with the generator
  58. The biggies
  59. The table and fields are created when we run this
  60. Run the migration Since we&#x2019;re in development, it will be applied to the dev database
  61. Create the default root We&#x2019;ll use this later Uncomment the line in routes.rb and change it
  62. The list page Create two employers Update one Delete one
  63. Our employer model
  64. Our employer model Add validations: these are two of many
  65. Employer errors
  66. Skinny controller fat model Jamis Buck - Rails core team member
  67. The controller has the CRUD, and that&#x2019;s it
  68. Put all logic into the model, not into the controller Result: better code reuse, keep details in templates, easier testing
  69. The console is a tool that gives us the runtime environment at a command-line Use it for testing, rather than trying everything in a browser Can fully interact with a database Can run in any Rails environment: development, testing, production Fire it up
  70. Create new objects Save objects View errors Use &#x201C;reload!&#x201D; to see updates to your models
  71. We first pull up a list of employers using the index action Above the action is the REST call We can have numerous return formats: html, xml, json
  72. Above the action is the REST call
  73. Data return formats We can have numerous return formats: html, xml, json
  74. Index view
  75. h is a Rails helper method to sanitize displayed data, preventing cross-site scripting attacks
  76. link_to builds a hyperlink to a particular destination
  77. edit_employer_path is a helper that Rails provides as part of RESTful routing. You&#x2019;ll see a variety of these helpers for the different actions that the controller includes.
  78. Employer layout <%= yield %> is where views get rendered into The scaffold generator creates a default layout for each model We can create a master layout that is applied to all, and either have a per-model layout, or remove them
  79. First, create a new employer first by showing the new form Instantiate a new employer
  80. New view Form helpers error messages, label, text field, submit
  81. The employer is then created by the create action
  82. Next we show the employer This shows only a single employer
  83. Show view
  84. If we want to edit the employer we retrieve the employer using the edit action
  85. Edit view
  86. The update action actually updates the record
  87. The destroy action will remove the employer from the database
  88. The new and edit forms have the same form fields
  89. Name the partial In the same view folder as all the other employer stuff The &#x201C;_&#x201D; indicates it&#x2019;s a partial
  90. The new partial
  91. Render the partial Can render partials that are in any folder
  92. Can render partials that are in any folder by specifying the folder and the partial name
  93. Duplicates in the show, edit, update, and delete methods
  94. Put it all into a before filter Before filters run before actions After filters run after actions Put this code underneath the controller declaration
  95. The code for the before_filter Put it at the bottom of the controller above the last end
  96. Use scaffolding to create a Job Created our model, our views, and our controller
  97. Job migration
  98. Run the migration
  99. Model relationships
  100. Belongs_to association One-to-one connection Each job can be assigned to only one employer
  101. Has_one association One-to-one connection * Used if an employer had one and only one job
  102. Has_many association The other side of the belongs_to association One-to-many connection Each instance of employer has 0 or more jobs
  103. Has_many through association Many-to-many connection The third model sets up the association
  104. Has_and_belongs_to_many association Many-to-many connection
  105. Our job model
  106. Our job model
  107. Our job model
  108. Our updated employer model with the connection to the jobs
  109. Create jobs as a nested resource within employers
  110. Just like with the Employer controller, create a before filter on the Jobs controller
  111. The code for the before_filter Put it at the bottom of the controller above the last end
  112. Index action to create a job
  113. Index view
  114. Create a new job as a resource of an Employer
  115. This creates a new Job object and sets up the employer_id field to have the id from the specified Employer object in a single operation
  116. New view
  117. Create action
  118. Show the job
  119. Show view
  120. If we want to edit the job we retrieve the job using the edit action
  121. Edit view
  122. The update action actually updates the record
  123. The destroy action will remove the job from the database
  124. Hook the employer and it&#x2019;s jobs together Update the show view for employers Each employer has it&#x2019;s own jobs collection
  125. Now we can see the employer and get to their jobs
  126. And we can see the list of jobs for the employer, and CRUD them.
  127. Add a simple search form to our index page
  128. Simple employer search Search form added to employers/index.html.erb
  129. Update the index method
  130. Keep the search in the box Updated search form Shows our query in the search box
  131. Updated index action @query allows us to capture information and use it in a form