ANN: rails-undo-redo

Posted on Mon Feb 18 01:03:00 UTC 2008

To this day, very few web apps provide any undo/redo capabilities. This is really not such a good thing for usability. There are a few exceptions like gmail, but it does not go far enough to provide what every one is used on their desktop.

Ever since I read Assaf’s post on the subject, and left hungry for more, as Assaf only helps you on the UI side and leaves you all the heavy lifting, I have been thinking that there must be a way to make it a lot easier to implement undo/redo in a consistent manner, and in a way that is as easy as rails has gotten us used to.

After a few failed attempts, and building on the work of Brian Durand and his Acts As Revisionable and ActsAsTrashable plugins, that I’ve reused (and probably abused as well), I have come to realize a few (obvious?) things, namely that:

for Undo/Redo to work, it needs to

  • Work across all models
  • Capture the list of changed objects (UndoRecords)
  • Group these UndoRecords per User Action (UndoActions)

Then undo and redo are just a simple matter of replaying the UndoRecords in the right order.

All my previous attempts, and most other plugins I got inspiration from focused on one model, and even though you need this as a building block, for any real application, you need to be able to undo changes across multiple models (even beyond belongs_to, has_many type changes).

When you look at the types of changes to a model in details, you really have 3 types of changes Create, Update and Destroy (these are the C-U-D in CRUD, even if you are not doing REST), and undoing each one requires special handling, so this is also tracked and managed by UndoRecord.

To make a long story short, I’ve packaged all these ideas into a new Rails plugin: Rails Undo Redo (and very soon a gem as well, because this can help, and that’s also easy, or very easy), you can now easily transform any Rails Application using Active Record into a full fledged multi level undo/redo application like most desktop application.

For a full how-to, read the Rails Undo Redo project page, or try the Rails Undo Redo demo.

Posted in News, Rails  |  Tags  |  5 comments

git, submodules and Capistrano

Posted on Sun Feb 17 21:47:00 UTC 2008

If you use git submodules, as git-rails does, and want to use Capistano, you’ll need to patch patch Capistrano (lib/capistano/recipes/deploy/scm/git.rb) to make sure your submodules get included.

        def checkout(revision, destination)
          git      = command

          branch   = head

          fail "No branch specified, use for example 'set :branch, \"origin/master\"' in your deploy.rb" unless branch

          if depth = configuration[:git_shallow_clone]
            execute  = "#{git} clone --depth #{depth} #{configuration[:repository]} #{destination} && " 
          else
            execute  = "#{git} clone #{configuration[:repository]} #{destination} && " 
          end

          execute += "cd #{destination} && #{git} checkout -b deploy #{branch}" 

          if submodules = configuration[:git_enable_submodules]
            execute += " && git-submodule init &&" 
            execute += "git-submodule update" 
          end

          execute
        end
then define this in your deploy.rb:
set :git_enable_submodules,1

Or you can use the trunk version (post 2.1), which includes that support already.

Posted in Rails  |  Tags ,  |  1 comment

Debugging Specs

Posted on Sun Feb 17 00:11:00 UTC 2008

It is easy enough to debug specs on by one. For this you just run the ruby file that contains the spec with ruby-debug instead of ruby:

rdebug spec/rur_spec.rb

But when running via rake, you can’t do this. A simple solution is to add these lines in the spec file you want to debug (or in spec_helper.rb):

require_library_or_gem 'ruby-debug'
Debugger.start

And you are in business…

Posted in Rails, Testing  |  Tags ,  |  1 comment

git branches, merges and remotes

Posted on Thu Feb 07 00:21:00 UTC 2008

After releasing the first version of git-rails, Ron Damen created a clone of the repository and started improving on it. And I liked what he was doing, so now was the time to figure out how to get some of his changes back in to the master repo.

Here is the list of steps (and what they mean) to get his changes into the master branch on Gitorious.

