Search

Friends

Atomspheric CO2 (PPM)

Archives

Blather

Uptime verified by Wormly.com

6 May 2010

ArgumentError: comparison of Fixnum with nil failed

Using acts_as_nested_set in ruby and something like taxon.move_to_child_of(parent) you can get this error if your table data is incomplete. You may have functioning nesting through the chain of parent IDs but you need the left and right fields as well. If either the left or right field is null you will get an error like this one for certain move operations. This can easily happen if you've created some dodgy fixtures for instance.

Trying using Taxon.rebuild! to repair the table.

23 December 2009

Slow Rails Tests & fixtures :all

With my latest Rails project I'm using a new version of Rails than I'd been used (my last job was over a year ago). It seemed to me that the tests had got substantially slower. Problem was fixtures :all in the test_helper.rb. I changed that and things got much quicker.

18 December 2009

DEPRECATION WARNING: ActiveRecord::Errors.default_error_messages & attachment_fu

The latest version of attachment_fu will give you this error. You need to replace a line in this file:

vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu.rb:386

+ errors.add attr_name, I18n.translate('activerecord.errors.messages.inclusion') unless enum.nil? || enum.include?(send(attr_name))    
- errors.add attr_name, ActiveRecord::Errors.default_error_messages[:inclusion] unless enum.nil? || enum.include?(send(attr_name))

12 August 2008

Apache 2, mod_passenger and HTTP Authentication

Using Lighttpd and FastCGI for Rails you can use Lighty's HTTP Authentication to "protect" an application. But the equivalent doesn't work with Apache 2. Putting the Apache authentication stuff in a <Directory> block will protect all the styles and scripts but no the application itself. You need to use a <Location> block for that.

