Jeremy Hubert Baker's Random Thoughts

  • Archive
  • RSS
  • Ask me anything

Rails 3: Removing or adding www in the url

I don’t like having two separate domains that point to the same content for a number of reasons. Caching and SEO optimization are two them that make it worth dealing with for me. Here is how I deal with that in Rails 3.

Usually, I would handle this in my webserver config file but since I’ve started using Heroku I don’t have access to a config file so the Rails application needs to handle that for me.

One way to do the redirect is to have some code in your application_controller.rb file that checks for www. and then behaves accordingly. Like this:

before_filter :strip_www

def strip_www
  if request.env["HTTP_HOST"] == "myapp.com"
    redirect_to "http://www.myapp.com/"
  end
end

This functions just fine, however, there is no need to load the entire application stack just to do a redirection.

Fortunately, Rails runs on Rack which means you can run some pretty awesome middleware and a few of the guys over at pivotal labs have done just that.

Enter Refraction.

Refraction is a piece of middleware that gives you a router before the request reaches your main application stack, which means you can intercept the call and perform a redirect on it without loading a bunch of unnecessary code. You can read a lot more about it in the README file on GitHub.

All I’m going to show you here is how to ADD “www.” to a request that doesn’t have it. These instructions are fairly similar to the README.md, with the exception of the refraction_rules and a small change to the production.rb call.

First, install the refraction gem. I recommend adding “gem ‘refraction’” to your Gemfile and running “bundle install” in your app. This will also install it on Heroku when you push.

Once you have done that, we are going to add the following call near the top of your config/environments/production.rb file:

config.middleware.insert_before(::Rack::Lock, ::Refraction)

and then create a new file inside the config/initializers/ folder called refraction_rules.rb that has the following content in it:

Refraction.configure do |req|
  req.permanent! :host => "www.mydomain.com" if req.host !~ /^www./
end

Once that’s done, you should be good to go. I tested this on my dev box by setting my /etc/hosts file up to point www.mydomain.com and mydomain.com to 127.0.0.1 which should work nicely for testing. :)

Good luck!

    • #ruby
    • #routing
  • 1 year ago
  • 11
  • Permalink
  • Share
    Tweet

Restart just one mongrel configuration

sudo mongrel_rails cluster::restart -C /etc/mongrel_cluster/file.conf

    • #ruby
    • #development
  • 4 years ago
  • Permalink
  • Share
    Tweet

Serialized Multiple Select in Rails

In the current app i’m working on, I wanted to store multiple values in a single column. I know, violation of the first normal form.. blah blah blah. Save it.

Anyway, I wanted to have a multiple select box that would easily allow me to Manage and update the attributes of the model. Here is my solution.

Create the database table

create_table :tshirt, :force => true do |t|
  t.column :available_colors, :string
  t.column :available_sizes, :string
end

Create the Model

class Tshirt < ActiveRecord::Base
  serialize :available_colors, Array
  serialize :available_sizes, Array
end

Create the YAML Options Hash

I use an options.yml file in the config directory to setup the options for the object. A containing hash is created using the name of the object, and then the sub-hashes match the name of the column.

./config/options.yml

tshirt:
  available_colors:
    1: Red
    2: Blue
    3: Green
  available_sizes:
    1: Small
    2: Medium
    3: Large

Load the Options File into the App

In your environment.rb file you have to load the YAML parser and then parse the options.yml file:

require ‘yaml’ OPTIONS = YAML::load(File.open(”#{RAILS_ROOT}/config/options.yml”))

The Select Box

This is the hard part.

module ActionView
  module Helpers
    module FormOptionsHelper
      include ERB::Util
      def serialized_multiple_select(object, method, choices = {}, options = {}, html_options = {})
        html = []
        html << “<select id=\"#{object}_#{method}\" name=\"#{object}#{method}\” multiple=\”multiple\” size=\”5\”>” 
        html << options_for_select(OPTIONSobject.invert,self.instance_variable_get(’@’+object).send(method).collect{|x| x.to_i })
        html << “” 
        return html
      end
    end
  end
end

Add the select box to your form

And this is the easy part:

Colors: <%= serialized_multiple_select ‘tshirt’, ‘available_colors’ %>

Sizes: <%= serialized_multiple_select ‘tshirt’, ‘available_sizes’ %>

I am pretty sure there are better way to do this, but this one worked for me.

Also, my serialized_multiple_select has options that it doesn’t even use. I should really use them. Please offer feedback if you have any. :)

    • #rails
    • #ruby
    • #development
  • 4 years ago
  • Permalink
  • Share
    Tweet

About

A collection of thoughts from Jeremy Baker, a curious and adventurous geek living in San Francisco.

Pages

  • Supporter Wall
  • RSS
  • Random
  • Archive
  • Ask me anything
  • Mobile

Effector Theme by Carlo Franco.

Powered by Tumblr