Postgres on Rails

Posted by Elliott Golden
header line
I have been wanting to give Heroku a try for a while. Their platform uses Postgres for data persistence. This was the motivation I needed to finally set up the Postrgres database on my Snow Leopard dev box.

The Postgres one-click installer makes things pretty simple, but I thought a record of the steps I took may prove useful in the future.

To begin, I grabbed the OS X version of the Postgres one-click installer for v.9.0.1-1. Once it downloaded and the .dmg mounted, I just ran the installer. It prompted me with a few options; I just stuck with the defaults and didn't opt for any of the post install apps that were offered.

Once everything was installed, I could open up the DB's GUI client (pgAdmin3) from /Library/PostgreSQL/9.0/pgAdmin3 and login as the default postgres user that the installer created. Depending on how you ran through the installer prompts, your postgres user may or may not have a password. Playing around with the GUI was proof that the DB was now setup. 

Rails requires a database adaptor Gem to be installed so that ActiveRecord can interface with Postgres. There are several available, but pg seems to be the library of choice. This gem and the included Postgres command line tools require access to the Postgres binary (The adaptor requires the binary so that native extensions can be built out during installation). To facilitate these requirements, my solution was to add the Postgres binary to the shell's $PATH variable. I ran which postgres to get the binary's location, then prepended the result to $PATH from within Bash's .profile. 

export PATH="/Library/PostgreSQL/9.0/bin:$PATH"
 

All that was left to do was set up a fresh Rails 3 app configured for Postgres integration.

rails new simpleapp -d postgresql
cd simpleapp
bundle install

After the app was created and the pg gem installed, the freshly generated database.yml needed editing. I used the default postgres user for username (another user can be created and used if desired) and set its password value accordingly. Finally, I fired off rake db:create:all to create the Postgres dbs for my new app, and I was ready to go.

The pgAdmin3 GUI is great, however if you care to use some of the command line tools the installer provides, you'll need to get down with their syntax and relation to Postgres centric users. Postgres and Rails – for MySQL people by Mike Williamson proved to be very useful in this department.
Comments

Love for Rails 3 Engines

Posted by Elliott Golden
header line
Until recently, I didn't really know what a Rails Engine was. Is an Engine something completely different than a plugin or Gem? Does it stand alone from the Rubygems ecosystem, or is it something that is integrally connected to it? All were questions of mine.

I struggled for a couple weeks setting up a smart development and test env for a CMS Gem I have been working on. Having little Gem/plugin dev experience didn't help either (especially when dealing with a full stack Gem such as a CMS). 

I had decided to go with a development structure that I had read of a couple times and that made sense to me. I created a new Rails app. In the app's vendor dir I built out the core structure of the Gem itself within a lib dir. Within lib was all my implementation code, Cucumber features and RSpec directories. To avoid repeatedly building (Jeweller: rake install) the Gem every time I ran a feature or spec, I had a ton of implementation and test dirs packed onto $LOAD_PATH. These stanky $LOAD_PATH additions and their subsequent requires were littered all about my Gem's root init file. It smelled even worse in Cucumber's env.rb and Rspec's spec_helper.rb. But since I was basically wiring the Gem into the host app instead of letting the host app simply bundle my Gem, that's what was needed. My last two posts reveal a bit more about the kludgery that was a foot.

Engines to the rescue, sort of... Learning about Engines ultimately put me on a better path regarding the structuring of the Gem, its test environment and the host app the enables it all. The new dev structure is as follows: On the root, I have my Gem's implementation within lib, sibling to that is spec_env. spec_env is a full-blown "dummy" Rails app that now contains the Cucumber and RSpec dirs. From the Gemfile of the dummy app I include the Gem via the convenient Bundler path argument like so:


#spec_env/Gemfile
gem 'my_gem', :path => '../../'


With these changes, everything just kinda fell into place. I felt like I was developing for Rails again. Among many other things, my features' and specs' rake tasks could now be found by default and the Gem's root init file was far leaner. These structural changes actually have little to do with Engines however. The Rails::Engine class can now come into play because the host app is now able to require the CMS Gem as Rails intended. 

An Engine is a class, you write it into your Gem or plugin. It doesn't stand alone from that context. Looking at its source reveals that by default the Rails::Engine class predominantly tasks itself with adding conventionally structured Rails directories to $LOAD_PATH. Among other things, it also provides an interface for hooking initializers into the load process and enables customization of the default Rails dir mappings within the Gem/plugin's context. What this means, is, that if your Gem's init file requires your engine.rb, your host app can now call controllers, models and routes etc.. from your Gem as if they were "native". Now you can forget explicit $LOAD_PATH additions for your Gem's Rails dirs. Rails::Engine handle this for you. For smaller Gem's Engines may not be necessary, but for larger libraries that are structured predominantly like a Rails app, it's a big win in simplicity.

A little code to show how easy an Engine is to implement should about wrap things up.


# lib/engine.rb
require "my_gem"
require "rails"

module MyGem
  class Engine < Rails::Engine
   # Desired config code here, if any.
  end
end

# lib/my_gem.rb
require 'engine' if defined?(Rails) 


That's it. If you want to configure the Engine beyond the default, spend a minute with railties/lib/rails/engine.rb to learn about the options. Beyond that, have a look at master. Looks like some nice things are already available for edge Rails. 3.1 should be a treat.

One final tip. If you have an app the will only have several concurrent users (I think a CMS fits into this category). You may find it convenient to serve static files directly from your Gem (The alternative is to copy them over to the host app's public dir). The code below does the trick. Thanks be to Jon Swope for this snippet rails-3-engines-plugins-and-static-assets .


# lib/engine.rb
require "my_gem"
require "rails"

module MyGem
  class Engine < Rails::Engine
    initializer "static assets" do |app|
      app.middleware.use ::ActionDispatch::Static, "#{root}/public"
    end
  end
end


More:
Gist by José Valim on related topics
Keith Schacht on Rails 3 engine and Gems

Comments
Posts 1-2 of 7


top All content in this site is copyright protected by either Simple Circle llc or its respective clients.   © 1999-2010
Validate XHTML