diff --git a/README.md b/README.md
index 94e7ee7e..ad9905ec 100644
--- a/README.md
+++ b/README.md
@@ -4,8 +4,16 @@
| :--- |
| Review **CRUD** in the context of a Rails application, especially **update** and **delete**. |
| Implement **form helpers** in a Rails application. |
+| Get some reps on building a Rails CRUD app. |
-Researchers are collecting data on a local bog and need an app to quickly record field data. Your goal is to create a **Bog App**. If you get stuck at any point, feel free to reference the solution branch.
+Researchers are collecting data on a local bog and need an app to quickly record field data. Your goal is to create a **Bog App**. If you get stuck at any point, feel free to reference the [solution branch](https://github.com/sf-wdi-27-28/rails_bog_app/tree/solution).
+
+We want to format this project as a "time trial." You will be building the app 4 times, each time gaining skills through repetition. Here's how we want you to work:
+
+ 1. Start by making a `first-run` branch: `git checkout -b first-run`. Move through the instructions below to build your bog app. Use as many hints as you'd like to check your work and make sure you get through the lab smoothly. Commit your work along the way and at the conclusion.
+ 2. Reset your progress to the beginning by checking out master again `git checkout master` then make a `second-run` branch: `git checkout -b second-run`. Go through the lab another time. This time, time yourself on how long it takes you. Push yourself to peek at the hints more sparingly and code as much as you can on your own. Again, make sure to commit your work.
+ 3. Reset your progress to the beginning by checking out master again `git checkout master` then make a `third-run` branch: `git checkout -b third-run`. Repeat the lab a third time. Try not to use the instructions to build your bog app and refer to them only when very stuck. Time yourself again and aim to build the app faster than you built it the second time around. Make sure you have roughly the same number of commits as you had on your second run. Version control isn't the place to cut corners!
+ 4. Reset your progress to the beginning by checking out master again `git checkout master` then make a `fourth-run` branch: `git checkout -b fourth-run`. This is the fourth time; streamline your process. Squash bugs faster and look at the resources less. Commit often and build it as fast as you can!
## Background
@@ -37,13 +45,10 @@ REST stands for **REpresentational State Transfer**. We will strictly adhere to
#### 1. Set up a new Rails project
-Fork this repo, and clone it into your `develop` folder on your local machine. Change directories into `rails_bog_app`, and create a new Rails project:
+Fork this repo, and clone it into your `wdi` folder on your local machine. Change directories into `rails-bog-app`, and create a new Rails project:
```zsh
-➜ rails new bog_app -T
-➜ mv bog_app/* ./
-➜ rm -rf bog_app
-➜ rm README.rdoc
+➜ rails new bog_app -T postgresql
➜ rake db:create
➜ rails s
```
@@ -78,32 +83,43 @@ To include the Bootstrap file you just downloaded, require it in `app/assets/sty
#### 3. Define the `root` and creatures `index` routes
-In Sublime, open up `config/routes.rb`. Inside the routes `draw` block, erase all the commented text. It should now look exactly like this:
+In Atom, open up `config/routes.rb`. Inside the routes `draw` block, erase all the commented text.
+
+ ```ruby
+ #
+ # config/routes.rb
+ #
+ Rails.application.routes.draw do
-```ruby
-#
-# config/routes.rb
-#
+ end
+ ```
+
+ ```ruby
+ #
+ # config/routes.rb
+ #
-Your routes tell your app how to direct **HTTP requests** to **controller actions**. Define your `root` and creatures `index` routes as follows:
+ Rails.application.routes.draw do
+ root "creatures#index"
-```ruby
-#
-# config/routes.rb
-#
+ get "/creatures", to: "creatures#index", as: "creatures"
-Rails.application.routes.draw do
- root "creatures#index"
+ end
+ ```
+
+ ```ruby
+ #
+ # app/controllers/creatures_controller.rb
+ #
+ class CreaturesController < ApplicationController
+ # display all creatures
+ def index
+ # get all creatures from db and save to instance variable
+ @creatures = Creature.all
+ # render the index view (it has access to instance variable)
+ render :index
+ end
end
+ ```
+
- Name: <%= creature.name %>
+ Name: <%= creature.name %>Throughout the instructions, there will be hints like this one that show you the code. When you're running through the project a second time, try to use these less. The third time, try not to use them at all. Hint: `routes.rb` should now look exactly like this...
+
-Rails.application.routes.draw do
+Your routes tell your app how to direct **HTTP requests** to **controller actions**. Define your `root` route and your creatures `index` route to refer to the index method in the creatures controller:
-end
-```
+Hint:
+ Hint:
+ Here's one way that could look:
- Description: <%= creature.description %>
+ ```html
+
+
+ <% @creatures.each do |creature| %>
+
+ Description: <%= creature.description %>
+
+ ```ruby + # + #/config/routes.rb + # -Rails.application.routes.draw do - root to: "creatures#index" + Rails.application.routes.draw do + root to: "creatures#index" - get "/creatures", to: "creatures#index" - get "/creatures/new", to: "creatures#new" -end -``` + get "/creatures", to: "creatures#index" + get "/creatures/new", to: "creatures#new" + end + ``` +
++ ```ruby + # + # app/controllers/creatures_controller.rb + # -class CreaturesController < ApplicationController + class CreaturesController < ApplicationController - ... + ... - # show the new creature form - def new - render :new - end + # show the new creature form + def new + render :new + end -end -``` + end + ``` +
++ ```html + + + <%= form_for :creature, url: "/creatures", method: "post" do |f| %> + <%= f.text_field :name %> + <%= f.text_area :description %> + <%= f.submit "Save Creature" %> + <% end %> + ``` +
+-Rails.application.routes.draw do - root to: "creatures#index" + ```ruby + # + #/config/routes.rb + # - get "/creatures", to: "creatures#index", as: "creatures" - get "/creatures/new", to: "creatures#new", as: "new_creature" - post "/creatures", to: "creatures#create" + Rails.application.routes.draw do + root to: "creatures#index" -end -``` + get "/creatures", to: "creatures#index", as: "creatures" + get "/creatures/new", to: "creatures#new", as: "new_creature" + post "/creatures", to: "creatures#create" + + end + ``` +
+-class CreaturesController < ApplicationController + ```ruby + # + # app/controllers/creatures_controller.rb + # - ... + class CreaturesController < ApplicationController - # create a new creature in the database - def create - # whitelist params and save them to a variable - creature_params = params.require(:creature).permit(:name, :description) + # ... - # create a new creature from `creature_params` - creature = Creature.new(creature_params) + # create a new creature in the database + def create + # whitelist params and save them to a variable + creature_params = params.require(:creature).permit(:name, :description) - # if creature saves, redirect to route that displays all creatures - if creature.save - redirect_to creatures_path - # redirect_to creatures_path is equivalent to: - # redirect_to "/creatures" + # create a new creature from `creature_params` + creature = Creature.new(creature_params) + + # if creature saves, redirect to route that displays all creatures + if creature.save + redirect_to creatures_path + # redirect_to creatures_path is equivalent to: + # redirect_to "/creatures" + end end end - -end -``` + ``` +
+-class CreaturesController < ApplicationController + ```ruby + # + # app/controllers/creatures_controller.rb + # - ... + class CreaturesController < ApplicationController - # show the new creature form - def new - @creature = Creature.new - render :new - end + ... -end -``` + # show the new creature form + def new + @creature = Creature.new + render :new + end -This sets `@creature` to a new instance of a `Creature`, which is automatically shared with the form in `views/creatures/new.html.erb`. This allows you to refactor the code for the `form_for` helper. + end + ``` +
++ ```html + + + <%= form_for @creature do |f| %> + <%= f.text_field :name %> + <%= f.text_area :description %> + <%= f.submit "Save Creature" %> + <% end %> + ``` +
++ ```ruby + # + # config/routes.rb + # + + Rails.application.routes.draw do + root to: "creatures#index" + + get "/creatures", to: "creatures#index", as: "creatures" + get "/creatures/new", to: "creatures#new", as: "new_creature" + post "/creatures", to: "creatures#create" + get "/creatures/:id", to: "creatures#show", as: "creature" + end + ``` +
+-Now that you have your `show` route, set up the controller action for `creatures#show`: + ```ruby + # + # app/controllers/creatures_controller.rb + # -```ruby -# -# app/controllers/creatures_controller.rb -# + class CreaturesController < ApplicationController -class CreaturesController < ApplicationController + ... - ... + # display a specific creature + def show + # get the creature id from the url params + creature_id = params[:id] - # display a specific creature - def show - # get the creature id from the url params - creature_id = params[:id] + # use `creature_id` to find the creature in the database + # and save it to an instance variable + @creature = Creature.find_by_id(creature_id) - # use `creature_id` to find the creature in the database - # and save it to an instance variable - @creature = Creature.find_by_id(creature_id) + # render the show view (it has access to instance variable) + render :show + end - # render the show view (it has access to instance variable) - render :show end - -end -``` + ``` +
++ ```html + -
<%= @creature.description %>
-``` +<%= @creature.description %>
+ ``` + ++ ```ruby + # + # app/controllers/creatures_controller.rb + # + + class CreaturesController < ApplicationController + + ... + + # create a new creature in the database + def create + # whitelist params and save them to a variable + creature_params = params.require(:creature).permit(:name, :description) + + # create a new creature from `creature_params` + creature = Creature.new(creature_params) + + # if creature saves, redirect to route that displays + # ONLY the newly created creature + if creature.save + redirect_to creature_path(creature) + # redirect_to creature_path(creature) is equivalent to: + # redirect_to "/creatures/#{creature.id}" + end end - end -end -``` + end + ``` +
++ ```ruby + # + # config/routes.rb + # + + Rails.application.routes.draw do + root to: "creatures#index" + + get "/creatures", to: "creatures#index", as: "creatures" + get "/creatures/new", to: "creatures#new", as: "new_creature" + post "/creatures", to: "creatures#create" + get "/creatures/:id", to: "creatures#show", as: "creature" + get "/creatures/:id/edit", to: "creatures#edit", as: "edit_creature" + end + ``` +
++ ```ruby + # + # app/controllers/creatures_controller.rb + # -class CreaturesController < ApplicationController + class CreaturesController < ApplicationController - ... + ... - # show the edit creature form - def edit - # get the creature id from the url params - creature_id = params[:id] + # show the edit creature form + def edit + # get the creature id from the url params + creature_id = params[:id] - # use `creature_id` to find the creature in the database - # and save it to an instance variable - @creature = Creature.find_by_id(creature_id) + # use `creature_id` to find the creature in the database + # and save it to an instance variable + @creature = Creature.find_by_id(creature_id) - # render the edit view (it has access to instance variable) - render :edit - end + # render the edit view (it has access to instance variable) + render :edit + end -end -``` + end + ``` +
++ ```html + + + <%= form_for @creature do |f| %> + <%= f.text_field :name %> + <%= f.text_area :description %> + <%= f.submit "Save Creature" %> + <% end %> + ``` +
++ ```ruby + # + # config/routes.rb + # + + Rails.application.routes.draw do + root to: "creatures#index" + + get "/creatures", to: "creatures#index", as: "creatures" + get "/creatures/new", to: "creatures#new", as: "new_creature" + post "/creatures", to: "creatures#create" + get "/creatures/:id", to: "creatures#show", as: "creature" + get "/creatures/:id/edit", to: "creatures#edit", as: "edit_creature" + patch "/creatures/:id", to: "creatures#update" + end + ``` +
+-class CreaturesController < ApplicationController + ```ruby + # + # app/controllers/creatures_controller.rb + # - ... + class CreaturesController < ApplicationController - # update a creature in the database - def update - # get the creature id from the url params - creature_id = params[:id] + ... - # use `creature_id` to find the creature in the database - # and save it to an instance variable - creature = Creature.find_by_id(creature_id) + # update a creature in the database + def update + # get the creature id from the url params + creature_id = params[:id] - # whitelist params and save them to a variable - creature_params = params.require(:creature).permit(:name, :description) + # use `creature_id` to find the creature in the database + # and save it to an instance variable + creature = Creature.find_by_id(creature_id) - # update the creature - creature.update_attributes(creature_params) + # whitelist params and save them to a variable + creature_params = params.require(:creature).permit(:name, :description) - # redirect to show page for the updated creature - redirect_to creature_path(creature) - # redirect_to creature_path(creature) is equivalent to: - # redirect_to "/creatures/#{creature.id}" - end + # update the creature + creature.update_attributes(creature_params) -end -``` + # redirect to show page for the updated creature + redirect_to creature_path(creature) + # redirect_to creature_path(creature) is equivalent to: + # redirect_to "/creatures/#{creature.id}" + end + + end + ``` +
+-Rails.application.routes.draw do - root to: "creatures#index" - - get "/creatures", to: "creatures#index", as: "creatures" - get "/creatures/new", to: "creatures#new", as: "new_creature" - post "/creatures", to: "creatures#create" - get "/creatures/:id", to: "creatures#show", as: "creature" - get "/creatures/:id/edit", to: "creatures#edit", as: "edit_creature" - patch "/creatures/:id", to: "creatures#update" - delete "/creatures/:id", to: "creatures#destroy" -end -``` + ```ruby + # + # config/routes.rb + # + + Rails.application.routes.draw do + root to: "creatures#index" + + get "/creatures", to: "creatures#index", as: "creatures" + get "/creatures/new", to: "creatures#new", as: "new_creature" + post "/creatures", to: "creatures#create" + get "/creatures/:id", to: "creatures#show", as: "creature" + get "/creatures/:id/edit", to: "creatures#edit", as: "edit_creature" + patch "/creatures/:id", to: "creatures#update" + delete "/creatures/:id", to: "creatures#destroy" + end + ``` +
++ ```ruby + # + # app/controllers/creatures_controller.rb + # -class CreaturesController < ApplicationController + class CreaturesController < ApplicationController - ... + ... - # delete a creature from the database - def destroy - # get the creature id from the url params - creature_id = params[:id] + # delete a creature from the database + def destroy + # get the creature id from the url params + creature_id = params[:id] - # use `creature_id` to find the creature in the database - # and save it to an instance variable - creature = Creature.find_by_id(creature_id) + # use `creature_id` to find the creature in the database + # and save it to an instance variable + creature = Creature.find_by_id(creature_id) - # destroy the creature - creature.destroy + # destroy the creature + creature.destroy - # redirect to creatures index - redirect_to creatures_path - # redirect_to creatures_path is equivalent to: - # redirect_to "/creatures" - end + # redirect to creatures index + redirect_to creatures_path + # redirect_to creatures_path is equivalent to: + # redirect_to "/creatures" + end -end -``` + end + ``` +
+```html @@ -636,6 +759,8 @@ Add a delete button to the view that displays a single creature:
<%= @creature.description %>
<%= button_to "Delete", @creature, method: :delete %> ``` + +