RSpec helped me refactor my code.

Posted by Brian in Rails, Howto, Testing (June 10th, 2008)

I’ve been extremely against using RSpec. I always found it rather clunky, but it turns out that resources to really help a person learn how RSpec works are dificult to find. The examples you find out on the web are just poorly written or just contrived and impractical, or they’re so hopelessly overengineered that a newcomer would be overwhelemed.

This weekend I took it upon myself to really learn RSpec and so I started rewriting some of the tests for FeelMySkills. I started with the Account model which is used all over the app. The account_id is stored in the session and I use the Restful_authentication plugin to get access to a current_account method which returns the Account object. I want to be able to determine whether or not that account is an Admin, and I have an entry in the roles called “admin”. Nothing too special about all this, as many apps use a similar bit of functionality.

To make this easy on myself, I wrote a method called is_admin? which returns true if the admin role is associated with my account and nil if it’s not, and as we all know, nil evaluates to false, and anything other than nil or false evaluates to true.

When an account is created, I give them a role called “user”. Eventually, Pro users will have a different role, giving them access to more stuff in the system. Here’s what i have so far:

  class Account < ActiveRecord::Base
    has_and_belongs_to_many :roles
    after_create :add_user_role
 
    def is_admin?
      self.roles.detect{|r| r.name == "admin"}
    end
 
    def is_user?
       self.roles.detect{|r| r.name == "user"}
    end
    
    def add_user_role
          self.roles << Role.user
 
    end
 
  end

So, when I create a new user, I need to make sure that user gets the user role. My original Test/Unit test looked like this:

  def test_new_account_should_have_user_role
    account = Account.create(:login => "test",
                                       :password=>"test",
                                       :password_confirmation => "test",
                                       :email => "test@test.com")
    assert account.is_user?
  end

This test passes without any issues, so I know the code is right. Here’s what I tried with RSpec:

  describe "when creating an account" do
    fixtures :accounts, :roles
    before(:each) do
      @account = Account.create(:login => "test",
                                           :password=>"test",
                                           :password_confirmation => "test",
                                           :email => "test@test.com")
    end
 
    it "should have the user role" do
      @account.is_user?.should be_true
    end
 
  end

Imagine my surprise when I ran this spec and it failed! The reason why makes perfect sense when you start thinking about it.

First, RSpec’s matcher be_true evaluates the response of the method to be equal to true. The code for is_admin? actually returns an instance of Role, and not true like I asserted earlier. While that method evaluates to true, it does not equal true. So it’s interesting that the assert method has no probelm making the evaluation, but RSpec’s matchers are pickier.

A fair argument here would be “why does your is_admin? method return a Role and not just true or false?” The answer is that I’m lazy. I rely on Ruby to work for me, and until now, #detect has been a great ally. In my controller code, I can do

if current_user.is_admin...

and all is well, without the need to explicitly return true or false from the is_admin? or is_user? methods.

A better way

Looking at the spec again, I notice that I am in fact asking for the role in that specification. So I rewrite it to grab the User role from the fixtures and ensure they’re equal and it passes.

    it "should have the user role" do
      @account.is_user?.should equal roles(:user)
    end

But something about that bothers me. What am I really testing? I’m testing to make sure that the account is a regular user. Maybe I really do need a method that returns true or false.

It turns out that if you have a method in your model that ends with a question mark (?) and returns true or false, then RSpec can dynamically create a matcher for it. I rewrote the spec like this:

 
    it "should be a user" do
      @account.should be_a_user
    end
 

and then added this method to my model:

   # calls is_user? and returns true if is_user? returns a result, 
   # or false if it returns nil
   def user?
      self.is_user? != nil
   end

and I ended up with something I am much more comfortable with. I think future refactorings might change this around even more, but I found this exploration to be extremely enlightening.

P.S. For those that are interested, I actually have several roles in my system and I don’t manually declare these methods like is_admin? and is_user? by hand. I use this instead:

class Account < ActiveRecord::Base
 
  # ...
    
    # constant containing all of the role names
    # in the system
    Role::ROLE_NAMES.each do |r| 
 
    class_eval <<-CODE
      def is_#{r}?
        self.roles.detect{|role| role.name == "#{r}"}
      end
      
      def #{r}?
        self.is_#{r}? != nil
      end
      
    CODE
  end
 
  #... 
 
