Entries from April 2008
Cleaning Up User Submitted Data
A little while back, I complained about WordPress’ handling of URLs without “http://”. While it turns out WP actually handles these correctly, it brings up the question on how to handle a user’s inputted data. It’s always important to format or sanitize incoming data, and for items like URLs, which have a well-defined format, it’s really easy to do. Here’s how to do it in Rails.
One of the great things about Ruby is the way it treats just about anything as a method, so if I call link.url = "http://website.com", it’s actually calling the method Link#url= with the parameter of “http://website.com”. So, to intercept incoming data, I just overwrite the default url= method in my Link model:
class Link < ActiveRecord
def url=(new_url)
if new_url[0..6] != 'http://'
new_url = 'http://' + new_url
end
super(new_url)
end
end
So, now, when I set the url, it’s automatically formatted correctly. Some may advocate putting something like this in a before_save callback, but personally, I like to make sure the data is always correct, even when it hasn’t yet been saved.
Clean Up Your Code By Overwriting Methods
Just wanted to share a quick Rails tip that has come in useful for me in the past. Let’s say you’re creating a forum, and when users register, they create a username (like “kyleslat”). However, they can edit their profile and add their full name (like “Kyle Slattery”). They also can decide what they want to have displayed on their posts (like “Kyle S.”). All of these are fields in the database (username, full_name, and display_name, respectively). Now, when writing your templates, you have to make sure you display the correct name. If you use if-statements, this could be really messy:
<%=
if @user.display_name
@user.display_name
elsif @user.full_name
@user.full_name
else
@user.username
end
%>
Luckily, Ruby has a nice syntax that can compress that into the following:
<%= @user.display_name || @user.full_name || @user.username %>
However, you’ll likely want to display this in many different places on your forum, and what if you want to change the logic? That means a lot of code to change, and it’s really likely you’ll miss somewhere. But, what if you could just call @user.display_name, and it gave back the right name? Thanks to the ability to overwrite methods, this is really simple to do. Just do the following in your User model:
class User < ActiveRecord::Base
def display_name
super || full_name || username
end
end
Now, if you want to change what displays for a user’s name, you only have to change it in one place, rather than throughout your code.
A Review of CakePHP
Recently, on a somewhat secret project, I’ve had the opportunity to try out CakePHP, an MVC framework for PHP. I wanted to take some time to share my thoughts on what I’ve liked and disliked in my experience so far.
Missing Migrations
My #1 favorite feature in Rails has to be migrations. They allow you to very easily add and remove fields of a database without trying to keep track of SQL queries. In CakePHP, nothing like this exists (at least that I’m aware of). I’ve already had numerous issues with databases being out of sync due to having the code in three different environments (dev, staging, and production). I’ve had to resort to a combination of phpMyAdmin and text files with SQL to keep track of all the changes that need to be made.
Models Fall Short
Personally, I’m a huge subscriber to the “fat model, skinny controller” method of structuring code, which stipulates that the majority of code should reside in your models (which handle the data), rather than the controllers and views. With CakePHP, however, this is a little difficult to implement. When querying the database using a model like $this->User->findAll();, the function just returns a text array, rather than an array of objects like Rails does.
To demonstrate my point, let’s pretend I have a table of users that stores their first name as first_name and last name as last_name. I want to print out their first name, last name, and their full name (which is generated from their first and last name). With Rails, I just add the method User#full_name to the User model. Since the full object is passed to the view, I can call that method directly:
First Name: <%= @user.first_name %><br />
Last Name: <%= @user.last_name %><br />
Full Name: <%= @user.full_name %>
However, with CakePHP, since it’s only an array that’s passed, I can’t call a function, and the code gets a little messy:
First Name: <?php echo $user['User']['first_name']; ?><br />
Last Name: <?php echo $user['User']['last_name']; ?><br />
Full Name: <?php echo $user['User']['first_name] . ' ' . $user['User']['last_name']; ?>
Granted, I could use a helper function in the view, but in my eyes, generating the full name is something that should reside in the model. In this example, it’s really not that big of a problem, but as you want to do more complicated manipulations of the data, it gets a little messy with CakePHP.
Messy Syntax
While it isn’t totally the fault of CakePHP, but rather of PHP itself, Cake requires some pretty messy syntax to accomplish things. For example, let’s say I have posts that have both an editor and an author. To define these relationships in Cake, I’d have to do the following:
// user.php
class User extends AppModel {
var $name = 'User';
var $hasMany = array('EditedPosts' =>
array('className' => 'Post',
'foreignKey' => 'editor_id'),
'AuthoredPosts' =>
array('className' => 'Post',
'foreignKey' => 'author_id')
);
}
// post.php
class Post extends AppModel {
var $name = 'Post';
var $belongsTo = array('Editor' =>
array('className' => 'User',
'foreignKey' => 'editor_id'),
'Author' =>
array('className' => 'User',
'foreignKey' => 'author_id')
);
}
Pretty confusing, huh? All the arrays really get in the way. In Rails, the same situation would be done like this:
# user.rb
class User < ActiveRecord::Base
has_many :edited_posts, :foreign_key => 'editor_id',
:class => 'Post'
has_many :authored_posts, :foreign_key => 'author_id',
:class => 'Post'
end
# post.rb
class Post < ActiveRecord::Base
belongs_to :editor, :class => 'User'
belongs_to :author, :class => 'User'
end
To me, the Rails code is a lot easier to read and makes much more sense. Like I said before though, this is really a Ruby vs PHP issue and not Rails vs CakePHP.
Super Easy Deployment
It may seem like I’m really ragging on CakePHP, but there are definitely things I like compared to Rails. One of my (and many others’) major gripes about Rails is how difficult it is to deploy an application: there’s a lot of server side configuration that can get really confusing. With CakePHP, however, it’s practically a non-issue. Since that supports PHP (which I’m guessing is 99% of shared hosting). Just upload your files, and you’re ready to go. With Rails, setting up a production environment would require setting up Apache forwarding, Mongrel instances, and more. In this department, Rails really can’t compete with Cake.
More Resources for the Beginner
PHP has perhaps the best online documentation of any language out there. Every function is well documented, and most have user comments below with tips and explanations on various quirks. It’s also a very widely used language, which means a lot more people can help you out if you have issues. Even though CakePHP itself isn’t particularly well documented, it definitely benefits from the many PHP resources out there. Ruby, on the other hand, though things are getting better, isn’t nearly as well documented as PHP and doesn’t really have a central place to go like PHP.net. There also aren’t nearly as many people that are familiar with the language.
CakePHP is Beginner-Friendly
Though CakePHP is lacking in a many areas where Rails really excels, I think it definitely has its place in the world of web frameworks. I would definitely consider using it on smaller-scale projects where I don’t want to deal with the complicated setup of a Rails production environment. It’s also a little more accessible for beginners than Rails because of the vast PHP community. However, for a user requiring a more powerful framework, I currently don’t think there’s much out there that’s better than Rails.
Building a CMS: Simplifying Posts with Single Table Inheritance
“Posts” will make up the majority of my site’s content, and there will be a few different types: articles, reviews, links, and comments. While I could create separate tables in the database for each, I’ve decided to utilize Rails’ single table inheritance, whereby multiple models share the same table and some common behavior. However, STI is not limited to Rails; it’s a general design pattern where one table is used for multiple objects or models.
Rails and Single Table Inheritance
In Rails, every table in the database is represented as a “Model” (which follows the model-view-controller design). So, for instance, a standard Post might look something like this:
class Post < ActiveRecord::Base
# model methods go here
end
This model will store its data in the “posts” table in your database. Now, to implement STI in Rails, all I have to do is create models, but instead of inheriting from ActiveRecord::Base, I inherit from Post, like below:
class ArticlePost < Post
# model methods go here
end
Now all that’s left is to add a “type” column to the “posts” table in the database, and Rails automatically figures out the rest. I’ll go into more detail about this in a future post.
Why STI is Awesome
The basic reason I wanted to go with STI is it makes it very easy to pull different types of data from the database at once and display them. Instead of making a query for each type of post, I can just do @posts = Post.find(:all), and Rails pulls every type of Post and even makes each the right object type (e.g. if the table row has a type of “ArticlePost,” Rails returns an ArticlePost object, not just a Post object).
Single Table Inheritance also makes it very easy to share behaviors between different types of posts, especially the way it’s implemented in Rails. Since each object is a child of the Post model, I only have to write standard behavior once, such as post status and commenting.
Potential Pitfalls
One of the main problems with STI is that it can lead to cumbersome database tables with many columns, since each child model might require different fields. When the database table gets very large, this could potentially cause issues and slowdowns. However, in my case, since each post has the same basic fields (title, body, author, etc.) with only a few specific fields (product name for reviews, link urls for link posts, etc.), I don’t see this becoming an issue. Also, since I’m never expecting the database table to reach, say, 100,000 rows, it’s doubtful there will be much of a performance loss.
Comments as Posts?
While it was a simple decision to handle articles, reviews, and links as subclasses of “Post,” I had a little trouble coming up with how to best handle comments. I had two choices, either I make comments just another type of Post (i.e. CommentPost), or I create a new table and model just for comments. In the end decided on STI, because, once again, I can take advantage of shared behaviors to cut down on code. Also, since a comment is just a “Post,” it will make it easy to “comment on a comment” to create a threaded discussion.
More to come
Since this was more of an overview of STI, in a future post, I’ll try to explore more of Rails’ implementation of single table inheritance and how to best use it.
Valid URLs and Wordpress
Today, while poking around WordPress 2.5’s menus, I came across this on the “Write Link” page, and I got a little angry:

Why in the world should I have to remember to add “http://” to my links? It should be the responsibility of the software, not the user, to check and fix a formatting issue as simple as this.
UPDATE: Very shortly after posting this, I realized WordPress actually does fix the URLs for you. That being said, why is the warning there in the first place?
Building a Content Management System on Rails
In my first post, I mentioned building a content management system from scratch. To introduce the project, I figured I should go through my reasons for it, and what I want to accomplish.
Why write my own?
Sure, there are loads of systems out there for running a web site, and it’d be really easy to take something like the incredible ExpressionEngine and get it to do what I want. However, using existing software means I don’t get the experience of writing one myself.
Also, by writing it myself, I don’t have to try and work around an existing structure to get my site to operate the way I want. If I want a feature, I can just dive into the code and add it, rather than reading through plugin documentation and existing code.
What’s it going to do?
A few of the features I want to implement:
- Blog Posts
- Link Posts (i.e. my own del.icio.us)
- Review Posts
- Portfolio Management (to replace my current portfolio)
- Comments
- Static Page Management
- RSS Feeds for everything
- Caching System
- User Management
This is a pretty general list, but as I start working on it, I’ll go into detail about each of the site’s features.
Why Ruby on Rails?
Simply put, I love Ruby, and I love Rails. If you’ve never used either, however, don’t despair! Although I’ll have a lot of Ruby and Rails specific material, my focus will be more on designing the structure of the application, rather than going through the underlying code.
Stay tuned!
I’m going to try to post pretty regular updates on my progress, so make sure to check back often if you want to see how it’s going!
A New Beginning
I’m no good at introductions, but I feel like my first post needs to accomplish something, so here we go, a brief introduction to me and the site.
All About Me
I’m Kyle Slattery, a college student and freelance web developer and designer. Technology and the internet have always been interests of mine, and I love being able to do something I enjoy for a job. You can see some of the work I’ve done in my portfolio, and I also hope to be able to showcase my work through this blog as well. At some point, I’ll write up a complete bio, and put it in my about section, but for now, this will have to do
The Site
First things first, yes, I realize I am a web designer, yet I’m using an existing WordPress template. I really wanted to get this site up, so I haven’t yet had the time to put together a design. I’m also planning on coding my own content management system for the site (more on this later), and I’ll likely want to redesign the site when I do that anyways.
My plans for this site are pretty simple: I want a place to communicate my thoughts on web development and design and also somewhere to post various helpful tips I’ve found throughout my web adventures. Right now the site is powered by WordPress 2.5, but I’m planning on writing my own content management system with Ruby on Rails. Posts about this process will likely take up a lot of the space on this site, as I think documenting my trials and tribulations could be helpful to other developers out there.
I don’t really have much more to say than that, as my posts will hopefully speak for themselves. Enjoy!
