<div class="test" /> 0

Posted by win
on Monday, August 25
Never use bq.
It will not validate and does some very weird things!

Dynamic attribute-based finders AND creators 0

Posted by win
on Tuesday, August 05

I’m not sure if its a common Rails idiom but I recently discovered the dynamic attribute-based finders methods on ActiveRecord.

Though I already knew about the common ActiveRecord#find_by_(column)and(another_column) I did not know about the ActiveRecord#find_or_create_by_(column)

With this dynamic attribute-based finder/creator you can create a new record or receive an existing record matching the passed conditions.

Example:

 User.find_or_create_by_name_and_email_and_title('Bob','bob@domonkeydo.com','Super Guy')

Similarly, you can also use ActiveRecord#find_or_initialize_by_(column) to find or create an unsaved ActiveRecord object.

Check out the ActiveRecord api here

Sweet.

When to use observe_form versus observe_field 0

Posted by win
on Tuesday, August 05

I recently needed to update a drop-down field with values taken from a set of check boxes.

I first tried using the observe_field helper. I decided against using observe_field for my final solution since it did not easily allow me to send more than one value in the params when a check box was clicked.

In thinking about it more I realized it made more practical sense to use a single observe_form.

Since:
  1. It allows additional (especially hidden fields) parameters to be passed to the action
  2. Uses a single Observer instead of multiple observers per check box input

<%= observe_form “form_id_here”, :update => ‘drop-down id_here_’, :url => {:controller => ‘javascripts’, :action => ‘dynamic_drop_down’ } %>

Ode to The Pragmatic Programmers' Guide Part 1 0

Posted by win
on Wednesday, July 30

Though I graduated with a Computer Science degree and started my career programming Java for a stint, I feel I didn’t really start coding the way I wanted until I read a book that most Rubyists regard as the book that started it all. The “pickaxe” it is now called has been a staple at my work desk for these past months and in honor of the help it has given me I’ve decided to try and condense the more than 400 pages (the rest of the pages are reference) of programming prose to no more than 26 blog posts.

Why am I doing this? Am I bored? Is this just so I have more to write on m blog? Will it even be useful?

Not sure. Probably. Sadly, maybe. Who knows.

Though I will still try and throw in unrelated posts (and maybe some additions to the summaries ) of my more original thoughts and ideas, I will begin with Chapter 1 – though elementary I’d like to be comprehensive at least.

And here we go…

Programming Ruby – The Pragmatic Programmers’ Guide

Chapter 1 Summary

Installing Ruby

Nowadays Ruby comes preinstalled on many Linux distros and Mac OS X systems. If Ruby is not installed or you’d like to have it handled through Macports check out my earlier blog post. To find out if you need to upgrade ruby use the

ruby -v

to find the version of Ruby you’re running.

Binary Distributions

Binary distros work fine but you are limited to the versions that are available. Below you can find references for RPM-based systems, Debian dpkg-based systems and MacPorts (courtesy of my own link).

  • RPM – search http://www.rpmfind.net entering “ruby” as a search term
  • Debian – use apt-cache to search for ruby packages

apt-cache search ruby

then use

apt-get install <rubyandversion>

to install it.

Building Ruby from Source

Using this method you take on all the responsibility for managing the build and installation process. If you’d dare follow the steps below:

  1. Go to http://www.ruby-lang.org
    1. Then choose from the next three options
      1. Click the Download Ruby link and then the Ruby 1.8.7-p22 link – the latest stable version of Ruby
      2. Click the stable snapshot link – a tar’ed and gzip’ed stable version.
      3. Click the Nightly Snapshot link – the edgiest of the edge version (beware may contain issues).

Once downloaded untar the files using the following command

 tar xzf <file>.tar.gz

This will install the Ruby source tree in the ruby/ subdirectory. Find the README file in that directory for the installation procedure.

Running Ruby

Ruby can be run in two ways:

  1. Interactively using

ruby 

at a prompt followed by ruby commands or the more preferred method

irb

which allows you to see what you’re typing better and also allows for the loading of the second type (Ruby programs) using

 load "src/examples/ruby_file.rb" 

after typing ‘irb’ to start the Interactive Ruby.

2. In Ruby Programs

Obviously, Ruby can be run from a file by running the Ruby interpreter with the script name as an argument

ruby example.rb

The Unix shebang notation placed on the first line of an executable file will also work.

#! /usr/local/bin/ruby -w

