In Rails 3, how can I retrieve a record by looking up on a virtual attribute? I have a name
column and a slug
that does a simple modification to it (see code below). How can I do a "reverse lookup" by slug
to name
?
I'm trying to find the right code for the find_by_slug
method below:
class Brand < ActiveRecord::Base
has_many :sale_items
validates :name, :uniqueness => true
def slug
self.name.downcase.gsub(/\s/, '-')
end
def self.find_by_slug(given_slug)
first(slug: given_slug)
end
end
When I try find_by_slug
in the Rails console I'm given an Unknown key: slug
error.
This question seems similar but I'm not sure if it's the same as my problem. I'd appreciate some insight and help!
Since slug doesn't exist in the database you can't query for it with first. What you need to do is search on the name. But in order to do that, your 'name to slug' mapping needs to be reversible. You need to be able to do
name = 'San Francisco'
slug = convert_to_slug(name) #san-francisco
name == convert_to_name(slug) #true
So that given a slug, you know what it's name would be - you can then do find_by_name. Right now your slug conversion
downcase.gsub(/\s/, '-')
is not reversible, unless there's some implicit information that you're not sharing with us, like 'there are only spaces and every first letter is capitalized'. So it can't be done, and you're best off making this a regular attribute and not a virtual one. If your conversion is reversible, then you just have to use
find_by_name(convert_to_name(slug))