end

That way I don’t need to add new methods when I implement factchecker or pro or business roles later. Just thought I’d share that.

Working with Docbook on Windows

Posted by Brian in Howto, snacks, tips (March 3rd, 2008)

Setting up a toolchain for working with Docbook on Windows often requires setting things up using Cygwin. Many people are just simply not willing to do that. This tutorial will show you how to set up a native environment to work with Docbook, and show you how to make CHM and PDF files on Windows.

Thanks to http://supportweb.cs.bham.ac.uk/documentation/tutorials/docsystem/build/tutorials/docbooksys/segmentedhtml/ch03s03.html#DocBookSys-Chapter3-XML-Install-libxml-Windows for much of this information.

Getting the tools

The tools you need to work with Docbook XML and XSTL are all available on Windows. The first thing you need to do is visit http://www.zlatkovic.com/pub/libxml/ (new window) and grab the latest versions of

  • libxml2
  • libxslt
  • iconv

Download each and unzip the contents of the folder to c:\windows or another location on your path. For reference, these files are the ones you’re looking for:

iconv.exe
libexslt.dll
libxml2.dll
libxslt.dll
xmlcatalog.exe
xmllint.exe
xsltproc.exe

If you feel better about putting these in their own folder, that’s fine as long as you add the new folder to your path.

Getting the Stylesheets

In order to build a book, you need to have the XSLT stylesheets so you can transform your XML into a pretty-looking book with a table of contents and nicely formatted text.
Download the docbook-xml-ns files from sourceforge: http://sourceforge.net/project/showfiles.php?group_id=21935

Unpack to your c:\ drive and then rename the extracted folder to c:\docbook-xsl

Generating PDFs

In order to create a PDF, you have to first convert to the FO format and then use a Java library to convert the FO to a PDF. Apache FOP does this for you. You’ll need to have a JRE (Java Runtime) installed though. Visit http://java.sun.com/ for that.

Get FOP to build PDFs

Download FOP at http://www.uniontransit.com/apache/xmlgraphics/fop/fop-0.94-bin-jdk1.4.zip and unzip it to a temp location. Copy all .jar files in build/ and lib/ to your Java installation’s lib/ext folder. On my system it’s C:\Program Files\Java\jre1.5.0_11\lib\ext. Your system will differ depending on your installed version of Java.

Next, download OFFO-hyphenation from http://offo.sourceforge.net/index.html and grab the offo-hyphenation-fop-stable.zip file from the downloads page and put the jar files in the same folder as the FOP files.

Building your first book

Create a project folder called “my_book” and create a new file called “book.xml” in this folder.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
                 "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<book>
  
  <bookinfo>
  <title>My Simple Book</title>
  </bookinfo>

  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="chapter1.xml"/>
 
</book>

Then create a chapter for your book. Create the file chapter1.xml in your project folder with this content:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
                 "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
 
<chapter id="chapter1">
  <title>Introduction</title>
  <para>This is just a simple book.</para>
 
</chapter>
 

Notice that the chapter and book each have their own doctype, This is really important. Each chapter file needs to have this structure in order to work properly.

Generating HTML from the document

The easiest way to use Docbook is to export to HTML. Execute this command to create an HTML version of your book:

   xsltproc --xinclude --output book.html c:/docbook/xsl/html/docbook.xsl book.xml

Creating a makefile to build the PDF

The PDF creation process is similar to the HTML process but it does require two steps. You need to first convert the document to the FO file format. Then you use FOP to convert it to the PDF. We can automate this by using Ruby.

Create a Ruby file in your project folder called “make”. You’ll use this file to build the PDF of your book.

file = ARGV[0]
cmd1 = "xsltproc --xinclude --output #{file}.fo c:/docbook-xsl/fo/docbook.xsl #{file}.xml "
cmd2 = "java org.apache.fop.cli.Main -fo #{file}.fo -pdf #{file}.pdf"
 
puts "Building FO file"
`#{cmd1}`
 
puts "Building PDF"
`#{cmd2}`
 
puts "Cleaning up"
`del #{file}.fo`
 
puts "Done"
 

Now, build your book:

ruby make book

Creating a Help File

Generating a Windows HTML Help file (CHM) is pretty similar to the way you make a PDF. You first need to make the HLP file using xsltproc, and then you use a commandline tool to build the CHM.

