Inconsistent behavior for #parse_friendly_id
Thanks for the great work in this project 🙇
We have opted-in the #first_by_friendly_id case insensitive change while upgrading to 5.4.0.
With 5.4.2 released, we hope to maintain the same behavior by override #parse_friendly_id in our model, but we have noticed same inconsistent behavior for the finders.
With the following model definition
class Product < ApplicationRecord
extend FriendlyId
friendly_id :name, use: %i[slugged finders]
has_many :skus
scope :not_deleted, -> { where(deleted_at: nil) }
# ...
def self.parse_friendly_id(value)
super.downcase
end
end
We expect the finder to work for the following cases
Product.find('FriendlyID') # => Finds product with #slug friendlyid
Product.includes(:skus).find('FriendlyID')
Product.not_deleted.includes(:skus).find('FriendlyID')
But instead, the first Product.find('FriendlyID') works without issue, yet the second and third statement did not call the correct #parse_friendly_id and returns exception: ActiveRecord::RecordNotFound: can't find record with friendly id: "FriendlyID"
Both Product.includes(:skus) and Product.not_deleted.includes(:skus) returns Product::ActiveRecord_Relation, so I am guessing that Product::ActiveRecord_Relation did not pick up #parse_friendly_id definition from Product model as expected
Strangely, if I called Product.not_deleted.includes(:skus).parse_friendly_id('FriendlyID'), it will return the expected result friendlyid, and if I called Product.not_deleted.includes(:skus).find('FriendlyID') followed by that, the query will return expected result.
We are using
- FriendlyID: 5.4.2
- Rails: 5.2.5
- Ruby 2.7.0
I've also tried moving friendly id settings into initializer with no luck
FriendlyId.defaults do |config|
config.use :reserved
config.reserved_words = %w[ #... ]
config.use :finders
config.use :slugged
config.use(Module.new {
def parse_friendly_id(value)
super.downcase
end
})
end
We want to opt-in for case-insensitive slug and stumbled upon the same behavior. We use slugs without a scope, so our model Organization with
class Organization < ApplicationRecord
extend FriendlyId
friendly_id :name, use: :slugged
def self.parse_friendly_id(value)
super.downcase
end
end
yields
> Organization.friendly.find('customer')
=> #<Organization ...>
> Organization.friendly.find('Customer')
ActiveRecord::RecordNotFound (can't find record with friendly id: "Customer")
and
> Organization.friendly.parse_friendly_id('Customer')
NoMethodError (super: no superclass method `parse_friendly_id' for #<Class:0x00007f8259b0c588>)
We run on FriendlyID: 5.4.2, Rails: 5.2.5, and Ruby 2.5.9.
in addition to that, the example in the documentation has an instance method, not a class method:
# ### 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