By default, Rails uses ID’s in URLs. For example, let’s say we have a list of categories stored in the categories table of the database. The “Super Cool” category is stored with categories#id = 5. To view that category our URL will look like:

http://yourAwesomeDomain.com/category/5

That works great, but it’s not very user friendly. It’s also not very good for SEO purposes. A better URL would use a human-readable and search-engine-decipherable slug instead of an ID. For example:

http://yourAwesomeDomain.com/category/super-cool

How do we get that? Easy!

First, add a column named “slug” to the categories table:

# \db\migrate\20120402020611_create_categories.rb

class CreateCategories < ActiveRecord::Migration
  def change
    create_table :categories do |t|
      t.string :name
      t.string :slug
      t.timestamps
    end
  end
end

Next, add these lines to your category model:

# \app\models\category.rb

class Category < ActiveRecord::Base
  before_create :generate_slug
  attr_protected :slug

  def generate_slug
    self.slug = name.parameterize
  end

  def to_param
    slug
  end

end

Bam! You are done. Your rails helpers and other logic will now automagically use slugs instead ID’s. For example:

@my_new_cat =  Category.create(:name => 'Super Cool')
=>  #<Category id: 3, name: "Super Cool", slug: "super-cool", created_at: "2012-04-02 18:43:08", updated_at: "2012-04-02 18:43:08">

category_path(@my_new_cat)
=> /category/super-cool

link_to(@my_new_cat.name, @my_new_cat)
=> <a href="/category/super-cool">Super Cool</a>

And in your controller, you can find the category by searching with the slug:

# \app\controllers\category_controller.rb

class CategoryController < ApplicationController
  def show
    @category = Category.find_by_slug(params[:id])
  end
end

Pretty cool, huh?

{ 0 comments }

Most of your controller methods are public actions that display pages on your website. Your app’s routes will point to these methods and show the corresponding page (view). For example:

class PostsController < ApplicationController
  def new
    @post = Post.new
  end

  def show
    @post = Post.find(params[:id])
  end

end

But hopefully you are keeping things modular and breaking up complexity into smaller methods. For example, you might want to perform some check before you allow the user to add a new post:

class PostsController < ApplicationController
  def new
    check_something
    @post = Post.new
  end

  def show
    @post = Post.find(params[:id])
  end

  def check_something
    redirect_to(root_path) and return if something
  end
end

This is great. BUT, you should be sure to make the check_something method private and make it accessible by defining it as a helper method:

class PostsController < ApplicationController
  helper_method :check_something

  def new
    check_something
    @post = Post.new
  end

  def show
    @post = Post.find(params[:id])
  end

private

  def check_something
    redirect_to(root_path) and return if something
  end
end

Why Make the Helper Methods Private?

So, why is it important to make methods like this private? Because you don’t want them to be accessible to your users. They can’t hit that method unless you have defined a route that points to it as an action. While unlikely, it’s possible that you might have such a route defined. Or, if you have some type of catch-all route defined, then this check_something method could actually be accessed by a user.

In most cases, this will be unlikely to happen. And if it does happen, it’s likely that little harm could be done. However, making these non-action methods privates also makes your code a bit more clear by declaring that these methods are NOT accessible via any routes. So, simply put, you should make the non-action methods private because it’s a best practice.

{ 0 comments }

Use Ruby’s ‘autoload’ instead of ‘require’ for your Ruby and Rails Apps

Ruby on Rails Tips

When googling to find the answer to a ruby (or rails) coding problem, it struck me that code snippets always use “require” to include any necessary libraries. For example, I recently searched for a way to compare IP addresses using CIDR notation. (I had IP ranges stored in CIDR notation and wanted to see if [...]

Read the full article →

How to test IE9, IE8 and IE7 from the same computer

windows

I’m a software developer and I often need to make sure that a web page or site will display correctly in multiple versions of Internet Explorer. Specifically, I need to test a site in Internet Explorer 7 (IE7), Internet Explorer 8 (IE8) and Internet Explorer 9 (IE9). When I installed IE9, I of course lost [...]

Read the full article →

Windows 7 Can’t Connect to Default Administrative Share C$

networking

The Problem: Windows 7 Fails to Connect to Default Windows Admin Shares on Networked Drives I got a new laptop with Windows 7 and I found I suddenly could not connect to the default administrative shares on other networked windows machines. For example: using \\remoteComputerName\C$ to connect to the default C drive admin share on [...]

Read the full article →

Firefox dropdown menus are flickering on 2nd monitor

firefox shortcuts, tweaks, and tips

The Problem: Firefox Menus Flicker and Go Blank Had a very weird problem with Firefox on my Windows 7 box. (It might also happen on Ubuntu desktop.) I switched the connection on my second, extended desktop monitor to use DVI instead of VGA. Suddenly, all the Firefox drop-down menus went blank. They would flicker briefly [...]

Read the full article →

Setting Ubunutu 10.04 Raid with Dell PowerEdge T310 and PERC S100

file commands

It turns out that Dell PowerEdge servers (like the T310) with PERC S100 do not support RAID on Ubuntu. Bummer. But here is how I got Ubunutu software RAID 1 to work with my Dell PowerEdge T310, PERC S100 and Ubuntu 10.04 LTS… The main trick was to turn re-initialize the PERC Controller to use [...]

Read the full article →

How to view and debug PHP arrays

debug

Sometimes when coding or debugging in PHP, it’s helpful to see the entire contents of an array. An easy way to do this is with the print_r command. To make it more readable, wrap it in <pre> tags. For example, to see the contents of associative array $FormData: You’ll see output like this: Array ( [...]

Read the full article →

Setup WordPress or WPMU to make an atomic version switch — AND allow you to revert

apache

I have a new WordPress MU (WPMU) install and I am ready for my first upgrade. I couldn’t get automatic upgrade to work, and all the forums said: do it by hand manually. This is fine, but I didn’t want my site to be in flux with some old an some new files as I [...]

Read the full article →

How to keep the existing file attributes (owner, timestamp, etc) when copying files or directories

command line

When copying files and especially directories, sometimes you want to keep the existing file attributes. For example, you may likely want to keep the same owner, group, timestamp, etc. You can keep the attributes by using the preserve argument. preserve=all will keep everything: You can use the -p version of preserve to keep the default [...]

Read the full article →