Friendly id

What does the friendly_id gem allow foreman to do?

Foreman can use the same find logic for http://example.com/hosts/fdev2.sat.lab.tlv.redhat.com or http://example.com/hosts/394

params[:id] = ‘fdev2.sat.lab.tlv.redhat.com’
params[:id] = 394

without worrying if params[:id] contains the 'id' or 'name'. Otherwise, we would need code logic to either use find_by_id(params[:id) or find_by_name(params[:id).

Host.find(394)
Host.friendly.find(‘fdev2.sat.lab.tlv.redhat.com’)

Both work!

Please not the friendly scope, without which in rails 4 find will yield nothing - this scope was introduced in the friendly_id version we use in rails 4.

How to use friendly_id gem in a model?

class Operatingsystem < ActiveRecord::Base
   extend FriendlyId
   friendly_id :title

What are the benefits of using the friendly_id gem?

There is common find logic between UI (application_controller.rb) and API (api/base_controller.rb)

Logic is contained in a mixin called FindCommon located at app/controllers/concerns/find_common.rb
This mixin is included in both application_controller.rb and api/base_controller.rb

No need to specify previously used 'resource_identifying_attributes' for API controllers. (ex. ['login', 'id'] for users_controller)

How to use 'slug' database field as "friendly-id" in URL?

1) Create 'slug' field in database which will save the parameterized field defined by friendly_id

  friendly_id :title, :use => :slugged

If title is 'Europe/Israel/TLV', then slug is saved as 'europe-israel-tlv'

Location.friendly.find('europe-israel-tlv')

Miscellaneous things to know?

1) "name" wins over "id" if both have the same text value

Domain with id=6 has a name='sat.lab.tlv.redhat.com'
Domain with id=7 has a name='6'

Domain.friendly.find(‘6’) #returns Domain id=7
Domain.find(6) #returns Domain id=6

2) ActiveRecord::RecordNotFound:

Host.find_by_name(‘bad.host.name.com’)
#returns nil

Host.friendly.find(‘bad.host.name.com’)
#returns ActiveRecord::RecordNotFound: Couldn't find Host::Managed with id=bad.host.name.com

If you want to return nil, need to do this

    @host = begin
      authorized_scope.find(params[:id])
    rescue ActiveRecord::RecordNotFound
      nil
    end

friendly_id benchmarks

https://gist.github.com/norman/1129745

https://github.com/norman/friendly_id/blob/master/bench.rb