tl;dr Noticing that the URL for a model instance was surprisingly short, I 
discovered a mismatch between the doc and the implementation for AR's to_param 
method.

Given the history of the #to_param method and various existing (closed) pull 
requests, I wasn't sure if this would be considered an "Issue"/bug or a Feature 
request.

If you want to just jump right into the commit (which I'd like to turn into a 
pull request unless there are particular objections), here you go!

https://github.com/rab/rails/commit/e2b3a1756e3915bb47cd76b164b9866aa8ba244c 
<https://github.com/rab/rails/commit/e2b3a1756e3915bb47cd76b164b9866aa8ba244c>

Otherwise, settle in for a story. Got yourself a tasty beverage? Comfortable? 
OK, here we go!

Once upon a time, I added a:
    to_param :name
to a model that still had anemic little URLs.

One particular record had a name of "process background jobs" and its parameter 
was becoming "4-process".

The docs for #to_param said that returned string would be truncated by words if 
longer than 20 characters.

|.........11111111112
|12345678901234567890
"process background jobs"

Well, it sure seems like truncation was reasonable, but why not to 
"4-process-background"?

Turns out the option passed to the internal call to #truncate was omission: nil 
which was probably intended to not use any string when there was some 
truncation, but actually caused the default value of "..." to be used.

That means the word-by-word truncation plus the "..." needs to fit within the 
requested 20 characters and "process background..." is 21 so "background" gets 
lopped off, too, and "process..." is now safely under the limit.

Interestingly, had the name been just "process background", it would have 
generated "4-process-background" in the first place as no truncation would be 
needed.

The correct way to make this happen is omission:''

Furthermore, the subsequent call to #parameterize eliminates non-alphanumeric 
characters before replacing them with '-' and squeezing them. Therefore, 
calling .parameterize.truncate(20, separator: /-/, omission: '') results in the 
most information from the indicated attribute.

-Rob

Rob Biedenharn
[email protected]
GitHub: https://github.com/rab


-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/rubyonrails-core.
For more options, visit https://groups.google.com/d/optout.

Reply via email to