Rails 2.2 Custom Error Pages With Exception Loggable

Code, Rails, Ruby No Comments »

Well, with the release of Rails 2.2 and the ability to create custom error pages I figured I’d revisit my 404/500 pages and try to do it the new way.

Setting up the rescue_from methods were simple enough, but I noticed that when I was capturing my error 500s it wasn’t logging the exception. Here is a quick way to have it both display your custom 500 page and log the exception for later review:

  # application.rb
  include ExceptionLoggable

  unless ActionController::Base.consider_all_requests_local
    # yeah, its a long line
    rescue_from ActiveRecord::RecordNotFound, ActionController::RoutingError, ActionController::UnknownController, ActionController::UnknownAction, :with => :render_404
    rescue_from RuntimeError, :with => :render_500
  end

private

  def render_404
    render :template => "shared/error_404", :layout => 'application', :status => :not_found
  end

  def render_500
    # hacky, but works, this logs the exception in ExceptionLoggable
    log_exception $!
    render :template => "shared/error_500", :layout => 'application', :status => :internal_server_error
  end

To test this just change config.action_controller.consider_all_requests_local = true to false in your config/environments/development.rb file.

Not the _best_ way or cleanest, but it gets the job done without too much trouble.

OSX, RubyGems and cross-thread violations in rb_gc

Mac OS X, Nix, Ruby No Comments »

I recently decided to migrate away from OSX’s default ruby install yesterday and noticed a few quirky hangups. Firstly, for some reason, and I’m not sure if it is just me or not, OSX’s default $PATH variable is putting /usr/local/bin AFTER /bin making your local installs not enabled by default. (Editing the /etc/paths didn’t do the trick so I manually added it to PATH).

The installation went easily for both ruby gems and ruby, but I decided to take a ’short cut’ and copy all my gems from /Library/Ruby/Gems into my /usr/local/lib directory which started raising all kinds of errors — this one, in particular was obnoxious.

[BUG] cross-thread violation on rb_gc()

Luckily, all that means is that I copied over gems which were compiled against the standard OSX ruby version and not the new one. This was a little script I wrote which will show you which gems need to be re-compiled. Just cd over to your /usr/local/lib/ruby/gems/1.8/gems directory and run:

ls -1 **/**/*.bundle|ruby -pe '$_.gsub! /\-.*/, ""'|uniq

to get a list, or pipe that into sudo gem install and that should clear up those gc issues.

Rails: Mocking YAML arrays as ActiveRecord objects

Code, Rails, Ruby, Web No Comments »

I’ve been finding myself using YAML a lot for silly enums — maybe because I’m lazy, but mostly because there is no need to manage them via a database table. Here is just a simple example — I need to associate a region and division to a client. These will not change much and are simple enough to keep as a Yaml array until more logic can be brought to the table. Here is how that YAML file looks:

# RAILS_ROOT/config/app.yml

regions:
  - 'northeast'
  - 'southeast'
  - 'west'
  - 'central'
  - 'emerging east'
  - 'emerging west'
  - 'opportunity east'
  - 'opportunity west'
  - 'opportunity national east'
  - 'opportunity national west'

divisions:
  <%= (1..71).map{ |i| "Region #{i}" }.to_yaml %>

Loading it up using an initializer:

# RAILS_ROOT/config/initializers/load_app_config.rb

fdata =File.open(File.join(RAILS_ROOT, "config", "app.yml")).read
APP = YAML::load(ERB.new(fdata).result(binding)).symbolize_keys

Now we have our APP hash chock full o’ YAML goodness. My only problem with this is that I might want to eventually put this data set into a table and it is a pain to hunt and search for where the application references APP[:regions] and so on sooo: time to objectize.

I decided that since they are stupid simple objects they can all have the same parent: YamlArrayObject:

# RAILS_ROOT/app/models/yaml_array_object.rb
# or in lib

