0

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!

Community
  • 1
  • 1
Jim Connors
  • 297
  • 4
  • 14

1 Answers1

1

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))
psugar
  • 1,897
  • 2
  • 18
  • 27
  • You're right, it's not reversible because some names have hyphens and others have spaces between words. I'll take your advice and make it a regular attribute. – Jim Connors Mar 16 '12 at 15:51