Created
September 4, 2012 16:38
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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