Note: to find what exactly to put after the shebang (#!) do a

which ruby

to find where ruby is located in your system and copy and paste that after the shebang.

Ruby Documentation: RDoc and ri

The Ruby libraries are documented internally using a system called RDoc. ri is a command-line tool used to view documentation created in the RDoc system.

To find the documentation for a particular class use

 ri <Classname>

To look at a single method for a class use

 ri <Classname>.<method>

For more help using the ri tool use

ri --help

Done.

Request#referer not a defined method in ActionController:TestRequest 0

Posted by win
on Tuesday, July 29

Working on Rails 1.2.3/Ruby 1.8.5 (yes, i know) I recently found out that the referer method is not defined on the ActionController::TestRequest class so will throw an undefined method error during test. To try and solve this I changed

request.referer 

to:

request.referer if defined? request.referer

which DID NOT WORK. Apparently, ‘referer’ is not defined on the normal controller request object as well. I’m guessing the result (which does work) comes from the magical method_missing phenomenon. (Anyone please correct if I’m wrong.) I plan on doing further research later though it may be moot as well will soon be moving to Rails 2/Ruby 1.8.6 – hopefully its not a problem there.

Anyway, to work around it I rewrote

request.referer if defined? request.referer 

to:

request.referer if defined?(request.referr.class)

Hmmmm…

Google maps now with location-based photos...

Posted by win
on Tuesday, June 03

Not sure if this is old news but I just noticed location-based photos (and a few videos) set inside google maps. Right now it looks like photos are only being taken from Panoramio.com and videos from Youtube.com.

A quick google of Panoramio.com brings this up:

“Panoramio is a geographical photo collab site that uses Google Earth to link photos to the exact location from which they were taken.”

A quick peruse of the photos currently looks promising. I haven’t heard of panoramio.com until now but it looks like a great addition to the google mash-up family.

Fix the "Cannot unmount disk" error when erasing Time Machine backup

Posted by win
on Thursday, April 17

If you have tried to erase the contents of your Time machine backup (external drive) and received the “Cannot unmount disk” error – no fear. I too have received the error and resolved it by plugging the external drive into a different mac and used the disk utility to erase it. Don’t forget to choose the Max OS Extended (Journaled) option for Time Machine.

How to parse a response soap message using soap4r

Posted by win
on Wednesday, April 16

Soap4r is a very helpful utility. Using ‘wsdl2ruby’ you can generate local methods to invoke web service methods via SOAP.

wsdl2ruby.rb --wsdl path_to_your_wsdl --type client | server

The only problem I had with soap4r during my implementation was the difficulty I had with manually parsing the soap response from the web service. Though the web service methods were generated perfectly, I needed additional information from the soap response (the soap header information, not to be confused with the http header info) that was not provided by the wsdl, thus left out of the wsdl2ruby code generation.

SOAP4r uses a private send_post method in the HTTPStreamHandler class of the SOAP module. In the send_post method an net/http instance uses the post method to post the message as a string to the whichever url was sent in the SOAP call. The post method returns the response from the remote server. However, HTTPStreamHandler does not make this available to you. To change all you need to do is make the response variable an instance variable.

The new res instance variable will return an HTTP::Message class. You will then need to access the body instance variable in the Body class. However, this will also need an accessor method monkey-patched through HTTP::Message::Body. (Also included below)

Monkey-patch the private send_post method in SOAP::HTTPStreamHandler to change the res local variable to an instance variable

module SOAP
  class HTTPStreamHandler
  attr_accessor :res
  private
    def send_post(url, conn_data, charset)
        conn_data.send_contenttype ||= StreamHandler.create_media_type(charset)
        if @wiredump_file_base
          filename = @wiredump_file_base + '_request.xml'
          f = File.open(filename, "w")
          f << conn_data.send_string
          f.close
        end

        extheader = {}
        extheader['Content-Type'] = conn_data.send_contenttype
        extheader['SOAPAction'] = "\"#{ conn_data.soapaction }\"" 
        extheader['Accept-Encoding'] = 'gzip' if send_accept_encoding_gzip?
        send_string = conn_data.send_string
        @wiredump_dev << "Wire dumped:\n\n" if @wiredump_dev
        begin
          retry_count = 0
          while true
            %{color:red}@res% = @client.post(url, send_string, extheader)
            if RETRYABLE and HTTP::Status.redirect?(@res.status)
              retry_count += 1
                if retry_count >= MAX_RETRY_COUNT
                  raise HTTPStreamError.new("redirect count exceeded")
                end
              url = @res.header["location"][0]
             puts "redirected to #{url}" if $DEBUG
            else
              break
            end
         end
        rescue
          @client.reset(url)
        raise
       end
       @wiredump_dev << "\n\n" if @wiredump_dev
       receive_string = @res.content
       if @wiredump_file_base
         filename = @wiredump_file_base + '_response.xml'
         f = File.open(filename, "w")
         f << receive_string
         f.close
       end
       case @res.status
       when 405
         raise PostUnavailableError.new("#{ @res.status }: #{ @res.reason }")
       when 200, 202, 500
         # Nothing to do.  202 is for oneway service.
       else
        raise HTTPStreamError.new("#{ @res.status }: #{ @res.reason }")
       end

      # decode gzipped content, if we know it's there from the headers
      if @res.respond_to?(:header) and !@res.header['content-encoding'].empty? and
          @res.header['content-encoding'][0].downcase == 'gzip'
        receive_string = decode_gzip(receive_string)
      # otherwise check for the gzip header
      elsif @accept_encoding_gzip && receive_string[0..1] == "\x1f\x8b" 
        receive_string = decode_gzip(receive_string)
      end
      conn_data.receive_string = receive_string
      conn_data.receive_contenttype = @res.contenttype
      conn_data
    end
  end
end

module HTTP
    class Message::Body    
      attr_accessor :body
    end
end

After the monkey-patching, the response message will be accessible after invoking a web service method using the client class generated by wsdl2ruby. The response message will become available in the res accessor method through the streamhandler method of the client class that was generated by wsdl2ruby. The class will be called something like “ClientAPISoap” – this will be defined in the defaultDriver.rb file.

In my case:

 driver = ClientAPISoap.new
results = driver.some_ws_method(with_parameters).getResults 
#getResults is also a ws method
raw_response_message = driver.streamhandler.res.body.body

You can then use REXML to parse whatever you need in the SOAP response message body.

How to test production rails exceptions while in development mode

Posted by win
on Friday, April 11

Recently found an easy way to test rails exceptions raised in production while in development.

Though you could just as easily use:

script/server -e production

Short of that the following works perfectly:

Update config/development.rb

change:

config.action_controller.consider_all_requests_local = false

to:

config.action_controller.consider_all_requests_local = true

Then update controllers/application.rb

add as the last method (unless you have additional protected methods then add to those):

 
protected
  def local_request?
    false
  end

This works because rails will check if a raised exception is a local request. If it is a local request the “development” mode error screen will be presented to you like this:

Otherwise the 500 or 404 error pages will be displayed to the user.

Both modifications are needed since there are two ways a request is considered local 1.) which is controlled in the config folder and 2.) A request is also considered local if the request is being served on the local machine (127.0.0.1).

