From the monthly archives:

June 2009

After the third week of doing the 31 Days to Build a better blog, I’m seeing the traffic and participation on my blog increasing by leaps and bounds. This last week, the traffic increase was due primarily to being featured in the Rails Envy Podcast. The idea to email Gregg Pollack about my post 9 Ways to Use Rails Metal came from step 3 in the 31 days.

You can see from the google analytics I’ve included in this post that Wednesday and Thursday I saw significant traffic. About half of that was from Rails Envy.

Traffic from Week 3 - 31 Days to Build a Better Blog

Traffic from Week 3 - 31 Days to Build a Better Blog

Overall, I’m extremely pleased that this system has helped so many people find what I’m offering. I’m also excited that it appears to help some people with their Ruby on Rails applications. It’s encouraging me to think about other ways I can contribute to the community. You’ll probably see posts in the upcoming weeks regarding some of the things I’ll be doing to chip in and help a few more people with Ruby on Rails.

Follow this link if you’re interested in getting 31 Days to Build a Better Blog.

{ 0 comments }

A week and a half ago, I posted 9 Ways to Use Rails Metal. The fourth way I listed was “Redirecting Affiliate Links.” The basic idea is that you can set up http://mydomain.com/hosting to go to the link you were given by the hosting company you have an affiliate account with.

The first thing I did was set up a model to manage affiliate redirects.

script/generate model affiliate_redirect path:string location:string

Then I ran my migrations, to set up the database.

rake db:migrate

Then I set up a Rails Metal instance called affiliate_redirects.

script/generate metal affiliate_redirects

From there, programming Rails Metal was pretty simple. You just have to find an AffiliateRedirect with the path visited and redirect to the AffiliateRedirect’s location. Here’s the code:

require(File.dirname(__FILE__) + "/../../config/environment") unless defined?(Rails)

class AffiliateRedirects
  def self.call(env)
    redirect = AffiliateRedirect.connection.select_all("SELECT * FROM affiliate_redirects WHERE path = '#{env["PATH_INFO"]}'").first
    if redirect && (location = redirect["location"])
      [302, {"Content-Type" => "text/html", "Location" => location}, ["You are being redirected."]]
    else
      [404, {"Content-Type" => "text/html"}, ["Not Found"]]
    end
  end
end

This is the quick solution to the Rails action with nothing but a redirect_to.

{ 0 comments }

This is the second week I’ve been doing the 31 days to build a better blog. I’ve completed steps 3 through 7 this week and have seen an explosion of traffic on my blog. (See week one.)

Comparing the week (Saturday to Friday) of June 7th to the week of June 14th I’ve seen my visits jump from 34 to 198. That’s almost a 6 times increase in traffic. Here’s the graph from google analytics comparing the two weeks.

Traffic from June 14-20 vs June 7-13

Traffic from June 14-20 vs June 7-13

I thought I’d see a slight uptick in traffic from following these steps, but I had over 6 times the page views and just under 6 times the visits. My new visitors was down slightly, but what that really means is that I’m getting more and more return readers to my blog.

The information in this booklet is pure gold! I’m going to get my Dad blogging for his dental practice and we’re going to apply these same principles to get his traffic and readship up just as quickly. To say I’m pleased would be a gross understatement. I’m really excited.

Look out for my report next Monday.

{ 1 comment }

If you’re new to Ruby on Rails, you sometimes don’t know where to start with Ruby on Rails. Here are some resources that have helped me become familiar with Ruby and Ruby on Rails.

Ruby Guides

The Rails Guides have been extremely useful in explaining the different parts of Ruby on Rails. There are guides for Models, Views, Controllers, Routes, Rails Metal, Testing, etc. Most of the Guides are extremely comprehensive and have been written by experienced members of the Ruby on Rails community.

The Rails Guides are an excellent place to get started.

Railscasts

Ryan Bates has put together an excellent set of screencasts that help explain several concepts to programming in Ruby on Rails. The first episodes cover more basic topics. The later episodes cover gems and plugins that can be used to save you time and trouble building your Ruby on Rails application. Honestly, Ryan gets high marks in my book for the great work he’s done.

Rails Wiki

The Rails Wiki is a community generated set of documentation. The documentation here is excellent. The link above is to the “Getting Started with Ruby on Rails” page.

Rails Brain

Do you ever have trouble remembering exactly how to put together that link_to_remote call to get the AJAX to behave exactly the way you want? Me too. That’s why I use RailsBrain.com. The interface uses AJAX to take you to the correct place in the documentation based on what you type in the search field. In other words, you usually get the answer you’re looking for before you’re done searching.

Github

Git is the version control software of choice among Ruby and Rails developers. Github is the repository manager of choice. Most of the Ruby on Rails plugins, related gems, and even the Rails source code are stored on Github. There are also hundreds of gists that contain useful code snippets for Rubyists. If you’re looking for code samples, you’ll probably find it on Github.