First, define a remote branch to track his cloned repository
git remote add ron git://gitorious.org/git-rails/rons-mainline-clone.git
This adds this to .git/config:
[remote "ron"]
        url = git://gitorious.org/git-rails/rons-mainline-clone.git
        fetch = +refs/heads/*:refs/remotes/ron/*
Before doing the actual checkout, make sure you have nothing to commit in the current branch, then checkout a tracking branch:
git checkout -b ron/master
Now get the content from thre remote (remote “ron”, branch “master”)
git pull ron master
Once you’ve reached this point, it is easy to switch back and forth between branches
git checkout master
git checkout ron/master
Next, I created a temporary branch to merge what I like from Ron (not needed really)
git branch merge-ron
git status # does not switch branch!
git checkout merge-ron

This could be used as a shortcut: checkout -b merge-ron

Merge only specific changes (obtained using git log in ron/master branch)
git cherry-pick dc3de57a073e24eeb398e0cacbe52340258e861b
git cherry-pick 61579f92e1bfc95e582728011fcd21c79f08c3ae
Merge from merge-ron branch into local master
git checkout master
git merge merge-ron
And finally, push to origin
git push origin

From now on, the only thing needed to get more changes from Ron is to pull changes into ron/master, cherry-pick changes and merge back into master. Sweet!

Posted in Rails  |  Tags ,  |  0 comments

ANN: git-rails

Posted on Tue Feb 05 01:12:00 UTC 2008

Git is quickly becoming one of the best option for using a DVCS (Distributed Version Control System). Git main goal is to be quick (most everything you do is local), and has already been battle tested by the Linux Kernel dev team.

Recently, I’ve started experimenting with git after Rick switched Mephisto to git.

Even though things are pretty straightforward, some things are easier than others, especially when you have to take it all in in one shot.

So, over the weekend, I created git-rails, completed with a rubyforge project, an installable gem (gem install git-rails), and a git repository hosted by Gitorious

Currently, git-rails provides 3 functions:
  1. init repository (hookup to remote git repository, rails aware .gitignore)
  2. install plugin managed by git (using git submodules)
  3. update plugin

For now, I’m happy to use giston to manage svn hosted plugins, but I’m considering whether to add that functionality as well. We’ll see how things go.

To get started with git-rails, head over to the new git-rails project page.

Inspired by piston, and its newest sibling: giston/braid

Posted in News, Rails  |  Tags ,  |  3 comments

Git to svn (read-only)

Posted on Thu Jan 31 00:54:00 UTC 2008

As a follow up to last post about setting up git with gitorious

Here are the steps to mirror a git branch into svn.

First, I had to install git-svn
$ sudo port deactivate git-core
$ sudo port install git-core +svn
That did not got so well when trying to run git-svn:
error about Error.pm:
Can't locate Error.pm in @INC (@INC contains...
Something did not get copied correctly. Here’s the solution:
$ cp /opt/local/var/macports/software/git-core/1.5.2.4_1+doc/opt/local/lib/perl5/site_perl/5.8.8/Error.pm /opt/local/lib/perl5/site_perl/5.8.8/
Then create a place holder in svn so a location exist (it’s fine if it is empty):
$ svn mkdir svn+ssh://svn.nanorails.com/home/psq/svn/plugins/plugins/rur -m "creating rur"
Then add this to .git/config:
[svn-remote "nanorails"]
  url = svn+ssh://svn.nanorails.com/home/psq/svn/plugins/plugins/rur
  fetch = :refs/remotes/nanorails
nanorails will become the name of the branch Then fetch the svn (it won’t fetch anything, but this starts the process).
$ git svn fetch nanorails

$ git branch -a
* master
  nanorails
And the new branch is here :) Checkout that svn branch into a local branch:
$ git checkout -b local-svn nanorails
Switched to a new branch "local-svn" 

$ git branch -a
* local-svn
  master
  nanorails

Now the fun part.

Using rebase will forward the local commits to the updated upstream head
$ git-svn rebase
Current branch local-svn is up to date.
Get all the goodies from the master branch
$ git merge master
Merge made by recursive.
 .gitignore                            |    1 +
 MIT-LICENSE                           |   21 ++
 README                                |   48 +++++
 Rakefile                              |   20 ++
 init.rb                               |    3 +
 lib/undo_action.rb                    |   24 +++
 lib/undo_manager.rb                   |   89 ++++++++
 lib/undo_record.rb                    |  224 ++++++++++++++++++++
 lib/undoable.rb                       |   40 ++++
 lib/undoable_helper.rb                |   23 ++
 migrations/001_create_undo_records.rb |   32 +++
 spec/rur_spec.rb                      |  132 ++++++++++++
 spec/spec_helper.rb                   |   26 +++
 spec/undo_action_spec.rb              |   46 ++++
 spec/undo_manager_spec.rb             |   10 +
 spec/undo_record_spec.rb              |  368 +++++++++++++++++++++++++++++++++
 spec/undoable_spec.rb                 |   46 ++++
 17 files changed, 1153 insertions(+), 0 deletions(-)
 create mode 100644 .gitignore
 create mode 100644 MIT-LICENSE
 create mode 100644 README
 create mode 100644 Rakefile
 create mode 100644 init.rb
 create mode 100644 lib/undo_action.rb
 create mode 100644 lib/undo_manager.rb
 create mode 100644 lib/undo_record.rb
 create mode 100644 lib/undoable.rb
 create mode 100644 lib/undoable_helper.rb
 create mode 100644 migrations/001_create_undo_records.rb
 create mode 100644 spec/rur_spec.rb
 create mode 100644 spec/spec_helper.rb
 create mode 100644 spec/undo_action_spec.rb
 create mode 100644 spec/undo_manager_spec.rb
 create mode 100644 spec/undo_record_spec.rb
 create mode 100644 spec/undoable_spec.rb
And finally, send the changes to svn
$ git-svn dcommit
Committing to svn+ssh://svn.nanorails.com/home/psq/svn/plugins/plugins/rur ...
    A    .gitignore
    A    MIT-LICENSE
    A    README
    A    Rakefile
    A    init.rb
    A    lib/undo_action.rb
    A    lib/undo_manager.rb
    A    lib/undo_record.rb
    A    lib/undoable.rb
    A    lib/undoable_helper.rb
    A    migrations/001_create_undo_records.rb
    A    spec/rur_spec.rb
    A    spec/spec_helper.rb
    A    spec/undo_action_spec.rb
    A    spec/undo_manager_spec.rb
    A    spec/undo_record_spec.rb
    A    spec/undoable_spec.rb
Committed r66
    A    Rakefile
    A    .gitignore
    A    init.rb
    A    lib/undo_manager.rb
    A    lib/undo_action.rb
    A    lib/undo_record.rb
    A    lib/undoable_helper.rb
    A    lib/undoable.rb
    A    MIT-LICENSE
    A    spec/undo_record_spec.rb
    A    spec/rur_spec.rb
    A    spec/undoable_spec.rb
    A    spec/spec_helper.rb
    A    spec/undo_manager_spec.rb
    A    spec/undo_action_spec.rb
    A    migrations/001_create_undo_records.rb
    A    README
r66 = 98602d45907206a281f597f87445397f069cdc1d (nanorails)
No changes between current HEAD and refs/remotes/nanorails
Resetting to the latest refs/remotes/nanorails

And then there was much rejoicing across the land :)

Now, to update svn, the only things to do, assuming master is where the latest is, are:
$ git checkout local-svn
$ git merge master
$ git-svn dcommit

This setup could also bring changes back from svn, which git-svn is capable of doing, but I’ll be quite happy with the read-only part.

Resources:
  1. using-git-with-svn
  2. git-svn
  3. git tutorial
  4. gitorious

Update: in fact, it looks like “git-svn dcommit” from the master branch, without merging to the “local-svn” branch first, also commits to svn.

Posted in  |  Tags  |  0 comments

Getting started with Git

Posted on Wed Jan 30 22:07:00 UTC 2008

I’ve been using git for a bit now since Rick switched Mephisto to git, but I’ve only been using an existing repository, and not using the full thing just yet.

So as I’m starting a new project, I have been taking a few notes to get started with a new project (I’m also testing gitorious.org in the process, a free git repository provided by Johan Sørensen)

First, I created a .gitignore file to filter out anything unwanted. On a Mac, for example, it is alway a good idea to add:
.DS_Store
Then to create the initial repository and commit locally
$ cd vendor/plugin/rur
$ git init
Initialized empty Git repository in .git/
$ git add .
$ git commit
Now the big push:
$ git push git@gitorious.org:rur/mainline.git
The authenticity of host 'gitorious.org (67.207.146.32)' can't be established.
RSA key fingerprint is 1d:0f:80:3b:95:c5:a8:08:85:f6:fc:0a:b2:54:52:bb.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'gitorious.org,67.207.146.32' (RSA) to the list of known hosts.
No refs in common and none specified; doing nothing.
fatal: The remote end hung up unexpectedly
Whoops! Not quite what I expected. Let’s try to pull first then?
$ git clone git@gitorious.org:rur/mainline.git
Initialized empty Git repository in /Users/psq/tmp/mainline/.git/
fatal: no matching remote head
fetch-pack from 'git@gitorious.org:rur/mainline.git' failed.
Hmm, not quite either. Looking at the gitorious “faq”http://gitorious.org/about/faq provides the answer :) Add the remote and master definitions to .git/config:
[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
[remote "origin"]
       url = git@gitorious.org:rur/mainline.git
       fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
       remote = origin
       merge = refs/heads/master
(Change to match your project). Then, try to push again:
$ git push origin master
updating 'refs/heads/master'
  from 0000000000000000000000000000000000000000
  to   74bbfc838d4984ee81d5560daee3511fe044d36e
Generating pack...
Done counting 22 objects.
Deltifying 22 objects...
 100% (22/22) done
Writing 22 objects...
 100% (22/22) done
Total 22 (delta 0), reused 0 (delta 0)
refs/heads/master: 0000000000000000000000000000000000000000 -> 74bbfc838d4984ee81d5560daee3511fe044d36e

Finally! And checking the gitorious site, the code has been pushed!

(You can get your push and pull urls from the mainline page.

To get started locally with an existing project, just use the pull url
git clone git://gitorious.org/rur/mainline.git

Now, if I can figure out the best way to get an svn mirror from gitorious, I’ll be in business!

Source (and a good tutorial): A tutorial introduction to git (for version 1.5.1 or newer)

A final note: the project referenced here is not quite fully baked, so use at your own risk…

Posted in  |  Tags  |  1 comment

MacHeist

Posted on Sun Jan 20 21:52:00 UTC 2008

If you have a Mac, or want one, then you should surely take a look at the $49 bundle MacHeist has put together. An amazing value, with lots of cool apps. Plus 25% of your purchase goes to charities. It’s like getting 1password, CoverSutra (truly cool), and Snapz Pro for half the price, and getting all other 11 Mac Applications for free. Check it out (via Obie Fernandez)

Update: I had the link wrong (using https), and you could not see the apps. Fixed. Also forgot to mention you also get CSSEdit. And possibly VectorDesigner if they reach the $300,000 donation level.

Posted in Mac, News  |  Tags  |  2 comments

Ruby-debug quick tips: init file and -n option

Posted on Sat Jan 12 00:28:00 UTC 2008

I use ruby-debug quite a bit (too much? perhaps). And every time I start it, I find myself setting a few options (always the same ones), and it finally got to the point where I thought there had to be a better way. And there was! (Thank you, Kent)

The solution is even documented in some recent release notes:

Create a .rdebugrc in your home directory (it also looks for one in the current directory first):

set autolist
set autoeval
set autoreload
set forcestep

And voila! Each time you start rdebug, it executes this script.

An other good tip: run with -n to avoid stopping on the first instruction, now that you don’t need to run all these commands.

Update: with version 0.10, -n does not seem to be recognized, but —no-stop still works.

Posted in Rails  |  Tags  |  5 comments

Ruby Gem 1.0 is out

Posted on Thu Dec 20 01:42:00 UTC 2007

RubyGem 1.0 is out.

Yeah!

Which means that if you see

undefined method `require_gem' for main:Object (NoMethodError)

You’ll need to replace require_gem by just gem.

For example, unless you have the very latest version of ruby-debug (0.9.3), you’ll see the above error. In that case, though, updating your gem is simpler.

Posted in News, Quid Pro Quo  |  Tags  |  11 comments

Upgrade to Windows XP?

Posted on Sat Dec 15 00:48:00 UTC 2007

This was just too good to pass up! Vista has been getting a pretty bad rap anywhere you look (well, at least anywhere I look, and from second hand experience helping people with their Vista machine), so here’s your chance to finally Upgrade to XP

Ok, you can stop laughing now.

And for a real upgrade

(via Reginald)

Posted in News  |  Tags  |  2 comments

Removing the quarantine attribute on your application

Posted on Tue Dec 11 22:33:00 UTC 2007

With Apple latest OS, Leopard (Which I recommend highly), comes an interesting new feature (well, at least it is cute for a while, but it can get to you after a while). For annoying, try Vista

When you try to run an application you downloaded and get this message every time you try to start an application

"..." is an application which was downloaded from the internet...

There is an easy solution.

Check first tha it has the “com.apple.quarantine” Attribute.

xattr -l BetterZip.app
which may give you something like: com.apple.quarantine: 0000;4726d129;Safari;5FF2A3CB-B74C-405A-BF92-AD14858A6F5A|com.apple.Safari

If it does, remove it using:

sudo xattr -d com.apple.quarantine BetterZip.app

Posted in Mac  |  Tags  |  0 comments

Dreamhost codes

Posted on Tue Dec 04 23:37:00 UTC 2007

I’ve had my ups and downs with Dreamhost and I’m now running nano RAILS on a kick ass VPS with gentoo.

But for a starter ruby site (nano RAILS was hosted there for over a year!), it is hard to beat their price, and they do run quite nicely with fcgi. If you want to run multiple apps, using mongrel, then sure it is not for you.

I’m also running lots of wordpress blogs (Home Recipes and Why not create a Side Business) and I’m happy with the no hassle way to get them setup and how smoothly they run.

Any way, to make a long story short, Dreamhost has finally decided to update the way you create codes for their Coupons.

So if you want to get started with a pretty good host, and need a new domain name, you can get that domain for free for the life of your account by using the code NANODOMAIN (plus you get the max $50 off, which is a nice chunk of change).

Or if you already have a domain, but want a unique IP, you can use NANOIP (and you also get $50 off).

Or you can take advantage of that last week to get $97 off with NANO97.

Enjoy!

Posted in News  |  Tags ,  |  1 comment

Upgrading a MacBook Pro Hard Disk

Posted on Mon Aug 27 23:35:00 UTC 2007

Just last week I inherited a not so old 17” MacBook Pro. Sweet!

It just needed a little TLC, more memory and a bigger and faster disk (7200 rpm, yummy, but not so good for your pocket book).

Changing the memory is surprisingly easy on the later models. Just remove the battery, remove a few screws below the battery (small phillips screw driver) and you are done.

Changing the hard disk is a different story. A few google searches did not turn up the expected solution, but gave me enough ideas to be bold enough to get to it. In fact, it is really simple to open the case. (Before you do this, know that this will void your warranty if it is still current, so don’t say you have not been warned).

Unscrew all visible phillips screws (including the one below the cover from the memory, and then you are left with just a couple of torx screws. Then flip back the machine, open the screen and lift the keyboard/mouse pad. After that, gently unplug the single connection and the disk is within reach (just 2 more screws).

Unplug the disk, plug in the new one, and retrace your steps back.

If you can, though, avoid working above thick carpet, this will save you tons of embarrassing time looking for one of these tiny screws ;)

That was the easy part. Because I just did not have the system disks handy. I had a few other ones, though. A newer Macbook Pro set, and even the latest stainless steel iMac ones. But none of these would accept to install a new system on that brand new disk :(

Fear not, there is a simple solution, that will kill 2 birds with one stone (since I also needed to copy all the existing data from the old disk).

I bought (third trip to Fry’s that day) an external USB 2.5” laptop disk enclosure (this will set you back $15 or more), plugged in the old disk and followed these simple steps:

* plug the external disk * boot the mac with any system CD (Mac OS X) * go to the next step till the Utilities menu is available * use Disk Utilities to format/partition the new disk * go back and start “Terminal” to do the copy * once the terminal app has started, figure out the Volume names from /Volumes
ls /Volumes
* then run:
asr --source /Volumes/[SOURCE] --target /Volumes/[DEST] --verbose

asr will even go so far as to show you a progress bar that shows you how far it got. And some time later, you’ll have an exact, bootable, copy of your old disk.

Posted in Mac  |  Tags , , ,  |  2 comments

My Ruby on Rails Gentoo Setup

Posted on Mon Aug 20 22:24:00 UTC 2007

I had been hearing about Gentoo for a long time, and finally discovered it in depth about 6 months ago. Gentoo is really a different beast as Linuxes go. You get to build everything from sources. No binaries. That’s right. That means that you get to build everything with compatible flags, get to remove a lot of the unnecessary bloat (Do I hear X windows for example?). It also means that the initial setup could take you several days if your machine is not so powerful. Suffice it to say, I really, really like the approach and that is now what I’m using to run this blog.

Of course, if I need a server setup in a hurry, I’ll still go for a Debian or Ubuntu. But if I want a very fined tune system, Gentoo is it.

Of course, there is an ebuild for rails (ebuild is gentoo-speak for describing a package your can grab and build), but it did bring a lot more that what I cared for, so here’s the step by step instructions for getting Rails+Mongrel+nginx going on Gentoo.

This assumes that you are starting from a Gentoo 2006.1 stage 3 without much else.

A word of warning

Even though I’ve used these notes to successfully setup 3 machines (both on x86 and amd64), your experience may still be different, or you may need slightly different options or settings as the packages are bound to evolve, or I’ve made some assumptions that do not apply in your case, or something was obvious to me that should not have been, or, perish the thought, I just plain forgot something. If that happens, remember, Google is your friend, or don’t be shy, ask a question here, someone might know the answer.

So with that out the way, let’s get started.

Preamble

auto start ssh:
rc-update add sshd default
update portage tree
emerge --sync
emerge portage
emerge -av --update --deep world
At this point, you are going to have a lot of configuration files that out of date. Since we are doing a new setup, we just want to silence the warnings and making sure we use the latest version. So to find each file:
find /etc -iname '._cfg????_*'
But do not overwrite inittab if it is only putting back more terminal login than you need. Now it is time to add a few very useful tools like sudo, stuff to help you figure out what’s installed, and to find things (namely sudo, gentoolkit and sys-apps/slocate)
emerge -av app-admin/sudo app-portage/gentoolkit sys-apps/slocate
Now it is time to create your user. And set its password.
useradd user
passwd user

Add user to /etc/sudoers with ALL

Add vim (or whatever else you fancy)
emerge -av vim
Change default EDITOR
vi /etc/rc.conf
There, comment out /bin/nano, and uncomment /bin/vim Install subversion
emerge -av subversion
Even though not strictly necessary for Rails, a few network utilities always come in handy (traceroute, dig, nslookup):
emerge -av traceroute bind-tools
If you want to send/receive emails:
emerge -av mail-client/mailx
emerge --unmerge mail-mta/ssmtp
emerge -av syslog-ng mail-mta/exim
rc-update add exim default

There are lots of options to do SMTP, but I find exim4 the quickest and simplest to setup:

create /etc/exim/exim.conf from /etc/exim/exim.conf.dist

To lockdown mail to localhost (you just want your Rails app to send emails), add this exim.conf:

local_interfaces = 127.0.0.1
And to allow non users to send mails (comment out this line)
##require verify        = sender
And finally, start your mail server:
/etc/init.d/exim start

Rails Setup

My preferred database remains MySQL. I know, some people prefer PostgrSQL.

emerge -av dev-db/mysql
rc-update add mysql default
Then, to configure MySQL and create a first database, first you need to figure out which version you just installed. If you were not paying attention as the logs were flying by (I know I wasn’t), use
equery list mysql
And then
emerge --config =dev-db/mysql-5.0.26-r2
To get rubygems 0.9.x, you need to unmask it. For that, add a new line to /etc/portage/package.keywords with:
dev-ruby/rubygems ~amd64

Replace with ~x86 if you are not on an AMD chip, then run:

emerge -av dev-lang/ruby dev-ruby/mysql-ruby dev-ruby/rubygems  dev-ruby/ruby-termios
For any kind of image manipulation (resizing and such), install Image Magick. First, it it does not already exist create /etc/portage/package.use
dev-ruby/rmagick lcms gif imagemagick jbig jpeg jpeg2k pdf png svg tiff truetype unicode wmf xml xpm pcre
media-gfx/imagemagick lcms gif imagemagick jbig jpeg jpeg2k pdf png svg tiff truetype unicode wmf xml xpm pcre
emerge -av media-gfx/imagemagick dev-ruby/rmagick
The above line represents the options for that ebuild. Time to get the latest nginx
  1. add a new line to /etc/portage/package.keywords with (Again, on Intel, use ~x86)
"www-servers/nginx ~amd64

Then run emerge again:

emerge -av www-servers/nginx

Ok, now time to install what we actually wanted to install, Ruby on Rails and a few useful gems:

gem install -y rails rake capistrano daemons gem_plugin mongrel mongrel_cluster rmagick BlueCloth RedCloth ruby-debug termios ruby-openid ruby-yadis
Start mysql, create a database for rails test app
/etc/init.d/mysql start
mysqladmin -u root -p create test1_development
mysqladmin -u root -p create test1_production

And finally, install a rails app (we’ll use beast as it is pretty simple to install)

svn checkout http://svn.techno-weenie.net/projects/beast/trunk beast
cd beast/
rake rails:freeze:edge
#create config/database.yml from config/database.example.yml
rake db:schema:load RAILS_ENV=production
./script/server -e production

Test that everything’s fine fine by pointing your browser to port 3000.

Now, let’s configure mongrel (We are almost there, I promise).
cd [app]
sudo useradd -n mongrel
sudo chown -R mongrel:mongrel [app]
mongrel_rails cluster::configure -e production -p 8000 -N 3 -c [app] -a 127.0.0.1 --user mongrel --group mongrel

Later, a few useful commands to use

#start cluster
mongrel_rails cluster::start

#restart cluster
mongrel_rails cluster::restart

#stop cluster
mongrel_rails cluster::stop

To setup nginx, edit /etc/nginx/nginx.conf to match your setup

To setup mongrel_cluster for autostart
mkdir /etc/mongrel_cluster
ln -s [app]/config/mongrel_cluster.yml /etc/mongrel_cluster/[app].yml
#copy from wherever the gem is installed (use locate to figure out the location)
ln -s /usr/lib64/ruby/gems/1.8/gems/mongrel_cluster-0.2.1/resources/mongrel_cluster /etc/init.d/mongrel_cluster
chmod +x /etc/init.d/mongrel_cluster
Add nginx and mongrel_cluster to startup
rc-update add nginx default
rc-update add mongrel_cluster default

For smooth reboot, you may need to delete the pid files Apply this patch (from http://textsnippets.com)

create file “mongrel_cluster.patch” with:

--- bin/mongrel_rails-orig      2007-05-16 14:41:51.000000000 -0400
+++ bin/mongrel_rails   2007-05-16 14:42:50.000000000 -0400
@@ -83,9 +83,17 @@
       config = Mongrel::Rails::RailsConfigurator.new(settings) do
         if defaults[:daemon]
           if File.exist? defaults[:pid_file]
-            log "!!! PID file #{defaults[:pid_file]} already exists.  Mongrel could be running already.  Check your #{defaults[:log_file]} for errors." 
-            log "!!! Exiting with error.  You must stop mongrel and clear the .pid before I'll attempt a start." 
-            exit 1
+            # mongrels that crash can leave stale PID files behind, and these
+            # should not stop mongrel from being restarted by monitors…
+            pid = File.new(defaults[:pid_file]).readline
+            unless `ps -ef | grep #{pid} | grep -v grep`.length > 0
+            # use "ps ax" for freebsd 
+                log "!!! PID file #{defaults[:pid_file]} exists, but is stale, and will be deleted so that this mongrel can run." 
+                File.delete(defaults[:pid_file])
+            else
+                log "!!! PID file #{defaults[:pid_file]} already exists and the process id referred to in it is running.  This mongrel is probably already running.  #{defaults[:log_file]} for errors.  EXITING." 
+                exit 1
+            end

           end

                 daemonize

then apply the patch

patch -p0 /usr/lib64/ruby/gems/1.8/gems/mongrel-1.0.1/bin/mongrel_rails < mongrel_cluster.patch

And there you have it. A nice, humming Ruby on Rails+Mongrel+nginx on Gentoo.

Posted in Linux, Rails  |  Tags , ,  |  4 comments