- Use the MVC pattern in web applications with proper allocation of code and responsibilities to each layer
- Model relationships in a relational database (one-to-one, one-to-many, many-to-many)
- Use Active Record to create Associations between database tables
- Use Active Record Validations
We're going to write a simple homepage with a blog. This will be our first many-to-many relationship inside the context of Sinatra. Later, we'll integrate user authentication.
Do the Sinatra sandbox challenge first if you don't feel comfortable with the flow of a web application or how forms send data to the server.
We'll have two core models: Entry
s and Tag
s. A Entry
can have many Tag
s
and a Tag
can be on many Entry
s.
Think about your controllers and routes. Consider making three controller files:
app/controllers/index.rb
app/controllers/entries.rb
app/controllers/tags.rb
The index
controller will just have the index route, displaying your
homepage. All Entry
-related routes will go in the entries
controller and all
Tag
-related routes will go in the tags
controller.
These are features (roughly equivilent to the routes you'll need) your app should offer:
- Show all entries
- Show a particular entry (by id)
- Create a new entry
- Edit an existing entry
- Delete an existing entry
- Show all entries with a given tag. (what will this URL look like? which controller will include this route?)
Tags will be created via the Entry
-creation form.
Create all the necessary models and migrations to support the above. You should have three models — what are they?
Add the appropriate validations to your models. Read the Rails guide to ActiveRecord validations for reference.
For example, if your Entry
model has body
and title
fields, you probably
don't want to permit a Entry
that has no body
or title
to be saved to the
database. This means adding NOT NULL
constraints to the migrations and the
following validations to your ActiveRecord model:
class Entry < ActiveRecord::Base
validates :body, :presence => true
validates :title, :presence => true
end
You'll have other fields and validations, to be sure. What fields do you want your blog entry to have? Author?
Design simple pages and forms to implement all the above functionality. It doesn't need to be styled well, but if your HTML is well-structured it will make it easier to style later.
Your forms for creating and updating Entry
models should allow you to enter
tags. You can decide how that works, although from a user experience
perspective it would be incredibly tedious to have to create tags elsewhere
before an entry author can use them. However, if an entry author uses a tag that
already exists, you aren't going to want to create a new row in the tags
table, but rather re-use the already-existing tag.
One idea might be to permit them to enter tags like this:
<label for="entry_tags">Tags:</label>
<input id="entry_tags" name="entry[tags]" value="tag1, tag2, some other tag, a fourth tag">
which renders as:
Tags:
All your routes should now implement their basic functionality. You should be able to list, show, create, update, and delete entries. You should also be able to see all entries for a given tag at a url like
http://localhost:9393/tags/apple
Using valid? and invalid? and the errors methods, make sure you're handling your error cases gracefully. It doesn't need to be perfect, but good error handling means:
- When a user makes a mistake or breaks some rule, they're informed
- The user is presented with an opportunity to correct the mistake, if possible
- The user is given as much guidance as possible about that they need to do to fix the error
You might want to do the Layout Drill: Proper Typesetting first, if you haven't. But following the guidelines from that challenge, spruce up your blog design.
Make it something you're proud to look at.