class YamlArrayObject
  attr_reader :name
  def id
    0
  end
  def initialize(name)
    @name = name
  end
  def to_s
    name
  end
  def display_name
    to_s.titleize
  end
  def <=>(b)
    name <=> b.name
  end
end

Simple enough. Now we just inherit and overload as appropriate.

# RAILS_ROOT/app/models/region.rb
class Region < YamlArrayObject
  def self.all
    APP[:regions].map{ |r| Region.new(r) }
  end
end

# RAILS_ROOT/app/models/division.rb
class Division < YamlArrayObject
  def <=>(b)
    name.to_i <=> b.name.to_i
  end
  def self.all
    APP[:divisions].map{ |d| Division.new(d) }
  end
end

This is all Jim Dandy right now since we can populate select boxes using cleaner code (bonus: won’t break if you decide to add Divisions to a database table)

# i like
<%= f.select :division, Division.all.sort.map{ |d| [d.display_name, d] } -%>
# better than
<%= f.select :division, APP[:divisions].sort{|a,b| a.to_i <=> b.to_i}.map{ |d| [d.titleize, d] } -%>

The only real issue is that calling Client.first.region still returns a string, which is bad since we want to keep our code as ambiguous as possible. The last step is to override the Client class’ methods for region and division (and whatever else we want to use):

# RAILS_ROOT/app/models/client.rb

def division
  Division.new(@attributes['division']) unless @attributes['division'].blank?
end
def region
  Region.new(@attributes['region']) unless @attributes['region'].blank?
end

Now in our views (client/show) we can simply call @client.region.display_name or whatever and not have to change the code when we finally get around to DBing those object.

(There might be better ways to do this that I’m missing, but this seems pretty okay for my needs right now.)

Ruby on Rails Helpful Helpers: Content Tags

Code, Rails, Ruby No Comments »

Another common thing I like to do is use a helper method to handle tricky tag-soupish markup. A client may have 1 URL, in which case I would like to simply display it, but if they have multiple URLs I’d like to put it in a list format. The only problem with using the content_tag function is that it ugly to do HTML building. (And sometimes you just don’t _need_ a builder…) This is just a simple wrapper for these cases.

  def content_tag_each(items)
    items.inject(''){ |output, item| output << yield(item) }
  end

Usage

# urls = (string) semi-colon seperated URL list since this is
# from a legacy system and doesn't really need normalization
def display_urls(urls)
  link_options = {:target => :blank}
  urls = urls.split(';')

  # handle single url
  return link_to(urls.first, urls.first, link_options) unless urls.size > 1

  # handle multiple urls
  content_tag(:ul) do
    content_tag_each(urls) do |url|
      content_tag(:li){ link_to(url, url, link_options) }
    end
  end
end

Nothing special really, but can come in handy for certain cases.

Ruby on Rails Helpful Helpers: Defaulting Variables

Code, Rails, Ruby No Comments »

One piece of code I find myself using a lot is for defaulting values using a simple conditional if statement: condition ? true : false. This isn’t bad in itself, but it also isn’t very powerful and dynamic. I wrote a small application helper which wraps this function and provides a pretty nice way of setting default values.

  def default(object, default = 'n/a')
    return default if object.blank?
    block_given? ? yield(object) : object
  end

Usage

A very simple example:

#
# Simple Example
#

my_string = ''
puts default(my_string, 'String is empty')
# => 'String is empty'

my_string = 'hello world'
puts default(my_string, 'String is empty')
# => 'hello world'

my_string = 'hello world'
puts default(my_string, 'String is empty') { |str| str.titleize }
# => 'Hello World'

#
# Yielding example
#

puts default(current_user, 'Guest') { |user| user.name.titleize }

Subversion Info in Ruby / Rails

Code, Nix, Rails, Ruby No Comments »

I was trying to tag a few of my internal apps with a subversion revision number just for personal reference. Since running the command svn info yields YAML-ish output the ruby YAML library can load it. Sweet. The next step was just wrapping it in a class and creating some instance variables and methods for them.

