mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
fix to_param to maximize content
The documentation states that parameter values longer than 20 characters will be truncated by words, but the example shows that a parameter based on "David Heinemeier Hansson" (with id: 125) becomes "125-david" when "David Heinemeier".length == 16 so why so short? The answer lies in the use of the #truncate option omission: nil which seems to have been intended to mean "nothing", but which actually causes the default string "..." to be used. This causes #truncate to cleave words until the "..." can be added and still remain within the requested size of 20 characters. The better option is omission: '' (which is probably what was originally intended). Furthermore, since the use of #parameterize will remove non-alphanumeric characters, we can maximize the useful content of the output by calling parameterize first and then giving truncate a separator: /-/ rather than a space.
This commit is contained in:
parent
c62ac07be8
commit
3b49d79223
3 changed files with 41 additions and 4 deletions
|
@ -1,3 +1,14 @@
|
|||
* Fix the generated `#to_param` method to use `omission:''` so that
|
||||
the resulting output is actually up to 20 characters, not
|
||||
effectively 17 to leave room for the default "...".
|
||||
Also call `#parameterize` before `#truncate` and make the
|
||||
`separator: /-/` to maximize the information included in the
|
||||
output.
|
||||
|
||||
Fixes #23635
|
||||
|
||||
*Rob Biedenharn*
|
||||
|
||||
* Ensure concurrent invocations of the connection reaper cannot allocate the
|
||||
same connection to two threads.
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ module ActiveRecord
|
|||
#
|
||||
# user = User.find_by(name: 'David Heinemeier Hansson')
|
||||
# user.id # => 125
|
||||
# user_path(user) # => "/users/125-david"
|
||||
# user_path(user) # => "/users/125-david-heinemeier"
|
||||
#
|
||||
# Because the generated param begins with the record's +id+, it is
|
||||
# suitable for passing to +find+. In a controller, for example:
|
||||
|
@ -100,7 +100,7 @@ module ActiveRecord
|
|||
define_method :to_param do
|
||||
if (default = super()) &&
|
||||
(result = send(method_name).to_s).present? &&
|
||||
(param = result.squish.truncate(20, separator: /\s/, omission: nil).parameterize).present?
|
||||
(param = result.squish.parameterize.truncate(20, separator: /-/, omission: '')).present?
|
||||
"#{default}-#{param}"
|
||||
else
|
||||
default
|
||||
|
|
|
@ -29,10 +29,30 @@ class IntegrationTest < ActiveRecord::TestCase
|
|||
assert_equal '4-flamboyant-software', firm.to_param
|
||||
end
|
||||
|
||||
def test_to_param_class_method_truncates_words_properly
|
||||
firm = Firm.find(4)
|
||||
firm.name << ', Inc.'
|
||||
assert_equal '4-flamboyant-software', firm.to_param
|
||||
end
|
||||
|
||||
def test_to_param_class_method_truncates_after_parameterize
|
||||
firm = Firm.find(4)
|
||||
firm.name = "Huey, Dewey, & Louie LLC"
|
||||
# 123456789T123456789v
|
||||
assert_equal '4-huey-dewey-louie-llc', firm.to_param
|
||||
end
|
||||
|
||||
def test_to_param_class_method_truncates_after_parameterize_with_hyphens
|
||||
firm = Firm.find(4)
|
||||
firm.name = "Door-to-Door Wash-n-Fold Service"
|
||||
# 123456789T123456789v
|
||||
assert_equal '4-door-to-door-wash-n', firm.to_param
|
||||
end
|
||||
|
||||
def test_to_param_class_method_truncates
|
||||
firm = Firm.find(4)
|
||||
firm.name = 'a ' * 100
|
||||
assert_equal '4-a-a-a-a-a-a-a-a-a', firm.to_param
|
||||
assert_equal '4-a-a-a-a-a-a-a-a-a-a', firm.to_param
|
||||
end
|
||||
|
||||
def test_to_param_class_method_truncates_edge_case
|
||||
|
@ -41,10 +61,16 @@ class IntegrationTest < ActiveRecord::TestCase
|
|||
assert_equal '4-david', firm.to_param
|
||||
end
|
||||
|
||||
def test_to_param_class_method_truncates_case_shown_in_doc
|
||||
firm = Firm.find(4)
|
||||
firm.name = 'David Heinemeier Hansson'
|
||||
assert_equal '4-david-heinemeier', firm.to_param
|
||||
end
|
||||
|
||||
def test_to_param_class_method_squishes
|
||||
firm = Firm.find(4)
|
||||
firm.name = "ab \n" * 100
|
||||
assert_equal '4-ab-ab-ab-ab-ab-ab', firm.to_param
|
||||
assert_equal '4-ab-ab-ab-ab-ab-ab-ab', firm.to_param
|
||||
end
|
||||
|
||||
def test_to_param_class_method_multibyte_character
|
||||
|
|
Loading…
Reference in a new issue