norman / friendly_id

FriendlyId is the “Swiss Army bulldozer” of slugging and permalink plugins for ActiveRecord. It allows you to create pretty URL’s and work with human-friendly strings as if they were numeric ids for ActiveRecord models.
http://norman.github.io/friendly_id/
MIT License
6.16k stars 592 forks source link

History does not use parse_friendly_id #1019

Closed manafire closed 1 year ago

manafire commented 1 year ago

If parse_friendly_id is used, say to downcase, it's used by the regular finder methods, but not by history:

https://github.com/norman/friendly_id/blob/master/lib/friendly_id/history.rb#L94

# history.rb:94   
def first_by_friendly_id(id)
  super || slug_table_record(id)
end

super calls the finder method which uses parse_friendly_id, but if that fails (not found, nil), slug_table_record is called with the unparsed ID which results in a query something like this, which will fail because the slug isn't parsed and downcased.

SELECT ... WHERE  "friendly_id_slugs"."sluggable_type" = 'MyModel' AND "friendly_id_slugs"."slug" = 'UNPARSED-VALUE'

Changing the method in history.rb to use the parse method results in expected behaviour:

# history.rb:94   
def first_by_friendly_id(id)
  super || slug_table_record(parse_friendly_id(id))
end

It likely needs to be applied elsewhere, such as exists_by_friendly_id?, where the same pattern super || method_using_unparsed_id(id) exposes the bug.

I also couldn't get parse_friendly_id to work in the documented way without monkey patching it in the initializer, but that's a different issue.