The default YAML output

This is what you will get if you simply throw the YAML.load result to an array or something. Nice, but I’m not a big fan of “Keys Like This” so…

irb(main):011:0> pp YAML.load(`svn info`)
{"Node Kind"=>"directory",
 "Last Changed Author"=>"rob",
 "URL"=>"http://example.com/share/lib",
 "Schedule"=>"normal",
 "Last Changed Rev"=>441,
 "Repository UUID"=>"0afc494f-e74d-0410-99f2-b94b27995134",
 "Repository Root"=>"http://example.com",
 "Last Changed Date"=>"2008-07-15 15:55:54 -0400 (Tue, 15 Jul 2008)",
 "Revision"=>446,
 "Path"=>"."}
=> nil

A nice class wrapper for the SVN Info

Heres what I ended up with. Nothing fancy, just a simple wrapper around the subversion info dump.

require 'yaml'
class SVNInfo
  def initialize
      YAML.load(`svn info`).each do |k,v|
          key = k.gsub(/\s/, '_').downcase
          instance_variable_set "@#{key}", v
          instance_eval %{ def #{key}; @#{key}; end }
      end
  end
end

Here is the end result:

irb(main):013:0> svn_info = SVNInfo.new
# ... snip ...
irb(main):014:0> pp svn_info
#<SVNInfo:0x57f378
 @last_changed_author="rob",
 @last_changed_date="2008-07-15 15:55:54 -0400 (Tue, 15 Jul 2008)",
 @last_changed_rev=441,
 @node_kind="directory",
 @path=".",
 @repository_root="http://example.com",
 @repository_uuid="0afc494f-e74d-0410-99f2-b94b27995134",
 @revision=446,
 @schedule="normal",
 @url="http://example.com/share/lib">
=> nil
irb(main):015:0>

Messing Around

irb(main):018:0> pp svn_info.methods - Object.methods
["last_changed_author",
 "revision",
 "repository_root",
 "last_changed_rev",
 "path",
 "url",
 "node_kind",
 "last_changed_date",
 "repository_uuid",
 "schedule"]
=> nil
irb(main):019:0> svn_info.revision
=> 446
irb(main):020:0> svn_info.last_changed_author
=> “rob”
irb(main):021:0>

Hope that comes in handy :)

History Meme

Code, Nix, Random No Comments »

Took the idea from Dive Into Mark because I’m bored. :)

If you’re curious to see which commands you use the most just run:

history | awk '{a[$2]++}END{for(i in a){print a[i] ” ” i}}’ | sort -rn | head
# local server
133 l
70 cd
47 svn
38 ..
29 e
26 mv
20 ll
10 rm
10 cp
8 ror
# remote server
123 l
74 cd
35 svn
31 touch
26 ..
23 exit
23 cat
20 ll
18 rm
16 rake

A few notes
here are those goofy aliases that you see:

alias ll='ls -lah'
alias la='ls -a'
alias l='ls -lh'
alias ..='cd ..'
alias ~='cd ~'
alias e='mate '

alias ss='./script/server'
alias console='./script/console'
alias migration='./script/migration'

alias ror='/var/rubydev'
alias www='/var/www'

shakebook pro for leopard - switch spaces with violence!

Code, Mac OS X, Random, Ruby No Comments »

I was just goin around on the interblagosphere today and stumbled upon Erling Ellingsen’s smackbook pro. If you’ve never heard of this then you’re in for a shock. The basic idea behind what he has created is a way to switch virtual desktops simply by tapping the side of the laptop’s monitor.

I was immediately in love and wanted to play with it a bit but he was using DesktopManager to do the space switching. Since I’m running leopard on the laptop I figured that was a waste of time and I’d never actually use a 3′d party virtual desktop switching app… and so the journey began. I turned to my mortal enemy, applescript, to accomplish this. After some browsing and hacking I found that this simple code can send CONTROL-# keystrokes to get the job done:

