-
Notifications
You must be signed in to change notification settings - Fork 6
Home
The README.md file contains instructions on how to create your own copy of this project.
-
rake -TPrint out all available rake tasks w/ a small description of each.
-
rake routesPrint out Rails' current "routing table" as defined by
routes.rb -
rake specRun all the automated RSpec tests for this project (aka "the test suite").
-
rake db:setupRun this on a fresh Rails application to set up the databases. Note:
database.ymlmust be configured correctly. -
rake db:migrateRun all outstanding database migrations, ensuring your database schema is up to date. You'll need to run this every time you create a new migration or pull down code that includes a new migration.
This project is structured as a sequence of iterations, each of which builds on previous iterations. We do not expect students to complete each and every iteration. Rather, they serve three important roles:
- Models for good engineering and product management, i.e., what do we build, in what order, and why?
- Natural checkpoints to ask for a code review or other feedback
- The ability to accommodate students with different interests, skill levels, and time constraints.
Note: This version is already built. It's what you'll get when you clone the repository! v0.2 is the first version for you to build.
In this version
- A user may create a
Linkby submitting a destination URL to the site - A user may see a list of all
Linkssubmitted to the site - Every
Linkhas an auto-generated short URL, which a user may visit to be redirected to the original destination URL.
In short, it's like the bare minimum functionality of bit.ly.
In this version, we'll add basic click tracking so that we know how many people have clicked on each of our links. To do this:
-
Add a new integer field to the
linkstable calledclicks_countwith a default value of0and ensure it can't have aNULLvalue. Do this by running$ rails generate migration AddClickCountToLinks clicks_count:integerEdit the migration file to set the default to
0and disallowNULLvalues.See the ActiveRecord Migrations documentation for information on how to do add a new field to an existing database table. You'll want to use
rails generate migrationto create the appropriate migration, which itself should contain a call toadd_column. Hint: Search for these keywords in the documentation.Remember, run
$ bundle exec rake db:migrateto run a migration after you've created it.
-
Add the appropriate validations to the
Linkmodel. -
Create a new instance method called
Link#clicked!on theLinkmodel which increments the value ofclicks_count. -
Call
Link#clicked!in theLinksController#showaction. -
Show the
clicks_countfor each link on the homepage. -
Add appropriate model tests to
spec/models/link.rbso that we knowLink#clicked!is doing what we expect. -
Add appropriate controller tests to
spec/controllers/links_controller_spec.rbso that we know the controller is incrementing the click count.
Add support for user authentication and user accounts using ActiveRecord's has_secure_password feature. Please don't use something "off the shelf" like devise. Right now, it's important we get a clear picture of all the major moving parts involved in "user authentication."
Note: Please read the has_secure_password documentation carefully. It describes what fields you need to add to your users table. It also contains a sample of very helpful code snippets around user authentication.
This feature requires that...
- A
Usercan register for the site using their email and password - A
Usercan log in to the site using their email and password - A
Usercan see the list ofLinksthey submitted while logged in.
People should still be able to submit links without an account, though.
To create the User model, run
$ rails generate model User email:string:uniq password_digest:string
To add the user_id field on the links table, run
$ rails generate migration AddUserToLinks user:references
Again, remember to run bundle exec rake db:migrate to actually apply these migrations.
Do your best to create tests for the User model and any controllers you create. You'll likely be creating two controllers for this iteration: UsersController for creating new user-related actions and SessionsController for logging in and logging out.
Don't worry if you struggle to write tests around user authentication. Do your best and ask for feedback.
Now that we have support for user authentication, it makes sense to allow links to be updated or deleted.
- As a
User, I want to be able to edit theLinksI submit. - As a
User, I want to be able to delete theLinksI submit.
Make sure a User can only delete or edit links they've submitted and not anyone else's. Do your best to write tests for these situations.
Note: You'll need to add new methods to the LinksController and add lines to routes.rb to tell Rails how to map URLs to those new methods.
Tip: At this point, you may or may not know what Rails expects. The easiest way to find out? Create a dummy project elsewhere containing a scaffolded-out Link model. You'll be able to look around this dummy project and see how Rails likes to organize things by default.
To create the dummy project, go to a new directory (outside your url-shortener project directory) and run
$ rails new dummy-project
Inside that the dummy project's root directory, run
$ rails generate scaffold Link short_name:string url:string
This will create a "fresh" Rails application with a fully-scaffolded Link model, controller, and views. You should use this as a reference for what the Rails conventions are.
Sometimes, we won't want the world to know we love sharing links to cute animals. Let's enable some privacy. As a User, I want the option of marking the Links I submit as "private", so that they aren't listed on the homepage.
Here's the migration command:
$ rails generate migration AddPrivateToLinks private:boolean
Make sure you go into the newly-created migration file to set a default value for the field and disallow NULL values. Again, remember to run
$ bundle exec rake db:migrate
to actually apply the migration.
Right now, we're only counting the raw number of clicks on each link. If you've ever used bit.ly, though, you know it tracks much more: referrer information, geographical information, when the clicks occurred, and so on. Let's add support for this while maintaining backwards compatibility with our pre-existing click_count interface.
On the database and model side, you'll need to do two things:
- Remove the
clicks_countscolumn from thelinkstable. - Add a new table called
link_clickswhich will have one row per click containing whatever information we want to record.
Remove the clicks_counts column from the links table by creating a new migration as follows:
$ rails generate migration RemoveClickCountFromLinks clicks_count:integer
Create the LinkClick model and migration by running
$ rails generate model LinkClick link:reference referrer:string
Change the Link model as follows
class Link < ActiveRecord::Base
# We want to write link.clicks and not link.link_clicks
has_many :clicks, class_name: 'LinkClick'
# ... code ...
# e.g., link.clicked!(:referrer => request.referrer)
def clicked!(click_attributes = {})
self.clicks.create(click_attributes)
end
# Determine number of clicks by size of clicks association
# vs. field directly in links table
def clicks_count
self.clicks.count
end
endWe have a pretty sweet URL shortener at this point. You decide what you want to do to take it over the finish line. Here are some ideas:
-
Improve the user interface. We highly recommend Shay Howe's Learn to Code HTML & CSS.
-
Add cross-
Linktracking. Two users can add the same URL, but they're tracked separately. Modify the application so that if multiple users enter the same URL they all get distinct short URLs, but the application can answer questions like "How many redirects have we done to a specific URL?" and "How many times has a specific URL been shortened?"This will require a new table because a "long URL" and "short URL" are now in a 1-to-many relationship instead of a 1-to-1 relationship. That is, a "long URL" can have many "short URLs".
-
Now that we have better tracking, add better reporting. Find a way to graph clicks over the last day, week, and month. What domains are the most common sources of traffic for a given link? Note: To make interesting graphs, you might want to insert lots of fake data into your database. The faker gem makes this very easy and it's already included in the
Gemfile.