Archive for the ‘Rails’ Category

h1

Rails: Render in a model

June 19, 2008

OK, this is really out there. Yes, the real answer is, “Don’t do it.”

Are you sure you aren’t going to be sad when the content of your database doesn’t change to keep up with your refactoring? Have you sufficiently explored other options and questioned the wisdom of what you are trying to do? Are you being asked to just to it anyway?

I found two approaches at http://davetroy.blogspot.com/2008/02/actsasrenderer-brings-output-to-models.html and http://blog.choonkeat.com/weblog/2006/08/rails-calling-r.html. I only tried the second of these, which didn’t like my use of polymorphic URLs and named routes in the template. I didn’t find the first approach before I had an interesting realization: if functional tests can do it then why can’t models?

def render_as_test(render_options, vars = {})
  controller = ApplicationController.new
  class << controller
    def set_instance_variables_and_render(render_options, vars)
      vars.keys.each do |k|
        instance_variable_set "@#{k}", vars[k]
      end
      render render_options
    end
  end
  require 'action_controller/test_process'
  request = ActionController::TestRequest.new
  response = ActionController::TestResponse.new
  controller.process(request, response,
    :set_instance_variables_and_render,
    render_options, vars).body
end

Now all my URLs generate. Use it responsibly. In fact, don’t use it at all. I am definitely not interested in pluginizing.

h1

FAILSAFE in my Rails production log

December 15, 2007

I’ll keep this one short and sweet. I was watching my production log and saw this:

/!\ FAILSAFE /!\ Sat Dec 15 19:48:06 -0800 2007
Status: 500 Internal Server Error
connect, accepted HTTP methods are delete, head, get, post, and put

I wondered what was going on, and after a check with the Apache log and Google, I found that the weird request was a CONNECT coming from freenode to make sure I didn’t have an abusable proxy or IIS. “What,” you say, “you’re running an IRC client on a Rails production server?” To that I say, “Yes.” Anyway, I stopped those requests from going to rails like this:

# First exclude some funky freenode port sniffing.
RewriteCond %{REQUEST_METHOD} !CONNECT
RewriteCond %{SERVER_NAME} teamdawg

That needs to be put before the line that finally redirects requests to your Mongrel cluster. (Of course you need to replace “teamdawg” in the second part with something that will match your own server name, or just leave the second part out.)

It occurs to me that maybe the “standard” Apache reverse proxy / rewriting config should have one additional condition before sending the request to the balancer. Most sample configs I have seen in blogs don’t have it:

RewriteCond %{REQUEST_METHOD} (GET|POST|PUT|HEAD|DELETE)

h1

Installing Rails without root

December 9, 2007

Some people are concerned with keeping their /usr hierarchy clean. Some people have no root access to the system that they are on. Some people don’t like using /usr/local. These people still want to install and run Ruby and Rails, but it will be best for them if it is done in a way that will keep gem working as it should.

I like to tell these people, “Oh it should be easy,” but I had to really make sure. There is one little trick, which is to make sure you really are using the right ruby when you install rubygems and then the right gem when you install Rails (and forever after).

As much for my own benefit as for anyone else’s, I put together a script so that I don’t forget. This should work on any UNIX that has the build dependencies for Ruby. That includes Linux of flavors Redhat, Ubuntu, Debian, and Slackware for all you Google fans out there. (The guy whose problems prompted me to put this together was using Ubuntu.) I like Debian but have found that Rails changes way too fast for Debian packages to be a viable way to install it. Gem is much better and standard in the Rails community, so you should do a local install of Ruby from source and then install rubygems using that version.

Without further ado, here’s the script that will save you time. You will need to edit it some unless you want /opt/rails. Personally I use /usr/local. It will also leave a build subdirectory in whatever location you use. It is your option to remove it after the fact. I would do so myself.

#!/bin/bash

INSTALL_ROOT=/opt/rails
cd $INSTALL_ROOT
mkdir build

cd $INSTALL_ROOT/build
wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.6-p111.tar.gz
tar zxvf ruby-1.8.6-p111.tar.gz
cd ruby-1.8.6-p111
./configure --prefix=$INSTALL_ROOT
make
make install

cd $INSTALL_ROOT/build
wget http://rubyforge.org/frs/download.php/28174/rubygems-0.9.5.tgz
tar zxvf rubygems-0.9.5.tgz

# This is crucial. rubygems setup really cares where ruby ran from, and if
# you have a system-wide ruby then it might get confused.
export PATH=$INSTALL_ROOT/bin:$PATH
# Of course you will also want to makde sure you include this wherever you
# normally set your PATH.

cd $INSTALL_ROOT/build/rubygems-0.9.5
ruby setup.rb
cd $INSTALL_ROOT

which ruby
which gem
gem install rake
gem install rails --source=http://gems.rubyonrails.org
gem environment
which rails
rails --version