tell application "System Events"
	tell process "Finder"
		keystroke "[SPACENUMBER]” using control down
	end tell
end tell

If you toss that into osascript from the command line we can finally start to get somewhere. So the next step was to grab that sudden motion sensor app. Erling was using AMSTracker by Amit Singh so that seemed a good place to start. After that a quick ruby script tied the SMS dump to the applescript and a fun new project was born. It is a lotta bit rough around the edges and needs some sensitivity tuning, but it _does_ get the job done… just be a little rough* :)

I am definitely not responsible for any damage caused by using this script — it was a proof of concept hack.

In case you have no idea WTF I mean — here is “SmackBook Pro”

This is not mine, but mine does essentially the same thing, only using native Leopard spaces… and ruby.

Click image to view video

Where to get the script?

Running it is as simple as AMSTracker -S -u0.01 | shakebook.rb then tap away (or shake if you want to be careful)

Revisions will probably be made to sensitize it once I have time to mess around with it — if you come up with anything shoot me back a comment :)

get protected ical calendars in google calendar

Code, Google, Life, Mac OS X, PHP No Comments »

This is a short and sweet post. I was trying to merge and sync all my calendars (something I do every so often which leaves me frustrated, drunk and huddled in a corner crying) and decided on google calendar as a main point since I have my work Outlook synced up with it (using their outlook sync program). I setup a simple WebDAV url on my good ole’ dreamhost and had a password protected directory to publish my schedule to from iCal.

iCal can publish to a password protected directory just fine — but to my surprise, google calendar could _not_ read from one… _only_ public urls. Wtf? I’m really hoping I overlooked something because this is just pathetic.

Anyway, the solution turned out to be dirt simple. Keep all protected calendars in a /private folder on my domain and have a public facing script to route stuff. So I went to work, and a few minutes later, here it is.

I tested this just now and google calendar can indeed read my password protected calendar so thats cool. It isn’t the best way I’m sure — but, hey, it only took a few minutes (edit: less time than it took to write this post in fact) and it gets the job done. (Plus I don’t exactly have a “personal” personal calendar, I’d just rather it not be public.)

view the protected ical calendars in google project page

Hope that can help someone. Or if there were any suggestions feel free to e-mail me :)

self clearing text input fields with javascript

Code, Javascript, Web 1 Comment »

I found that I use a lot of input fields which need to display a simple message to the user like “type the molecular structure of didehydro-dimethylether onium cation” — and when they focus the box it needs to clear, and when they blur the box it needs to go back to that message. Theres the sloppy way of doing it in the text box itself with the attribute callbacks “onfocus/blur” but thats annoying. I decided to make a simple extension to the HTMLInputElement instead like a good boy.

Here is the input extension to make a text field (actually, _any_ input, but you can add that logic yourself:) ) self clearing:

Requires Prototype Javascript Library!
I used v1.6 but I’m sure others will work fine.

// input_extensions.js

// extends HTMLInputElement to include a self-clearing method
// @author Rob Hurring
// @date 2008-04-23

Object.extend(HTMLInputElement.prototype, {
	make_self_clearing:function()
	{
		this.original_value = this.value
		Event.observe(this, 'focus', function()
		{
			if(this.value == this.original_value)
				this.value = '';
		});
		Event.observe(this, 'blur', function()
		{
			if(this.value == '')
				this.value = this.original_value;
		});
	}
});

when you want to use it, something like this can work:

<!-- index.html -->
<input type="text" name="some_field" id="some_field" value="start typing in this field!" />
<script language="javascript">
	// put somewhere after the field — or in an onLoad event, wherever.
	$(’some_field’).make_self_clearing();
</script>

JavaScript Self Clearing Input Project Page

© Ubrious / Zerobased, LLC 2008 – <This theme has been modified> Original Theme by N.Design Studio
Entries RSS Comments RSS Log in