Skip to content

Instantly share code, notes, and snippets.

@technicalpickles
Created September 4, 2012 16:38
Show Gist options
  • Save technicalpickles/3623243 to your computer and use it in GitHub Desktop.
Save technicalpickles/3623243 to your computer and use it in GitHub Desktop.
Trying to store regular expression results (if a thing is a match) in ActiveRecord can be tricky
# Consider this initial model
class IpAddress < ActiveRecord::Base
attr_accessible :description
end
# At some point, we want to add a boolean field, :primary, and populate that based on if the description matches /primary/i
# Here's the obvious thing to do:
IpAddress.find_each do |ip_address|
primary = ip_address =~ /primary/i
ip_address.update_attributes :primary => primary
end
# Does it work? No, not so much.
# Why? Two parts:
# First is what the regular expression operator returns
ip_address = IpAddress.new(:description => 'Primary IP')
ip_address.description =~ /primary/i # => 0
# It returns zero, which is the position it matches. For ruby, this is truthy, so you can do `if something =~ /matches/` and it works like you would think
# Second is how ActiveRecord stores boolean columns. With MySQL at least, they are stored as TINYINT(1), with 1 for true, 0 for false
# Combine those, and it appears under the hood ActiveRecord is storing the 0 as is, instead of converting to a ruby boolean
# Here's the workaround:
IpAddress.find_each do |ip_address|
primary = (true if ip_address =~ /primary/i)
ip_address.update_attributes :primary => primary
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment