Skip to content

Commit 37342a3

Browse files
committed
Allow redefining to_param delimiter using param_delimiter
This commit allows customizing the delimiter used by `to_param` when `to_key` returns multiple value. This unblocks supporting more varieties of composite primary key types in Active Record.
1 parent dd6d931 commit 37342a3

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

activemodel/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
* Add `ActiveModel::Conversion.param_delimiter` to configure delimiter being used in `to_param`
2+
3+
*Nikita Vasilevsky*
4+
15
* `undefine_attribute_methods` undefines alias attribute methods along with attribute methods.
26

37
*Nikita Vasilevsky*

activemodel/lib/active_model/conversion.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ module ActiveModel
2424
module Conversion
2525
extend ActiveSupport::Concern
2626

27+
included do
28+
##
29+
# :singleton-method:
30+
#
31+
# Accepts a string that will be used as a delimiter of object's key values in the `to_param` method.
32+
class_attribute :param_delimiter, instance_reader: false, default: "-"
33+
end
34+
2735
# If your object is already designed to implement all of the \Active \Model
2836
# you can use the default <tt>:to_model</tt> implementation, which simply
2937
# returns +self+.
@@ -80,7 +88,7 @@ def to_key
8088
# person = Person.new(1)
8189
# person.to_param # => "1"
8290
def to_param
83-
(persisted? && key = to_key) ? key.join("-") : nil
91+
(persisted? && key = to_key) ? key.join(self.class.param_delimiter) : nil
8492
end
8593

8694
# Returns a +string+ identifying the path associated with the object.

activemodel/test/cases/conversion_test.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,25 @@ def persisted?
5353
test "to_partial_path handles namespaced models" do
5454
assert_equal "helicopter/comanches/comanche", Helicopter::Comanche.new.to_partial_path
5555
end
56+
57+
test "#to_param_delimiter allows redefining the delimiter used in #to_param" do
58+
old_delimiter = Contact.param_delimiter
59+
Contact.param_delimiter = "_"
60+
assert_equal("abc_xyz", Contact.new(id: ["abc", "xyz"]).to_param)
61+
ensure
62+
Contact.param_delimiter = old_delimiter
63+
end
64+
65+
test "#to_param_delimiter is defined per class" do
66+
old_contact_delimiter = Contact.param_delimiter
67+
custom_contract = Class.new(Contact)
68+
69+
Contact.param_delimiter = "_"
70+
custom_contract.param_delimiter = ";"
71+
72+
assert_equal("abc_xyz", Contact.new(id: ["abc", "xyz"]).to_param)
73+
assert_equal("abc;xyz", custom_contract.new(id: ["abc", "xyz"]).to_param)
74+
ensure
75+
Contact.param_delimiter = old_contact_delimiter
76+
end
5677
end

0 commit comments

Comments
 (0)