Module: FriendlyId::FinderMethods
- Included in:
- History::FinderMethods
- Defined in:
- lib/friendly_id/finder_methods.rb
Instance Method Summary collapse
-
#exists?(conditions = :none) ⇒ Boolean
Returns true if a record with the given id exists.
- #exists_by_friendly_id?(id) ⇒ Boolean
-
#find(*args, allow_nil: false) ⇒ Object
Finds a record using the given id.
-
#find_by_friendly_id(id) ⇒ Object
Finds exclusively by the friendly id, completely bypassing original
find
. - #first_by_friendly_id(id) ⇒ Object private
-
#parse_friendly_id(value) ⇒ Object
private
Parse the given value to make it suitable for use as a slug according to your application's rules.
- #potential_primary_key?(id) ⇒ Boolean private
- #raise_not_found_exception(id) ⇒ Object private
Instance Method Details
#exists?(conditions = :none) ⇒ Boolean
Returns true if a record with the given id exists.
40 41 42 43 44 |
# File 'lib/friendly_id/finder_methods.rb', line 40 def exists?(conditions = :none) return super if conditions.unfriendly_id? return true if exists_by_friendly_id?(conditions) super end |
#exists_by_friendly_id?(id) ⇒ Boolean
53 54 55 |
# File 'lib/friendly_id/finder_methods.rb', line 53 def exists_by_friendly_id?(id) where(friendly_id_config.query_field => parse_friendly_id(id)).exists? end |
#find(*args, allow_nil: false) ⇒ Object
Finds a record using the given id.
If the id is "unfriendly", it will call the original find method. If the id is a numeric string like '123' it will first look for a friendly id matching '123' and then fall back to looking for a record with the numeric id '123'.
Use allow_nil: true if you'd like the finder to return nil instead of raising ActivRecord::RecordNotFound
Example
MyModel.friendly.find("bad-slug")
#=> raise ActiveRecord::RecordNotFound
MyModel.friendly.find("bad-slug", allow_nil: true)
#=> nil
Since FriendlyId 5.0, if the id is a nonnumeric string like '123-foo' it will only search by friendly id and not fall back to the regular find method.
If you want to search only by the friendly id, use #find_by_friendly_id.
28 29 30 31 32 33 34 35 36 37 |
# File 'lib/friendly_id/finder_methods.rb', line 28 def find(*args, allow_nil: false) id = args.first return super(*args) if args.count != 1 || id.unfriendly_id? first_by_friendly_id(id).tap { |result| return result unless result.nil? } return super(*args) if potential_primary_key?(id) raise_not_found_exception(id) unless allow_nil rescue ActiveRecord::RecordNotFound => exception raise exception unless allow_nil end |
#find_by_friendly_id(id) ⇒ Object
Finds exclusively by the friendly id, completely bypassing original
find
.
49 50 51 |
# File 'lib/friendly_id/finder_methods.rb', line 49 def find_by_friendly_id(id) first_by_friendly_id(id) or raise_not_found_exception(id) end |
#first_by_friendly_id(id) ⇒ Object (private)
77 78 79 |
# File 'lib/friendly_id/finder_methods.rb', line 77 def first_by_friendly_id(id) find_by(friendly_id_config.query_field => parse_friendly_id(id)) end |
#parse_friendly_id(value) ⇒ Object (private)
Parse the given value to make it suitable for use as a slug according to your application's rules.
This method is not intended to be invoked directly; FriendlyId uses it internally to process a slug into string to use as a finder.
However, if FriendlyId's default slug parsing doesn't suit your needs, you can override this method in your model class to control exactly how slugs are generated.
Example
class Person < ActiveRecord::Base
extend FriendlyId
friendly_id :name_and_location
def name_and_location
"#{name} from #{location}"
end
# Use default slug, but lower case
# If `id` is "Jane-Doe" or "JANE-DOE", this finds data by "jane-doe"
def parse_friendly_id(slug)
super.downcase
end
end
110 111 112 |
# File 'lib/friendly_id/finder_methods.rb', line 110 def parse_friendly_id(value) value end |
#potential_primary_key?(id) ⇒ Boolean (private)
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/friendly_id/finder_methods.rb', line 59 def potential_primary_key?(id) key_type = primary_key_type # Hook for "ActiveModel::Type::Integer" instance. key_type = key_type.type if key_type.respond_to?(:type) case key_type when :integer begin Integer(id, 10) rescue false end when :uuid id.match(/\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/) else true end end |
#raise_not_found_exception(id) ⇒ Object (private)
114 115 116 117 118 119 120 121 |
# File 'lib/friendly_id/finder_methods.rb', line 114 def raise_not_found_exception(id) = "can't find record with friendly id: #{id.inspect}" if ActiveRecord.version < Gem::Version.create("5.0") raise ActiveRecord::RecordNotFound.new() else raise ActiveRecord::RecordNotFound.new(, name, friendly_id_config.query_field, id) end end |