[Rails Level 2] REST ful routes
ROUTES BE RAKIN
Please type the rake command you use to list out all the routes on the command line.
rake routes
FORMS
Create the form for entering tweet status (text_area) and location (text_field) using the appropriate Rails view helpers. All you need is aform_for block, the input helpers, and a submit button.
class TweetsController < ApplicationController # GET /tweets/new # GET /tweets/new.json def new @tweet = Tweet.new respond_to do |format| format.html # new.html.erb format.json { render json: @tweet } end end # POST /tweets # POST /tweets.json def create @tweet = Tweet.new(params[:tweet]) respond_to do |format| if @tweet.save format.html { redirect_to @tweet, notice: 'Tweet was successfully created.' } format.json { render json: @tweet, status: :created, location: @tweet } else format.html { render action: "new" } format.json { render json: @tweet.errors, status: :unprocessable_entity } end end end ... end
Answer:
<h1>New tweet</h1> <%= form_for @tweet do |f| %> <%= f.text_area :status%> <%= f.text_field :location %> <%= f.submit %> <% end %>
INPUTS
Look at the following database table and create the proper input fields for the columns listed here.
ActiveRecord::Schema.define(:version => 20110814152905) do create_table "weapons" do |t| t.string "name" t.integer "ammo" t.boolean "is_broken" end end
Answer:
<%= form_for(@weapon) do |f| %> <%= f.text_field :name %> <%= f.number_field :ammo %> <%= f.check_box :is_broken %> <%= f.submit %> <% end %>
RADIO BUTTON
Rather than having a weapon that is broken or not, lets instead have a condition field which is either"New", "Rusty", or "Broken". Add a set of radio buttons where the user can select one of these states. Make "New" be checked by default.
<%= form_for(@weapon) do |f| %> <%= f.text_field :name %> <%= f.number_field :ammo %> <%= f.radio_button :condition, "New", checked: true %>New <%= f.radio_button :condition, "Rusty" %>Rusty <%= f.radio_button :condition, "Broken" %>Broken <%= f.submit%> <% end %>
SELECT BOX
Instead of using radio buttons, use a select box for the condition. Refactor the code below:
<%= form_for(@weapon) do |f| %> <%= f.select :condition, ["Rusty", "Broken", "New"] %> <% end %>
NESTED ROUTE
Write the nested route that will allow us to nest tweets and weapons under the zombie resource. The idea here is that a zombie has many tweets and zombie has many weapons.
RailsForZombies::Application.routes.draw do
resources :zombies do
resources :tweets
resources :weapons
end
end
ESTED PARAMS
Now that we have the proper route, we need to make sure the weapons controller properly looks up both the zombie and the weapon when we request /zombies/2/weapons/1. Finish this controller:
class Zombie < ActiveRecord::Base has_many :weapons end
class Weapon < ActiveRecord::Base belongs_to :zombie end
Answer:
class WeaponsController < ApplicationController def show @zombie = Zombie.find(params[:zombie_id]) @weapon = @zombie.weapons.find(params[:id]) end end
LINK TO
Now create the proper link_to for when we view a zombie and want to show each of its weapons, and when we want to create a new weapon for this zombie.
class WeaponsController < ApplicationController def index @zombie = Zombie.find(params[:zombie_id]) @weapons = @zombie.weapons respond_to do |format| format.html # index.html.erb format.json { render json: @weapons } end end end
Answer:
<h2><%= @zombie.name %>'s weapons</h2> <ul> <% @weapons.each do |w| %> <li><%= link_to w.name, [@zombie, w] %></li> <% end %> </ul> <%= link_to "New Weapon", new_zombie_weapon_path(@zombie) %>
NESTED FORM
Change the form_for below to use the proper nesting for creating a new weapon for a Zombie.
<%= form_for([@zombie, @weapon]) do |f| %> <%= f.text_field :name %> <%= f.submit %> <% end %>
USEFUL VIEW HELPERS
Modify the following code to make it more pretty, using titleize, to_sentence, pluralize, andnumber_to_currency (in just that order).
<h2><%= @zombie.name.titleize %></h2> <p>Weapons: <%= @zombie.weapon_list.to_sentence %></p> <p><%= pluralize(@zombie.tweets.size, "Tweets") %></p> <p>Money in Pocket <%= number_to_currency(@zombie.money) %></p>
FORM PARTIAL
Refactor the code below to move the form into the _form.html.erb partial.
<h2>New Tweet</h2> <%= form_for(@tweet) do |f| %> <div class="field"> <%= f.label :status %><br /> <%= f.text_area :status %> </div> <div class="field"> <%= f.label :location %><br /> <%= f.text_field :location %> </div> <%= f.submit %> <% end %> <%= link_to 'back', tweets_path %>
Answer:
new.html.erb:
<h2>New Tweet</h2> <%= render 'form' %> <%= link_to 'back', tweets_path %>
_form.html.erb:
<%= form_for(@tweet) do |f| %> <div class="field"> <%= f.label :status %><br /> <%= f.text_area :status %> </div> <div class="field"> <%= f.label :location %><br /> <%= f.text_field :location %> </div> <%= f.submit %> <% end %>
PARTIAL COLLECTION
Refactor the code below to use the _weapon.html.erb partial to render the list of weapons.
<h1><%= @zombie.name %>'s Weapons</h1> <% @weapons.each do |weapon| %> <%= div_for weapon do %> <h2><%= weapon.name %></h2> <p> Condition: <%= weapon.condition %> Ammo: <%= weapon.ammo %> Purchased <%= time_ago_in_words weapon.purchased_on %> ago </p> <% end %> <% end %>
Answer:
weapons/index.html.erb:
<h1><%= @zombie.name %>'s Weapons</h1> <%= render @weapons %>
weapons/_weapons.html.erb:
<% @weapons.each do |weapon| %> <%= div_for weapon do %> <h2><%= weapon.name %></h2> <p> Condition: <%= weapon.condition %> Ammo: <%= weapon.ammo %> Purchased <%= time_ago_in_words weapon.purchased_on %> ago </p> <% end %> <% end %>