File tree Expand file tree Collapse file tree 3 files changed +56
-1
lines changed Expand file tree Collapse file tree 3 files changed +56
-1
lines changed Original file line number Diff line number Diff line change
1
+ * Introduce ` ActiveModel::AttributeAssignment#attribute_writer_missing `
2
+
3
+ Provide instances with an opportunity to gracefully handle assigning to an
4
+ unknown attribute:
5
+
6
+ ``` ruby
7
+ class Rectangle
8
+ include ActiveModel ::AttributeAssignment
9
+
10
+ attr_accessor :length , :width
11
+
12
+ def attribute_writer_missing (name , value )
13
+ Rails .logger.warn " Tried to assign to unknown attribute #{ name } "
14
+ end
15
+ end
16
+
17
+ rectangle = Rectangle .new
18
+ rectangle.assign_attributes(height: 10 ) # => Logs "Tried to assign to unknown attribute 'height'"
19
+ ```
20
+
21
+ * Sean Doyle *
1
22
2
23
Please check [7 - 2 - stable](https: // github.com/ rails/ rails/ blob/ 7 - 2 - stable/ activemodel/ CHANGELOG .md) for previous changes.
Original file line number Diff line number Diff line change @@ -36,6 +36,27 @@ def assign_attributes(new_attributes)
36
36
37
37
alias attributes = assign_attributes
38
38
39
+ # Like `BasicObject#method_missing`, `#attribute_writer_missing` is invoked
40
+ # when `#assign_attributes` is passed an unknown attribute name.
41
+ #
42
+ # By default, `#attribute_writer_missing` raises an UnknownAttributeError.
43
+ #
44
+ # class Rectangle
45
+ # include ActiveModel::AttributeAssignment
46
+ #
47
+ # attr_accessor :length, :width
48
+ #
49
+ # def attribute_writer_missing(name, value)
50
+ # Rails.logger.warn "Tried to assign to unknown attribute #{name}"
51
+ # end
52
+ # end
53
+ #
54
+ # rectangle = Rectangle.new
55
+ # rectangle.assign_attributes(height: 10) # => Logs "Tried to assign to unknown attribute 'height'"
56
+ def attribute_writer_missing ( name , value )
57
+ raise UnknownAttributeError . new ( self , name )
58
+ end
59
+
39
60
private
40
61
def _assign_attributes ( attributes )
41
62
attributes . each do |k , v |
@@ -50,7 +71,7 @@ def _assign_attribute(k, v)
50
71
if respond_to? ( setter )
51
72
raise
52
73
else
53
- raise UnknownAttributeError . new ( self , k . to_s )
74
+ attribute_writer_missing ( k . to_s , v )
54
75
end
55
76
end
56
77
end
Original file line number Diff line number Diff line change @@ -86,6 +86,19 @@ def dup
86
86
assert_equal "hz" , error . attribute
87
87
end
88
88
89
+ test "assign non-existing attribute by overriding #attribute_writer_missing" do
90
+ model_class = Class . new ( Model ) do
91
+ attr_accessor :assigned_attributes
92
+
93
+ def attribute_writer_missing ( name , value ) = @assigned_attributes [ name ] = value
94
+ end
95
+ model = model_class . new ( assigned_attributes : { } )
96
+
97
+ model . assign_attributes unknown : "attribute"
98
+
99
+ assert_equal ( { "unknown" => "attribute" } , model . assigned_attributes )
100
+ end
101
+
89
102
test "assign private attribute" do
90
103
model = Model . new
91
104
assert_raises ( ActiveModel ::UnknownAttributeError ) do
You can’t perform that action at this time.
0 commit comments