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 *
122
223Please 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)
3636
3737 alias attributes = assign_attributes
3838
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+
3960 private
4061 def _assign_attributes ( attributes )
4162 attributes . each do |k , v |
@@ -50,7 +71,7 @@ def _assign_attribute(k, v)
5071 if respond_to? ( setter )
5172 raise
5273 else
53- raise UnknownAttributeError . new ( self , k . to_s )
74+ attribute_writer_missing ( k . to_s , v )
5475 end
5576 end
5677 end
Original file line number Diff line number Diff line change @@ -86,6 +86,19 @@ def dup
8686 assert_equal "hz" , error . attribute
8787 end
8888
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+
89102 test "assign private attribute" do
90103 model = Model . new
91104 assert_raises ( ActiveModel ::UnknownAttributeError ) do
You can’t perform that action at this time.
0 commit comments