Grab a copy of Microsoft’s HTML Help Workshop here and install it. Open a command prompt and copy the hhc file to the c:\windows directory so that the file is on your path.

copy "c:Program FilesHTML Help Workshop"hhc.exe c:windows

Next, we can use Ruby to make a file to create another build file. Create a file called “make_chm” in your project folder.

file = ARGV[0]
cmd1 = "xsltproc --xinclude c:/docbook-xsl/htmlhelp/htmlhelp.xsl #{file}.xml"
cmd2 = "hhc htmlhelp.hhp"
 
puts "Building HLP temporary files"
`#{cmd1}`
 
puts "Building CHM"
`#{cmd2}`
 
puts "Cleaning up"
`rename htmlhelp.chm #{file}.chm`
`del *.hhp`
`del *.hhc`
`del *.html`
 
puts "Done"
 

Summary

Docbook is a really great way to create books, tutorials, and documentation in a format that can be transformed into various other formats. It’s extremly easy to work with in Windows too!

Working with Docbook on the Mac

Posted by Brian in Howto, snacks, tips (March 3rd, 2008)

Docbook allows you to prepare documentation by using XML markup. You can create PDFs or HTML exports of your work, and it’s really nice for collaborating with others, as you can work in a code repository easily. In this article, you’ll learn how to build a PDF using Docbook XSLT.

Getting the Stylesheets

In order to build a book, you need to have the XSLT stylesheets so you can transform your XML into a pretty-looking book with a table of contents and nicely formatted text.
Download the docbook-xml-ns files from sourceforge: http://sourceforge.net/project/showfiles.php?group_id=21935

Unpack to your home directory and rename the folder to ~/docbook-xsl

Generating PDFs with Apache FOP

In order to create a PDF, you have to first convert to the FO format and then use a Java library to convert the FO to a PDF. Apache FOP does this for you.
Get FOP. - http://www.uniontransit.com/apache/xmlgraphics/fop/fop-0.94-bin-jdk1.4.zip

Unzip to temp location and copy all .jar files in the build/ and lib/ folders to ~/Library/Java/Extensions. Create that folder if it isn’t there for you already.

Finally, download OFFO from http://offo.sourceforge.net/index.html and grab the offo-hyphenation-fop-stable.zip file from the downloads page and put the jar files in ~/Library/Java/Extensions. This enables hyphenation support.

Building your first book

Create a project folder called “my_book” and create a new file called “book.xml” in this folder.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
                 "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<book>
  
  <bookinfo>
  <title>My Simple Book</title>
  </bookinfo>

  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="chapter1.xml"/>
 
</book>

Then creaet a chapter for your book. Create the file chapter1.xml in your project folder with this content:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
                 "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
 
<chapter id="chapter1">
  <title>Introduction</title>
  <para>This is just a simple book.</para>
 
</chapter>
 

Notice that the chapter and book each have their own doctype, This is really important. Each chapter file needs to have this structure in order to work properly.

Generating HTML from the document

The easiest way to use Docbook is to export to HTML. Execute this command to create an HTML version of your book:

   xsltproc --xinclude --output book.html c:/docbook/xsl/html/docbook.xsl book.xml

Creating a makefile to build a PDF

The PDF creation process is similar to the HTML process but it does require two steps. You need to first convert the document to the FO file format. Then you use FOP to convert it to the PDF. We can automate this by using Ruby.

Create a Ruby makefile in your project folder called “make”. You’ll use this file to build the PDF of your book.

file = ARGV[0]
cmd1 = "xsltproc --xinclude --output #{file}.fo ~/docbook-xsl/fo/docbook.xsl #{file}.xml "
cmd2 = "java org.apache.fop.cli.Main -fo #{file}.fo -pdf #{file}.pdf"
 
puts "Building FO file"
`#{cmd1}`
 
puts "Building PDF"
`#{cmd2}`
 
puts "Cleaning up"
`rm #{file}.fo`
 
puts "Done"
`open #{file}.pdf`
 

Now, build your book. In your project folder, type

ruby make book

Summary

Now you have a good introduction to how to work with the Docbook format. You may want to use a Textmate bundle to make editing the XML a little easier, but the syntax really isn’t that hard.

Up next… creating CHM files using Docbook on Windows.