Installing Ruby on Rails, mySQL and Rmagick on Leopard

Posted by win
on Wednesday, April 02

I recently had to reinstall Ruby on Rails and Rmagick on Leopard. There is a lot of debate surrounding the best way to go – whether it be by source, by MacPorts, by Fink or by anything else I don’t know about yet.

I’ve gone the Macports route and have yet to regret it. As according to Paul Sturgess:

MacPorts (formerly known as DarwinPorts) is a package manager that will download, compile and install software, while installing any required dependencies, automatically. You can easily upgrade or deactivate packages you download, it just makes managing everything that much easier.

Paul Sturgess’ article provides an excellent step-by-step guide that had me running on a Macported Ruby on Rails installation in no time at all.

Quick points from Paul Sturgess:

Set up your path environment variables:

PATH="/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin"

Install mySQL, Ruby, and maybe Subversion:

sudo port selfupdate
sudo port install mysql5 +server
sudo port install ruby
sudo port install rb-rubygems
sudo port install rb-termios
sudo port install rb-mysql
sudo port install subversion +tools

Add a symbolic link to the mysql5 mysqld.sock:

sudo ln -s /opt/local/var/run/mysql5/mysqld.sock /tmp/mysql.sock

Make sure Mysql5 starts up whenever the machine is rebooted with:

sudo launchctl load -w /Library/LaunchDaemons/org.macports.mysql5.plist

Install Ruby on Rails and others:

sudo gem install -y rake
sudo gem install -y rails
sudo gem install -y capistrano
sudo gem install -y mongrel
sudo gem install -y mongrel_cluster

In addition, Educate. Liberate. provides the simple rules to follow to get Rmagick properly installed once you’re rolling on Rails goodness.

Quick points from Educate.Liberate.:

sudo port install tiff -macosx
sudo port install ImageMagick
sudo gem install rmagick

A lesson in a working Dreamhost .htaccess 0