Rails Tutor

Rails Tutor is in its infancy, but I highly recommend it as a place to get involved. Even if you don’t feel like you have the level of expertise to write tutorials, asking questions to flesh out the tutorials that will eventually be there will help greatly in shaping the content that new Ruby on Rails developers will be using for years to come.

Rails Envy

Rails Envy puts out a podcast every few weeks about news and postings about Ruby on Rails. I personally have heard about plugins that I downloaded and used that same day to solve some problem I was working on. I’ve also learned several things both from their discussions and the articles they refer to. For me it was kind of the jump start from the beginner phase to the intermediate phase.

NOTE: Rails Envy has been discontinued. You can find Gregg Pollack’s new Ruby on Rails new podcast at http://ruby5.envylabs.com. You can check out the old episodes and show notes for Rails Envy at the old Rails Envy website.

Rails Issue Tracking on Lighthouse

The Ruby on Rails core team tracks all of their enhancements, patches, and bugs on Lighthouse. They also put their requests for new Guides and other help up on Lighthouse. If you want to know what’s coming up in the next version of Ruby on Rails or would like to get involved or make a suggestion, Lighthouse is a great place to start.

Rails Blog

The Rails core team posts news for the community on the Rails Blog, which makes it an excellent place to go to see how they view and approach the Rails community. A lot of useful news has come out on the blog.

Feel free to add to the list in the comments for this post.

{ 5 comments }

I’ve had a few requests on how to access the session from Rack and Rails Metal. In the Rack environment that is passed to the call method, the session is stored at the ‘rack.session’ index. You can use this to both read from and write to the session. Here are some examples:

session = env['rack.session']
User.find_by_id(session["user_id"])
session = env['rack.session']
session["user_id"] = 1

{ 0 comments }

I was browsing the ActiveRecord documentation and I came across notation that looks like this:

User.name?

When I looked more closely, I realized that it replaced all of the places where I had something like this:

!User.name.blank?

In other words, if the user’s name is an empty string (“”) or nil, I can call User.name? and it’ll return false. Here’s the documentation I was browsing. http://api.rubyonrails.org/classes/ActiveRecord/Base.html

{ 2 comments }

Rails Developers do it with Models

I saw a t-shirt at Mountain West RubyConf this year that said “Rails Developers do it with Models.” Of course, they were talking about the classes we use to access the database. In fact, in Ruby on Rails, when you think of your data, you usually think of Models, not the database. The database is more a mechanism for remembering the data when you’re not using it.

Let’s look at one of the files that were generated in Part I. This file is where the model for our blog’s posts are defined.
[click to continue…]

{ 0 comments }

Last week, I wrote a post listing 9 ways to use rails metal. This is an explanation of the first way to use Rails Metal: Check Authentication.

We’re setting up this Rails Metal to handle two scenarios: requiring authentication, and logging the user in. First, it verifies that requests to any path beginning with /admin have a user logged in by checking that a valid user id is stored in the session. Second, accepts an HTTP POST to /authenticate with a username, password, and target path for redirect upon

Before we get too deep into things, let me share the code. You can check out a working version of the application on GitHub.

Here’s the Metal.

require(File.dirname(__FILE__) + "/../../config/environment") unless defined?(Rails)

class Authentication
  def self.call(env)
    session = env["rack.session"]
    request = Rack::Request.new(env)
    params = req.params
    if env["PATH_INFO"] =~ /^/admin.*/ && (session["user_id"].nil? || (session["user_id"] && User.connection.select_all("SELECT * FROM users WHERE id = #{session["user_id"]}").empty?))
      [302, {"Content-Type" => "text/html", "Location" => "/login?target_path=#{env["REQUEST_URI"]}"}, ["You must be logged in to view this page. You are being redirected."]]
    elsif env["REQUEST_METHOD"] == "POST" && env["PATH_INFO"] =~ /^/authenticate/
      users = User.connection.select_all("SELECT * FROM users WHERE username='#{params["user"]["username"]}' AND password='#{params["user"]["password"]}'")
      unless users.empty?
        session["user_id"] = users.first["id"]
        [302, {"Content-Type" => "text/html", "Location" => "#{params["target_path"] || "/"}"}, ["You have been logged in. You are being redirected."]]
      else
        [302, {"Content-Type" => "text/html", "Location" => "/login"}, ["Authentication failed. You are being redirected."]]
      end
    else
      [404, {"Content-Type" => "text/html"}, ["Not Found"]]
    end
  end
end

Bases for Understanding the Code

There are a few methods and structures here that are important to note in how this all works.

First, the self.call(env) is the entry point for the Rails Metal application. env refers to the Rack environment.