Creating a new Edge Rails project in Windows (and *nix / OSX too!)

Posted by Brian in Rails, Howto, snacks (September 20th, 2007)

Rails has moved to Git so the scripts here no longer work! Visit the updated article instead.

I’ve been working with Edge Rails a lot lately, in preparation for a book I’m working on. Creating a new Rails project with Edge is a bit tricky—you need to have Edge Rails in your app’s vendor/rails folder before you can create your app. It usually involves the following steps:

  • Create the project’s folder
  • Create the vendor folder
  • Export Edge Rails to the vendor/rails folder
  • Create the Rails project using the vendor/rails/railities/bin/rails script instead of the normal one.

It seems that every time I want to do this, I have to go look at my notes and remember how. Not any more.

edge_rails

On Windows, paste this script into a new file and save the file to c:\ruby\bin\edge_rails.

@echo off
goto endofruby
#!/bin/ruby
 
require 'fileutils'
dir = ARGV[0]
dbtype = ARGV[1] rescue nil
FileUtils::mkdir(dir)
FileUtils::mkdir("#{dir}/vendor")
 
puts "Exporting EdgeRails from http://svn.rubyonrails.org/rails/trunk"
system "svn export http://svn.rubyonrails.org/rails/trunk #{dir}/vendor/rails"
 
system "ruby #{dir}/vendor/rails/railties/bin/rails #{dir} #{dbtype}"
 
__END__
:endofruby
"%~d0%~p0ruby" -x "%~f0" %*
 

Now, to create a new Edge Rails project, simply do

edge_rails my_app_name

or

edge_rails my_app_name --database=sqlite3

Right now, I’m not supporting any of the other command line options. If you want them, figure out how to do it. It’ll be a good exercise for you.

If you want to do this on a non-Windows system, just save the script below to a file called edge_rails, place the file on your path, and be sure to make it executable. You may need to change the first line of the script to correctly point to your ruby installation. Use

which ruby

to locate your Ruby path.

Here’s the script with all the Windows goodness removed.

#!/bin/ruby
 
require 'fileutils'
dir = ARGV[0]
dbtype = ARGV[1] rescue nil
FileUtils::mkdir(dir)
FileUtils::mkdir("#{dir}/vendor")
 
puts "Exporting EdgeRails from http://svn.rubyonrails.org/rails/trunk"
system "svn export http://svn.rubyonrails.org/rails/trunk #{dir}/vendor/rails"
 
system "ruby #{dir}/vendor/rails/railties/bin/rails #{dir} #{dbtype}"
 

Hope that makes someone else’s life easier too.

ActiveMerchant and Authorize.Net

Posted by Brian in Rails, Howto, snacks (June 4th, 2007)

I’ve been working on payment processing with AuthorizeNet, following the documentation for the ActiveMerchant plugin, as well as an excellent book on the subject. However, I find that both sources really lack the true implementation details, so I figured I’d write it up here.

Step 1: Get a developer account.

Go get a developer account from Authorize.Net . They’ll ask you some questions and you’ll get an account in about 24 hours.

Step 2. Get your API login and transaction IDs.