<Location /*>
    AuthType Basic
    AuthName "Beta Testing"
    AuthUserFile /path/to/htpasswd
    Require valid-user
</Location>

28 July 2008

No HTTP methods allowed with Rails 2

ActionController::MethodNotAllowed
Only get, head, post, put, and delete requests are allowed.

I started getting this funny little error this morning. It is a funny error in the humorous sense, but possibly you need to have used REST to think so. There were a few people getting this problem and finding a few different solutions, but my problem was I had a map.namespace in my routes.rb file. map.namespace appears to be deprecated/abandoned. So I tried using map.resource instead of the map.namespace. Technically I'm looking for a namespace and not a singleton resource, but it worked for me and namespaces and singular resources provide pretty similar functionality in this case. Although I'm still struggling to fix my tests so they they figure out what URL to use.

Update: Singleton resources seemed to cause problems with the :collection option, so now I've rolled my own namespaces with :path_prefix.

25 July 2008

Nested Scopes

I've just replaced a whole stack of nasty hand-coded SQL with nested scopes. There is a lot you can do with them that you aren't quite able to do with the standard associations. The main benefit is that you don't lose find_in_collection which all the examples seem to neglect. It's pretty rare that you want everything in a table. You mostly want to sort it and slice it, or search through it. So finder_sql isn't useful for very much. It doesn't provide any value that a standard method with some custom SQL search doesn't provide.

class User
    def public_topics(*options)
        Topic.with_user_scope(self) { Topic.with_public_scope { Topic.find(*options) }
    end
end

I was able to replace a nasty SQL subquery with this. And even swiftier, you can give it your normal ActiveRecord::Base.find options. It's probably not clear why I couldn't just use normal associations here, but I really couldn't. There was a topic_relationships table which connected users to topics very oddly, which is what created all the headaches.

So the moral of the story is, with_scope is the probably best option when normal associations won't cut it.

23 July 2008

Problems with ActionController::MethodNotAllowed

I started getting exceptions like this without really being sure why:

 ActionController::MethodNotAllowed 
 (Only get, put, and delete requests are allowed.)

I think the version of Rails was probably updated and it became less forgiving of our pitiful custom form builder.

One of the frustrating things about custom form builders is the Rails form helpers seems to move faster than it's practical to keep up with. So you end up with a whole lot of old-fashioned form builder code lying around that is either bigger than it needs to be or totally broken.

The new Rails RESTful routes stuff uses the "put" method to update existing records. Which I think is slightly silly, but someone is convinced we need to apply the HTTP CRUD metaphor to web forms. So we use hacks like <input type="hidden" name="_method" value="put" /> because forms don't support proper HTTP puts.

But anyway, that's the way things are and as everyone learns with Rails, resistance is futile or at least far more pain than it's worth.

But this particular problem I've fixed. The form action for updates should be /object/1234, which accepts GET, PUT, DELETE. I was getting MethodNotAllowed errors because my form builder wasn't adding the hidden _method field. Rails was treating the update as a normal POST to /object/1234 instead of a PUT. So I got the form builder to add in the hidden field for existing records, and everything was sweet.

Someone else had the same problem for a different reason.

Unknown column in field list in Rails 2 fixtures

This is a problem I've come across a few times and I keep forgetting why it happens. It occurs when there is an runtime error in the model (script errors fail more loudly). This is typically a NameError, such as a bad library name or method call. The new rails fixtures need to look at the model associations to work out their magic - the mapping between association names and association foreign keys. But if the model code is bad it silently fails and the fixtures code can't work out what to do.

You'll get something like this:

$ rake db:fixtures:load
rake aborted!
Mysql::Error: Unknown column 'holiday_type' in 'field list': INSERT INTO `holiday_periods` (`holiday_type`, ...) VALUES ('school_holidays', ...)

I'd assumed it was a problem with the fixtures or the migrations. But in this case the problem was in the HolidayType class. Which is certainly not clear from the error, but on reflection not really so surprising.

31 May 2008

Sort by two object attributes in Ruby

This is a potentially ugly to solve, but you can actually compare two arrays. So it isn't so bad. If the first attributes are the same, it sorts by the second.

def <=>(other)
  [self.dtstart, self.dtend] <=> [other.dtstart, other.dtend]
end

27 May 2008

European Dates in Ruby on Rails

I found a solution to the problem of month/day ordering by overriding the autocasting code in ActiveRecord. However, that didn't solve the problem more generally. So I came up with a nicer solution that uses the existing Date::Format._parse_sla_eu method. It replaces the US year/month/day parsing method with the European one.

# Overrides the default Date::_parse() method for dates of format dd/mm/yyyy
# ParseDate does the typical American thing and assumes mm/dd/yyy and
# doesn't seem to be configurable

module Date::Format::EuropeanDates
  def self.included(base)
    base.class_eval do
      class << self
        alias_method :_parse_sla_us, :_parse_sla_eu
      end
    end
  end
end

Date.send(:include, Date::Format::EuropeanDates)

With thanks to Simon who showed me how to replace static methods. This is the kind of wacky stuff you could never do with PHP. Not that we should want to. It's kind of ridiculous.

13 May 2008

Changing human attribute labels in Rails validation messages

I've been frustrated by the lack of humanity in Rails so-called human names. So I wrote a little library, which was largely stolen from Change displayed column name in Rails validation messages. The library lets you do something a little like this...

require 'human_attributes'

class Puppy < ActiveRecord::Base
  humanize_attributes :breakfast => "Puppy's preferred breakfast"
  validates_presence_of :breakfast
end

It doesn't do anything very spectacular, but it took me a long time to work out.

# lib/human_attributes.rb

module ActiveRecord
  class Base
    # Humanize attributes
    def self.human_attribute_name(attr)
      @humanized_attributes ||= {}
      @humanized_attributes[attr.to_sym] || attr.humanize
    end

    def self.humanize_attributes(*args)
      @humanized_attributes = *args
    end
  end
end

ActiveRecord::Base#human_attribute_name is deprecated and will be replaced by proper string inflection. For those with fancy, modern humanizing Inflectors you might have to change it to something like this.

def self.humanize_attributes(*args)
  humanized_attributes = *args
  Inflector.inflections do |inflect|
    humanized_attributes.each do |attr, label|
      inflect.human attr.to_s, label
    end
  end
end

Although I couldn't get that to work, probably because my Rails isn't new enough.

17 March 2007

Ruby + Matrices = Nonstop Fun!

I've had a look at a few different things for stuffing around with matrix arithmetic. It's the sort of thing my degree has reduced me to. I've looked at Excel and R. I already know about Stata. At uni they think Matlab is pretty good. But I've found something better than all of them. Ruby. It's totally sweet.

require 'matrix'
Q = Matrix[[20, 30, 43],
           [20, 25, 10],
           [20, 10, 5]]
assets = Matrix[[10], [20]]
price = Matrix[[5, 10]]
portfolio = Q.inv * assets
cost = price * portfolio

Or some leet OLS. Oh yeah.

portfolio = (Q.t*Q).inv*Q.t*assets

Awesome eh? It probably seems more nifty to programmers and those who've tried matrices in Excel. Nasty. I even wrote a little Ruby library to make printing out the matrices prettier. Although probably if I count that extra time my average productivity drops quite a bit.

Ruby is pretty good all round. Kind of slow in spots. But that won't stop it from taking over the world pretty soon.

10 June 2006

PHP and Ruby

I predict that PHP will go, and Ruby will replace it. For a developer, the only reason to keep using PHP is its transportability. And that advantage will disappear as web hosts realise that PHP only has this advantage going for it and start installing Ruby. I've been looking at the PHP MVC "frameworks", and they're OK, but you wouldn't use them unless you were wedded to PHP. There is nothing in them that people couldn't have developed five years ago. Even if they had, it still wouldn't have saved PHP. Ruby has elegance that PHP seems proud not to have.

22 February 2006

Ruby

I started learning Ruby the other day. I'm scripting one of the things for my uni project in it. It's so easy to learn. And exceptions are way tasty.

Everyone raves about Rails, but I'm a much bigger fan of Ruby than of Rails. Rails strikes me as very bloated and restrictive. Maybe I'll still become a convert though.

0.107 seconds