Posted by win
on Wednesday, March 19

# General Apache options
AddHandler fastcgi-script .fcgi
AddHandler cgi-script .cgi
Options +FollowSymLinks +ExecCGI

# If you don't want Rails to look in certain directories,
# use the following rewrite rules so that Apache won't rewrite certain requests
# 
# Example:
#   RewriteCond %{REQUEST_URI} ^/notrails.*
#   RewriteRule .* - [L]

# Redirect all requests not available on the filesystem to Rails
# By default the cgi dispatcher is used which is very slow
# 
# For better performance replace the dispatcher with the fastcgi one
#
# Example:
#   RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
RewriteEngine On

# If your Rails application is accessed via an Alias directive,
# then you MUST also set the RewriteBase in this htaccess file.
#
# Example:
#   Alias /myrailsapp /path/to/myrailsapp/public
#   RewriteBase /myrailsapp

RewriteRule ^$ index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]

# In case Rails experiences terminal errors
# Instead of displaying this message you can supply a file here which will be rendered instead
# 
# Example:
#   ErrorDocument 500 /500.html

ErrorDocument 500 "<h2>Application error</h2>Rails application failed to start properly"

Rebirth of the blog 0

Posted by win
on Tuesday, March 18

I had a blog before this one - not a good one, or even one worth talking about - but I've decided to change it up anyway. Its customary for curious neophytes of the geeky inclination to try out and explore the newest in technology so with this in mind I have traded in my Dreamhost-approved Wordpress for a brand-spanking new Ruby on Rails-powered supercool Mephisto blog. However, before taking on such a task my research left me a little more than just a little intimidated about installing Mephisto on my Dreamhost account.

Fortunately, braver and much smarter geeks ahead of me have decided to help us out by blogging their successes and more importantly their failures. Of the blogs chronicling the journey of installing Mephisto on Dreamhost Medeus made the installation about as smooth as any I'd ever tried - WITH THE ADDITION of creating a new Dreamhost user to get rid of the common error below:

FastCGI: incomplete headers (0 bytes) received from server

Follow the instructions and you should be sailing in no time.

Update:

I recently found out the Medeus blog I pointed to earlier in this post has gone to great beyond. However I did take the following scraps from the Google cache to replace my dead link



We all know Dreamhost is one of the best and cheapest solutions for all of your hosting needs. You can host unlimited domains with a ton of bandwidth and disk space for literally a couple of bucks a month. If you don't already have a Dreamhost account, you can get one here.

Wow what a pain... I was finally able to get this working after much trial and error and searching the internet.

I was following Yet Another Guide to Installing Mephisto on Dreamhost but was having a little difficulty mostly because it is using the most recent version of Mephisto. But this is where I found the most help.

So here is how I finally got Mephisto up on Dreamhost. Hopefully it helps somebody else to not have to deal with the problems I encountered.

    * Download 0.7.3 Noh-Varr (Bug fixes). There were issues checking out the most recent version using subversion so I reccomend to just grab the stable release. The stable release also comes with tzinfo in the vendor directory so no need to download it.
    * Upload it to your home directory on Dreamhost.
    * $ tar xzvf mephisto-0.7.3.tar.gz
    * $ cd mephisto-0.7.3
    * $ rake rails:freeze:edge TAG=rel_1-2-2
    * Use dreamhost panel to create mysql databases with username, password, etc. It's under Goodies - Manage MySQL
    * create config/database.yml and use information of mysql databases just created and don't forget not to use localhost for host but use what the Dreamhost panel tells you to use when you created the database
    * $ which ruby
    * whatever location ruby is in change public/dispatch.rb and public/dispatch.fcgi shebang to show this. Mine was #!/usr/bin/ruby
    * Edit public/.htaccess to use fcgi. Changes this line RewriteRule ^(.*)$ dispatch.cgi [QSA,L] to RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
    * Add DirectorySlash Off to public/.htaccess. This will fix the bug that doesn't allow more than one comment to be posted.
    * Edit config/environment.rb by uncommenting this line ENV['RAILS_ENV'] ||= 'production' so that you use your production database.
    * If there is no log directory, create it $ mkdir log
    * Change permissions - $ chmod -R u+rwX,go-w public log
    * $ rake RAILS_ENV=production db:bootstrap
    * Use dreamhost panel to use FastCGI and to create a link to your public directory of your mephisto folder. Domains - Manage domains and click Edit on your domain. Check FastCGI- support? and change web directory to /home/username/mephisto-0.7.3/public/

Everything should now work. Hopefully that helps someone...