This is really not documented well. ActiveMerchant’s docs all say to create a transaction with

   gateway = AuthorizeNetGateway.new({
       :login => "user",
       :password=>"password})

However, you don’t use the username and password for AuthorizeNet. You use a separate set of credentials..

1. Log into the Merchant Interface
2. Select Settings from the Main Menu
3. Click on API Login ID and Transaction Key in the Security section
4. Type in the answer to the secret question configured on setup
5. Click Submit

Then copy the credentials… you’ll need them later.

Step 3. Install ActiveMerchant

VIsit www.activemerchant.org for installation instructions.

Step 4. Add a configuration file

I suggest creating a file called “config.yml” in your config/ folder. It comes in handy for a lot of things. I’ll store the API login and transaction key in this file.

production:
  auth_net_user: asdfga
  auth_net_pass: 1234412355
development:
  auth_net_user: asdfga
  auth_net_pass: 1234412355
test:
  auth_net_user: asdfga
  auth_net_pass: 1234412355

Remember, that’s a yml file, so make sure you don’t use tabs, and be sure to get your spacing right.

Step 5. Reservation model

My particular application is a reservation system. Regular readers of my blog know I’m really into test-driven development and this is where I really found the docs lacking. Even the book I read, which pushes for TDD the whole way through, never once touched on how to test the Authorize.Net gateway.

I like unit tests a lot, and so rather than use the controller to do the payment processing, I use the model. I want to find a reservation that’s already been created, set the credit card details, and call a method called “process” that will return true if it worked and false if it doesn’t. The process method will set the status to 1 if it was successful.

 
def test_should_process_order_successfully
 
    r = Reservation.find 1
    r.status = 0  # want to make sure this has a "pending" status.
    r.step = "checkout"    # need to set this - validations for cc info run only if this is set
    r.customer_ip = '192.168.1.155'
    r.card_type = "Visa"
    r.card_number="4779139500118580"
    r.card_verification_value = "410"
    r.card_expiration_month = "10"
    r.card_expiration_year = "2008"
    r.billing_city = "Springfield"
    r.billing_state = "NT"
    r.billing_zip =" 54703"
    r.billing_address ="123 Fake Street"
    assert r.process
    assert_equal(1, r.status)
end

With that set, I can add the following code to my model.

#  id                     :integer(11)   not null, primary key
#  customer_email         :string(255)   
#  confirmation_number    :string(255)   
#  payment_transaction_id :string(255)   
#  created_at             :datetime      
#  confirmed_at           :datetime      
#  processed_at           :datetime      
#  cancelled_at           :datetime      
#  phone_number           :string(255)   
#  billing_address        :string(255)   
#  billing_city           :string(255)   
#  billing_state          :string(255)   
#  billing_zip            :string(255)   
#  user_id                :integer(11)   
#  status                 :integer(11)   default(0)
#  passengers             :integer(11)   
#  total_cost             :integer(10)   
#
class Reservation < ActiveRecord::Base
include ActiveMerchant::Billing
belongs_to :user
validates_presence_of :billing_address,
    :billing_city,
    :billing_state,
    :billing_zip,
    :customer_ip,
    :card_type,
    :card_verification_value, :card_number, :card_expiration_month, :card_expiration_year, 
    :if=> Proc.new{|record| record.step == "checkout"}
 
  # cc fields as accessors so we don't store anything bad.
  attr_accessor :card_type, :card_expiration_month, :card_expiration_year, :card_number, :card_verification_value, :step
 
  # Process the payment
  def process
    self.processed_at = Time.now
    begin
      process_payment
    rescue => e
      logger.error("reservation #{self.confirmation_number} failed with error message #{e} ")
      self.error_message = "#{e}"
      self.status = 7  #failed
    end
    save!
    self.status == 1
        
  end
    
  protected
 
    def process_payment
     
     # this forces the system to use the testing server, which is what all dev accounts use.
     ActiveMerchant::Billing::Base.mode = :test if RAILS_ENV != "production"
 
     # read api key and  transaction # from config file
    c = YAML::load(File.open("#{RAILS_ROOT}/config/config.yml")) 
    user = c[RAILS_ENV]['auth_net_user']
    pass = c[RAILS_ENV]['auth_net_pass']
 
     creditcard = ActiveMerchant::Billing::CreditCard.new(
       :first_name => self.user.first_name,
       :last_name => self.user.last_name,
       :number=> self.card_number,
       :verification_value =>card_verification_value,
       :type => self.card_type,
       :month => self.card_expiration_month,
       :year => self.card_expiration_year
     )
     
     if creditcard.valid?
         options = {:name => self.user.full_name,
            :email => self.user.email,
            :phone => self.phone_number,
            :ip => self.customer_ip,
        :card_code => self.card_verification_value,
             :order_id => self.confirmation_number,
        :description => "Conference reservation",
             :billing_address=>{
               :address1 => self.billing_address,
               :city => self.billing_city,
               :state => self.billing_state,
               :zip => self.billing_zip,
               :country => "US"}
             }
          
         }
          
     
                      
              gateway = AuthorizeNetGateway.new({:login => user, :password=>pass})
           
           
           response = gateway.purchase(self.total_cost_in_cents, creditcard, options)
 
           if response.success?
             self.status = 1
             self.confirmed_at = Time.now
             self.error_message = nil
           else
             self.status = 7
             self.error_message = response.message
           end
        else
          self.status = 7
 
         self.error_message = "Invalid credit card."
       end
 

  end
end
 
  

Run the unit test - it should pass without issue.

Now, you just need to make your controller take in the fields from a form. That should be pretty simple. Set up your form fields like

  <% form_for "reservation", @reservation, :url=>{:action=>"process_order"} do |f| %>
     <p>Card number: <%= f.text_field "card_number" %></p>
     ... other fields
    <%=submit_tag "Check out" %>
  <% end %>
 
 def process_order
   # get  id from session - no passing ids around in the url for me! 
   @reservation = Reservation.find(session[:reservation_id]
 
   @reservation.customer_ip = request.remote_ip
   @reservation.step = "checkout"   # for validation, remember?
        if @reservation.update_attributes(params[:reservation])
          if @reservation.process
            redirect_to :action=>"finished"
          else
            @reservation.errors.add_to_base @reservation.error_message
            render :action=>"checkout"    
          end
        else
          render :action=>"checkout"  
        end
 end

Step 6. Hooking it all up

You’re using a developer account, so you won’t actually see the transaction on the AuthorizeNet side of things unless you turn testing mode off. This part took me forever to figure out.

1. Log into the Merchant Interface
2. Select Account from the Main Menu
3. Click Test Mode
4. Press Turn OFF test

Now, re-run your unit test and then view the Reports page in the Merchant Interface. You will see a new transaction.

Testing without the Internet

If you’re not really into testing online, you can still get your test to pass. You can use 0 or 1 for the credit card number…. 0 means an invalid card, and 1 means a successful card. This comes in handy when doing a functional test later on.

Taking it Live

Change your details to use your permanent account’s transaction key and id. Then remove the :test mode stuff by running your app in production mode. Put your real gateway in test mode and then run through your app, using some fake credit cards from AuthorizeNet.

Mastercard: 5424000000000015
Visa: 4007000000027
Discover: 6011000000000012
American Express: 370000000000002

Once you’re absolutely sure that everything’s working, turn off the test mode on the production account, and you’re good to go!

Wrapping up

I hope that helps some of you. I spent a lot of time looking over the documentation and various examples out there. The developer account works a bit differently than the real account, so that was a major stumbling block.

Feedback is welcome, as always!

MySQL gem on OSX

Posted by Brian in Rails, Howto, snacks (June 1st, 2007)

When I got the Macbook Pro in March, I immediately installed Ruby, Rails, Subversion, etc, using this tutorial from Hivelogic. http://hivelogic.com/narrative/articles/ruby-rails-mongrel-mysql-osx
They’ve done a good job of keeping it up to date, but one problem I noticed is that the MySQL gem instructions don’t work anymore. When the article was first written, it contained steps to remedy a minor installation problem. However, enough users reported that the problem no longer existed so it was removed.

Today, I encountered that problem again, and thought I’d share the solution. If you’re getting an error when you do

  asudo gem install mysql -- --with-mysql-dir=/usr/local/mysql

You’ll need to do the following to fix it.

First, look at where the gem says it’s left its files.

  Gem files will remain installed in /usr/local/lib/ruby/gems/1.8/gems/mysql-2.7 for inspection.

So in my case, I’ll do

  cd /usr/local/lib/ruby/gems/1.8/gems/mysql-2.7

Then I’ll edit the file ‘mysql.c’ in that folder and add one line at the top of the file:

  #define ulong unsigned long

Then, I just run

  sudo make
  sudo make install

The original fix for this comes from
http://jlaine.net/2006/10/3/installing-ruby-mysql-driver-on-os-x but the instructions there are a little backwards. I hope this solution will help others having a similar problem.

Deploying your Rails applications to production

Posted by Brian in Rails, Howto (May 10th, 2006)

It’s pretty safe to say that there is little to no support for deploying Rails applications on Windows. There are lots of people who would love to say goodbye to their .Net infrastructures but need to be able to prove that Ruby on Rails will work in their Microsoft-based environment.

After months of research, including three separate failed attempts to deploy applications on Microsoft’s IIS web server, I have developed several deployment solutions for Windows. Hopefully one of these strategies will work for you.

The articles are now online and can be found here.

 

Setting up a Rails Development Environment on Windows Using Eclipse

Posted by Brian in Rails, Howto (February 10th, 2006)

I’ve updated the popular article to include instructions for integrating the environment to handle the latest build of Eclipse (v3.1.2).

You can read the full article here. (Link opens in a new window.)