Sei sulla pagina 1di 12

Rails Curriculum

From DevchixWiki

Contents
1 Build and deploy a web application
1.1 Let's build a web application
2 Make it your own
2.1 Edit index page
2.2 Awesome! Let's ship it!
3 A Closer Look at the Features
4 First Feature: Adding topics
4.1 Scaffolding
4.2 A Quick Look at Your Database
4.3 Deploy Your Application
5 What did we just do?
5.1 A closer look
6 Routes
7 Next feature: creating a topic
7.1 Controller: adjusting the flow of your application
8 Next feature: the Topics page
9 Next feature: allow voting on a topic
9.1 How will we build this feature?
9.2 Rails associations
9.3 Add votes
9.4 Allow people to vote

Build and deploy a web application


We will build a web application that allows people to create topics and vote on them. Ultimately, this
application will have registration and authentication and a variety of other features. Today we will focus on
building the core features of topics and votes.

Here is the UI ([User Interface (http://en.wikipedia.org/wiki/User_interface|) ]) design for the application:


Let's build a web application
Create a folder on the desktop for our programming stuff
Open the terminal or command line

rails suggestotron -m http://gist.github.com/316450.txt

Everything you need for your application is in this new folder. If you decide you don't like it, just delete it
and start over with the rails command.

Note that the -m option is just a shortcut for a few commands listed in the github file (click here to see
(http://gist.github.com/194076.txt) ). It is optional. Usually you will not use that option, or maybe you will
create your own template with your frequently used options). We'll explain them in more detail later.

Go to your new folder. Notice that Rails has created the following subdirectories within it:

File/Folder Purpose
README This is a brief instruction manual for your application.
Rakefile This file contains batch jobs that can be run from the terminal.
Contains the controllers, models, and views for your application. You will do most of your
app/
work here.
config/ Configure your application’s runtime rules, routes, database, and more.
db/ Shows your current database schema, as well as the database migrations.
doc/ You would add documentation for your application here
features/ Added by the template. This is from cucumber, which is not part of core Rails
lib/ Extended modules for your application (not covered today)
log/ Application log files
The only folder seen to the world as-is. This is where your images, JavaScript, stylesheets
public/
(CSS), and other static files go
script/ Scripts provided by Rails to do recurring tasks. We'll use some today
test/ Unit tests, fixtures, and other test apparatus
tmp/ Temporary files
vendor/ A place for third-party code

Run the web app:

ruby script/server

Point your web browser to http://localhost:3000, and see your web app actually there!

Make it your own


Start Komodo Edit
File -> New -> New Project...
Open your new "suggestotron" directory
View -> Tabs & Sidebars -> Projects

Edit index page

Note that the page you are seeing at http://localhost:3000 is in public/index.html


Make a change, save, and reload

Awesome! Let's ship it!


From your new "suggestotron" directory, create a local git repository:

git init
git add .
git commit -m 'basic web application'

Then deploy to heroku:

heroku create
git push heroku master

Notice the URL that heroku reports after you typed "heroku create." Type this URL in your browser to see
your application on the Web.

A Closer Look at the Features


The features have been defined in the /features directory. These were written for you in advance as a
specification of the application.

One of the basic features that we might build first is defined in the topics.feature file in the features
directory:
Feature: Topics
In order to see a list of potential topics for meetings
people need to be able to create and edit them

Scenario: Getting to the new topic page


When I go to topics
And I follow "New topic"
Then I should see a "Create" button

You can run all of the features in that file with:

cucumber features/topics.feature

Of course, the feature fails because we haven't written any code yet! These feature descriptions are tests as
well as documentation. Typically, we run the test, watch it fail, then implement a feature, then run the test
again to see if it passes. We'll be doing that today.

The "topics" feature relies on some basic elements of a web app, which is what we'll build first. As we get
features to pass, we'll look further at the features definitions to see what needs to be built.

To run a single feature scenario, you can provide its name:

cucumber features/topics.feature -n 'Getting to the new topic page'

First Feature: Adding topics


We can look through the features and screen shots and see how a topic is defined and how people expect
to interact with it. We will use rails "scaffolding" to generate some pages and code.

topic will have a title and a description


we will enable basic "CRUD" actions:
Create - enter a new topic
Read - see everyone's topics
Update - change the topics you entered
Delete - remove your topics from the system

Scaffolding
Run this command line script to generate a Topic model along with the application logic and views:

ruby script/generate scaffold topic title:string description:text

Holy generated files, Batman!

Open the migration file (yours will have a different number):

db/migrate/20091014021209_create_topics.rb

See how it contains Ruby code to set up the database table. Migrations can also be used for modifying
tables (add/remove/rename columns) and even modifying data.

Now let's set up the database for the test by running the migration file on the test database:

rake db:migrate RAILS_ENV=test

Run the cucumber feature again (and the first one should pass)

cucumber features/topics.feature

Now let's look at the feature we created. We will typically do so in the development environment.
Create the topics table:

rake db:migrate

Then start your server:

ruby script/server

And point your browser to http://localhost:3000/topics

Congratulations! You have built a web application that works with a relational database.

A Quick Look at Your Database


You can access the database directly on your local machine. For this class we’re using SQLite, the GUI
tool you installed that lets you inspect the database. In Firefox, select "Tools -> SQLite Manager."

Click the open folder icon ! or choose Database -> Connect Database to open suggestotron/db/
development.sqlite3

In SQLite, you can choose “Browse & Search” to interactively explore the database or “Execute SQL” to
type SQL commands.

You can also access the database through the command line:

ruby script/dbconsole
Common SQL Commands
sqlite MySql
list tables in current db .tables show tables;
.schema show create table topics;
show SQL for table create list columns
.schema people describe topics;

exit command line tool .quit exit


show all rows in table select * from topics;
show number of rows select count(*) from topics;
show matching record select * from topic where title = "My Topic";

Deploy Your Application


Don’t forget, "commit early, deploy often." Here's how:

git add .
git commit -m 'topic crud'
git push heroku master
heroku rake db:migrate

Congratulations! You have built and deployed a web application that works with a relational database.

What did we just do?


Rails implements a very specific notion of the Model-View-Controller pattern which guides how you
build a web application.

Model

represents what is in the database


ActiveRecord

View

the model rendered as HTML


ActionView, erb

Controller

receives HTTP actions (GET, POST, PUT, DELETE)


decides what to do, such as rendering a view
decides what to do, such as rendering a view
ActionController

When you executed the script/generate command, Rails generated files that implement a model, views, and
a controller for the topics feature.

The Model

create app/models/topic.rb
create db/migrate/20090611073227_create_topics.rb

Four (4) Views

create app/views/topics/index.html.erb
create app/views/topics/show.html.erb
create app/views/topics/new.html.erb
create app/views/topics/edit.html.erb

The Controller

create app/controllers/topics_controller.rb
route map.resources :topics

A closer look
Rails allows you to easily invoke irb with all of the Rails libraries and your application code loaded:

ruby script/console

Let’s look at the model that is defined here: app/models/topic.rb

>> t = Topic.new
=> #<Topic id: nil, title: nil, description: nil, created_at: nil, updated_at: nil>
>> t.title = "My topic"
=> "My topic"
>> t.description = "this is really cool"
=> "this is really cool"
>> t.save
Notice that the Topic class has title and description attributes which you did not need to explicitly declare
in the class. This is handled by ActiveRecord which implements ORM (Object Relational Mapping) in
Rails.

Routes
Rails routes control how URLs map to code. We can use rake to list the relationships between routes and
controllers.

$ rake routes
topics GET /topics(.:format) {:action=>"index", :controller=>"topics"}
POST /topics(.:format) {:action=>"create", :controller=>"topics"}
new_topic GET /topics/new(.:format) {:action=>"new", :controller=>"topics"}
edit_topic GET /topics/:id/edit(.:format) {:action=>"edit", :controller=>"topics"}
topic GET /topics/:id(.:format) {:action=>"show", :controller=>"topics"}
PUT /topics/:id(.:format) {:action=>"update", :controller=>"topics"}
DELETE /topics/:id(.:format) {:action=>"destroy", :controller=>"topics"}
/:controller/:action/:id
/:controller/:action/:id(.:format)

Each method in the controller will take an HTTP request, usually find some data in the database (via an
ActiveRecord model) and render a view or re-direct to another action.

Next feature: creating a topic


Let's run the next feature and see what we need to build next.

cucumber features/topics.feature

Scenario: Creating a topic


Given I go to topics
And I follow "New topic"
When I fill in "Title" with "Rails Fixtures"
And I fill in "Description" with "Introduce how to add test data with fixtures."
And I press "Create"
Then I should see "Rails Fixtures"
And I should see a "New topic" link

Run the server ( script/server), look at the app (http://localhost:3000/topics/), and see how the scaffold
template differs from the desired application as we've described it above using cucumber. What we want is
the application to show the list of topics after the user creates a topic by completing the form. However,
the scaffold displays instead a page showing only the individual topic the user just created.

Controller: adjusting the flow of your application


We looked at the scaffold-generated code a little earlier. To change the behavior and make the feature act
as desired, we will look more closely now at the controller, which controls the general flow of your
application; for instance, which page is displayed when the user clicks a link or a button.
Open app/controllers/topics_controller.rb and look at the new and create actions.

Notice that in create there is a redirect to a single topic, format.html { redirect_to(@topic)


}. We want to redirect instead to the list of topics:

format.html { redirect_to(topics_path) }

Now run your feature again with cucumber and it should pass

cucumber features/topics.feature

Next feature: the Topics page


Note that for this next set of feature scenarios we have a "Background" set of steps which will be executed
before each scenario in the file. Since they depend on behavior that already works, they're rendered in
green (pass).

Scenario: Clicking on the topic title


When I follow "Rails Fixtures"
Then I should see "Introduce how to add test data with fixtures."
And I should not see "add a topic"

Run the scenario and watch it fail:

cucumber features/topics_list_and_details.feature

In the last scenario we made it so the app redirected to "topics_path" after create. So, we expect that
we will need to fix the error in that page. We can use rake routes to find the controller action, then
we can see that the default view is rendered. The error is in views/topics/index.html.erb:

<td><%= link_to h(topic.title), topic %></td>

Run the scenario again and see that the "Clicking on the topic title" passes, but we still have one
failure which can be addressed in the same file
Open views/topics/index.html.erb and change "Destroy" to "Delete".

Next feature: allow voting on a topic


Feature: Votes
In order to determine which talk to give
people need to be able to vote for the ones they like

Background: Make sure that we have a topic


Given I go to topics
And I follow "New topic"
When I fill in "Title" with "Rails Fixtures"
And I fill in "Description" with "Introduce how to add test data with fixtures."
And I press "Create"

Scenario: viewing votes already cast


When I go to topics
Then I should see "0 votes"

Scenario: voting on a topic


When I follow "+1"
Then I should see "1 vote"

cucumber features/votes.feature

How will we build this feature?


Each vote will be an object (row in database table)
When someone votes on a topic, we'll create a new vote object and save it
Each vote is associated with a specific topic

Rails associations

* Topic has_many :votes


* Vote belongs_to :topics

Add votes
Use cucumber to run the "votes" feature

cucumber features/votes.feature

We will use the resource generation script to create a model and controller (no views):

script/generate resource vote topic_id:integer

And then we migrate

rake db:migrate db:test:prepare

The script creates files with:


model (including migration, unit, fixture)
controller (and route) with no code

Add code to to your models ( /app/models/vote.rb and /app/models/topic.rb) to create the


associations:

class Topic < ActiveRecord::Base


has_many :votes
end

class Vote < ActiveRecord::Base


belongs_to :topic
end

Check it out in irb ( script/console):

>> t = Topic.new
=> #<Topic id: nil, title: nil, description: nil, created_at: nil, updated_at: nil>
>> t.votes
=> []
>> t.votes.build
=> #<Vote id: nil, topic_id: nil, created_at: nil, updated_at: nil>
>> t.votes
=> [#<Vote id: nil, topic_id: nil, created_at: nil, updated_at: nil>]
>> t.save
=> true
>> t.votes
=> [#<Vote id: 2, topic_id: 2, created_at: "2010-02-22 01:42:27", updated_at: "2010-02-22 01:42:27">]

TODO: Missing rake db:migrate here?

Now you can use it in your view ( /app/views/topics/index.html.erb):

<td><%= pluralize(topic.votes.length, "vote") %></td>

Allow people to vote


It's good to do one bit at a time and let the test failures drive what you do next.

Check rake routes for figuring out the pathTODO: diagram or screenshot of where this info is on the rake output , and
edit your view ( /app/views/topics/index.html.erb):

<td><%= link_to '+1', votes_path(:topic_id => topic.id), :method => :post %></td>

Now we need to create the controller action. Open the Votes controller
( /app/controllers/votes_controller.rb) to add the create action:

class VotesController < ApplicationController


def create
topic = Topic.find(params[:topic_id])
vote = topic.votes.build
if vote.save
flash[:notice] = 'Vote was successfully created.'
else
flash[:notice] = 'Sorry we could not count your vote.'
end
redirect_to(topics_path)
end
end

Retrieved from "http://wiki.devchix.com/index.php?title=Rails_Curriculum"

This page was last modified on 27 February 2010, at 03:39.


Content is available under Attribution 3.0 Unported.

Potrebbero piacerti anche