Validates_uniqueness_of on a facade column

Hey all…

I’ve got a facade column set up (specifically, I’ve got a column in my
database called ip_address that stores an IP as a 32-bit integer rather
than the dotted notation, but the model reads and writes as the dotted
notation), but I want to validate that the IP is unique in the database
whenever an entry is created or edited.

is there any way to do this?

simply putting ‘validates_uniqueness_of :ip_address’ doesn’t work since
it’s querying my database with the dotted notation rather than the
32-bit integer value.

thanks!

You may have to roll your own like:

def before_save
find(:all, :conditions => [‘ip_address = ?’,
convert_to_int(self.ip_address)]).empty?
end

just a note, convert_to_int is simply a facade that you should replace
with whatever method you are using to do the conversion, I assume
IPAddr#to_i, but none-the-less, you get the gist of it.

I’m putting it in my validate function since I want to be able to report
errors to the user.

and it works… awesome, thanks!

I didn’t even think of doing it like that.

my complete function is:

def validate

check if the ip_address is unique

@s = Machine.find(:all, :conditions => [‘ip_address = ? and id <> ?’,
IPAddress.to_int(self.ip_address), self.id])

if @s.length > 0
errors.add :ip_address, “is already taken”
end

end

looks alright, right?

yep, or you could clean it up even more by eliminating the unnecessary
instance variable:

def validate

check if the ip_address is unique

unless Machine.find(:all, :conditions => [‘ip_address = ? and id <> ?’,
IPAddress.to_int(self.ip_address), self.id]).empty?
errors.add :ip_address, “is already taken”
end
end

However, both will work, this one just uses a tad less memory. Glad it
worked for ya.