Next, Rack::Request is a class that provides a convenient interface to the Rack environment. In this case, we’re using it to extract the GET and POST parameters from the request. You can see the full Rack::Request API here.

env[‘rack.session’] returns the session as a hash. In this case, keys are accessed as strings, not symbols. So, in our case, session[:user_id] won’t work, but session[“user_id”] will work.

Finally, we do direct SQL calls through the ActiveRecord object rather than using the find method because it’s faster and we only need a few fields like the id of the user that’s found.

Overview of the Code

Checking Authentication

Our authentication code creates a session variable called user_id and places the current user’s id into it. So, to make sure someone is logged in, we need to make sure that a valid user id is in the session.

To do this we check if the path begins with /admin. env[“PATH_INFO”] contains the path without any GET parameters. So, we do a regular expression match and them move on to checking if there’s a valid user id in the session.

There are two scenarios that we need to check. There is no user id stored in the session and the user id stored is not the id of a valid user.

If both conditions are met, we redirect the user to /login and pass along the path the user was trying to access as a GET parameter called “target_path.”

Logging the user in

If a valid username and password are passed to the path /authenticate, we need to store the user’s id in the session and redirect them to where they were trying to go. To check the username and password, we query the database. If no matches are found in the database, then we send them to the login page.

Overall the code is pretty simple. Feel free to use it in any of your applications. I’ll post the benchmarks when I get a chance, but several people were looking for this content, so I’m putting it out now.

{ 7 comments }

Last week I started the 31 days to build a better blog on this blog. The week before I started—May 31 through June 6—the blog got 28 visits and 34 page views.

I’ve completed the first two days’ assignments. It was very helpful in a couple of ways. First, it helped me define exactly what I wanted to do with this blog. It also made me realize that my about page wasn’t visible from my wordpress theme, so I found a new theme and reworked my site. Finally, it guided the writing of one of my posts, which I think was very helpful both to the readers and for me as a writer. Feel free to let me know what you think so far. I’ll post the changes in traffic next week regarding these effects.

As of right now, I’ve gotten 34 visits and 42 page views this week—since the beginning of day June 7.

{ 0 comments }

I wrote a quick overview of Rails Metal earlier and started thinking that it would be nice to provide some examples of how you could use it in your Rails application. Here are 9 ways I thought of off the top of my head.

I’ll provide a quick explanation of each one and then post the code as I get each one done.

1. Authentication checking

Many sites have two parts to them. The administrative side—which is protected by an authentication system—and the public side—which anyone can access. If a user must be logged in to access the admin/authenticated part of the site, then why not take advantage of the performance boost Rails Metal gives you and redirect before the Rails even gets loaded.

UPDATE: I just posted the an explanation of how to do Rails Metal Authentication.

2. OpenID checking

Similar to the Authentication checking, you can do a quick check of the user’s authentication status with their OpenID and let them through if they are already authenticated. It’s kind of like a convenient before_filter call on that section of your website.

3. Simple API’s

API’s are extremely simple to implement with Rails Metal. If you have a convenient method on the Model to convert a given instance into the format the API user expects—to_json for example—then you could simply provide a success response with the converted object as the response text.

UPDATE: I just posted the code and explanation on how to do API’s in Rails Metal.

4. Redirecting Affiliate Links

Have you ever built a site that made money from advertising and wished you could send people to http://mydomain.com/hosting for your hosting affiliate? This would be one of the simplest uses of Rails Metal. Check the path and redirect.

UPDATE: I just posted the an explanation of how to do Rails Metal Redirects.

5. Serving Static Content

If you have pages or some other type of content that doesn’t change from one page load to the next and you don’t need the nice templating magic that the Ruby on Rails layouts give you, then this solution is for you. It allows you to make these pages database driven.

UPDATE: I just posted the an explanation of how to serve Static Content and Pages using Rails Metal.

6. Serving Downloads

Regardless of whether the file you’re serving is a file in the filesystem, or has its data stored in the database, all you really need is the file’s mime-type and its content. Then you give a success response with the content type set in the header and the file content in the response text.

7. Tracking Analytics

Rails Metal was designed to be a possible endpoint for your application, meaning that it returns a response and stops execution. However, you can perform some function and then pass the execution on to the remainder of your application. So storing visits to certain paths is a cinch with Rails Metal.

8. Serving Cached Content

Are you caching your content to memcached or the filesystem? For memcached, loading cached content is as easy as loading the memcached client gem and accessing memcached with they key. The rest is caching on the part of your rails application.

9. Triggering Server Side Events (Jobs and Rake Tasks)

Have you ever thought it would be convenient to hit a particular URL and have it kick off a process on your server? Obviously you’d have to secure it, but we can do that with another Rails Metal that checks authentication. (See #1 and #2.)

If you have any other uses that you’re putting Rails Metal to, let us all know in the comments below.

{ 7 comments }