Rails is an MVC framework built on Ruby. MVC = Model, View Controller.
Controller (covered last week)
- Facilitates control logic
- Responsible to get the information from a server request and send them to a view to be rendered.
- A bridge of communication between the models and views
Views (covered last week)
- Presentation layer.
- Templates that contain html and mixed with ruby code in order to present to the user the final response.
Models
- Facilitates business logic
- There are entities of your application that you will address using nouns, like users, tasks, etc.
- Business logic that goes around these models entail the interactions around these things, their relationships and how they should work inside of the application.
- This includes persistence, like saving data into the database.
-
Create a new rails app
$ cd workspaces $ rails _3.2.17_ new bookstore -T $ cd bookstore $ git add . $ git init . $ git commit -m "Initial commit"
-T skips test unit
-
Create a book model
$ rails generate model Book name:string page_id:integer
-
Look at generated files
- comment out attr_accessible for the time being
-
Migrate the database
$ rake db:migrate
-
Show db/schema.rb
-
Check in changes
$ git add . $ git commit -m "Create book model"
-
Rails console
$ rails console > book = Book.new > book.name = "The Bible" # Didn't have to set up an attr_accessor because rails generates one for each column in db > book.save # Now it's saved > book_2 = Book.new name: "Charlie Brown", pages: 150 # Attr Accessible Error - Fix error > reload! > book_2 = Book.new name: "Charlie Brown", pages: 150 > book_2.save > books = Books.all > book = Book.find(2) > book.name = "Calvin and Hobbes" > book.save > book.destroy
-
Start server
$ bundle exec rails s -
Visit /books (mention TDD flow)
-
Create books route in config/routes.rb
Bookstore::Application.routes.draw do get '/books' => 'books#index' end
-
Create app/controllers/books_controller.rb
class BooksController < ApplicationController end
-
Create index method
class BooksController < ApplicationController def index end end
-
Create app/views/books/index.html.erb
<h1>Books</h1> -
Add html table of books
In app/views/books/index.html.erb
<h1>Books</h1> <table> <tr> <th>Name</th> <th>Pages</th> </tr> <% @books.each do |book| %> <tr> <td><%= book.name %></td> <td><%= book.pages %></td> </tr> <% end %> </table>In app/controllers/books_controller.rb
class BooksController < ApplicationController def index @books = Book.all end end
-
Create a link to the bike detail page
In app/views/books/index.html.erb
<h1>Books</h1> <table> <tr> <th>Name</th> <th>Pages</th> </tr> <% @books.each do |book| %> <tr> <td><%= link_to book.name, "books/#{book.id}" %></td> <td><%= book.pages %></td> </tr> <% end %> </table>
-
Create the show route
Bookstore::Application.routes.draw do get '/books' => 'books#index' get '/books/:id' => 'books#show' end
-
Create the show action
class BooksController < ApplicationController #index method def show @book = Book.find params[:id] end end
-
Create app/view/books/show.html.erb
<h1><%= @book.name %></h1> <p>Pages: <%= @book.pages %></p> -
Git commit
$ git add . $ git commit -m "Displaying books"
-
Create a new link on the index page
<%= link_to "New Book", "/books/new" %> -
Create a new deck route (routes are order specific)
Bookstore::Application.routes.draw do get '/books' => 'books#index' get '/books/new' => 'books#new' get '/books/:id' => 'books#show' end
-
Create a new action in BooksController
def new @book = Book.new end
-
Create app/views/books/new.html.erb
<%= form_for @book do |f| %> <div> <%= f.label :name %> <%= f.text_field :name %> </div> <div> <%= f.label :pages %> <%= f.text_field :pages %> </div> <%= f.submit %> <% end %> -
Create a POST create route
Bookstore::Application.routes.draw do get '/books' => 'books#index' get '/books/new' => 'books#new' get '/books/:id' => 'books#show' post '/books' => 'books#create' end
-
Create a create action in BooksController (show params hash in log)
def create @book = Book.new params[:book] @book.save redirect_to "/books" end
-
Git Commit
$ git add . $ git commit -m "Add books action"
-
Add an edit link to the books page
<h1><%= @book.name %></h1> <%= link_to "Edit", "/books/#{@book.id}/edit" %> <p>Pages: <%= @book.pages %></p> -
Create edit route
Bookstore::Application.routes.draw do get '/books' => 'books#index' get '/books/new' => 'books#new' get '/books/:id/edit' => 'books#edit' get '/books/:id' => 'books#show' post '/books' => 'books#create' end
-
Create edit action
def edit @book = Book.find params[:id] end
-
Create app/views/books/edit.html.erb (copy from new.html.erb)
<%= form_for @book, url: "/books/#{@book.id}" do |f| %> <div> <%= f.label :name %> <%= f.text_field :name %> </div> <div> <%= f.label :pages %> <%= f.text_field :pages %> </div> <%= f.submit %> <% end %>Need to set url since the book already exists
-
Add update route
Bookstore::Application.routes.draw do get '/books' => 'books#index' get '/books/new' => 'books#new' get '/books/:id/edit' => 'books#edit' get '/books/:id' => 'books#show' post '/books' => 'books#create' put '/books/:id' => 'books#update' end
-
Add the update action
def update @book = Book.find params[:id] @book.update_attributes params[:book] redirect_to "/books/#{@book.id}" end
-
Git commit
$ git add . $ git commit -m "Update books action"
-
Update app/views/pages/show.html.erb to add
<%= link_to "Delete", "/books/#{@book.id}", method: :delete %>
-
Add delete destroy route
Bookstore::Application.routes.draw do get '/books' => 'books#index' get '/books/new' => 'books#new' get '/books/:id/edit' => 'books#edit' get '/books/:id' => 'books#show' post '/books' => 'books#create' put '/books/:id' => 'books#update' delete '/books/:id' => 'books#destroy' end
-
Add destroy action
def destroy @book = Book.find(params[:id]) @book.destroy redirect_to "/books" end
-
Git commit
$ git add . $ git commit -m "Destroy books action"
config/routes.rb can be changed to
Bookstore::Application.routes.draw do
resources :books
end$ rake routes
books GET /books(.:format) books#index
POST /books(.:format) books#create
new_book GET /books/new(.:format) books#new
edit_book GET /books/:id/edit(.:format) books#edit
book GET /books/:id(.:format) books#show
PUT /books/:id(.:format) books#update
DELETE /books/:id(.:format) books#destroy
First column is the name of the path helper. Can be accessed like new_book_path or new_book_url.
- Use path unless you need the absolute url.
- Path helpers are automatically set up by
resources :books
-
app/views/books/index.html
<h1>Books</h1> <%= link_to "New Book", new_book_path %> <table> <tr> <th>Name</th> <th>Pages</th> </tr> <% @books.each do |book| %> <tr> <td><%= link_to book.name, book_path(book) %></td> <td><%= book.pages %></td> </tr> <% end %> </table> -
app/views/books/show.html.erb
<h1><%= @book.name %></h1> <%= link_to "Edit", edit_book_path(@book) %> <%= link_to "Delete", book_path(@book), method: :delete %> <p>Pages: <%= @book.pages %></p> <!-- New link --> <%= link_to "Back to all books", books_path %> -
app/views/books/edit.html.erb
<%= form_for @book do |f| %> <div> <%= f.label :name %> <%= f.text_field :name %> </div> <div> <%= f.label :pages %> <%= f.text_field :pages %> </div> <%= f.submit "Edit Book" %> <% end %> -
app/controllers/books_controller.rb
class BooksController < ApplicationController def index @books = Book.all end def show @book = Book.find params[:id] end def new @book = Book.new end def create @book = Book.new params[:book] @book.save redirect_to books_path # Changed line end def edit @book = Book.find params[:id] end def update @book = Book.find params[:id] @book.update_attributes params[:book] redirect_to book_path(@book) # Changed line end def destroy @book = Book.find params[:id] @book.destroy redirect_to books_path # Changed line end end
-
git commit
$ git add . $ git commit -m "Books resource route and path helpers"
-
Show duplication between app/views/books/new.html.erb and app/views/books/edit.html.erb
-
Create app/views/books/_form.html.erb
<%= form_for @book do |f| %> <div> <%= f.label :name %> <%= f.text_field :name %> </div> <div> <%= f.label :pages %> <%= f.text_field :pages %> </div> <%= f.submit %> <% end %> -
Update app/views/books/new.html.erb and app/views/books/edit.html.erb
<%= render partial: "form" %> -
Git commit
$ git add . $ git commit -m "Extract book form partial"