6

How to check if friendly_id entry exists before get it?

For example:

  def book
   @book = Book.find(params[:book_id])
  end

It's ok, but i want check before if friendly_id exists, something like:

def book
  if Book.exists?(params[:book_id])
    @book = Book.find(params[:book_id])
  else
    #404 not found
  end
KK2
  • 63
  • 1
  • 3

4 Answers4

17

As of the latest version of the friendly_id gem, you can say:

Book.friendly.exists? params[:book_id]
Hamed
  • 1,382
  • 11
  • 20
  • 2
    This is so much better than the accepted answer. Exceptions should only be for things you can't easily predict - not things you expect to happen. – marksiemers Feb 27 '15 at 18:12
  • if you use :finders you can probably omit friendly, resulting in `Book.exists? params[:book_id]` – AndreiMotinga Mar 26 '16 at 15:53
  • Dangerous. Any slug that starts with a number will return false positives since it will fall back on ActiveRecord's finder, and "1something".to_i == 1 – Stephen Corwin Jun 17 '21 at 16:01
  • 1
    @StephenCorwin Yes, that's why I don't mix in the "finders" module into my model. – Hamed Jun 17 '21 at 20:29
5

Rescue from RecordNotFound exception ==>

def book
  @book = Book.find(params[:book_id])
  #OK
rescue ActiveRecord::RecordNotFound => e
  head :not_found
end
Deepak N
  • 2,561
  • 2
  • 30
  • 44
2

I suggest you to move Deepak N's solution to model like I did:

def self.find_by_friendly_id(friendly_id)
  find(friendly_id)
rescue ActiveRecord::RecordNotFound => e
  nil
end

So now it will fetch your books by both id and slug and won't throw exception, just like standard AR method #find_by_id.
BTW, according the documentation #exists? method now is right way to check record existance!

icem
  • 707
  • 7
  • 12
-2
@book = Book.find_by_id(params[:book_id])
if @book
  # OK
else
  #404 not found
enв
fl00r
  • 82,987
  • 33
  • 217
  • 237