Skip to content

Commit d043d65

Browse files
committed
Merge pull request rails#570 from sikachu/decouple_actionpack
Make ParamsWrapper use a well-defined API and not rely on AR methods
2 parents 6e581cc + d77b306 commit d043d65

File tree

6 files changed

+35
-14
lines changed

6 files changed

+35
-14
lines changed

actionpack/CHANGELOG

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
class PostsController < ActionController::Base
1818
stream :only => :index
1919
end
20-
20+
2121
Please read the docs at `ActionController::Streaming` for more information.
2222

2323
* Added `ActionDispatch::Request.ignore_accept_header` to ignore accept headers and only consider the format given as parameter [José Valim]

actionpack/lib/action_controller/metal/params_wrapper.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ def _default_wrap_model #:nodoc:
145145
begin
146146
model_klass = model_name.constantize
147147
rescue NameError, ArgumentError => e
148-
if e.message =~ /is not missing constant|uninitialized constant #{model_name}/
148+
if e.message =~ /is not missing constant|uninitialized constant #{model_name}/
149149
namespaces = model_name.split("::")
150150
namespaces.delete_at(-2)
151151
break if namespaces.last == model_name
@@ -163,8 +163,8 @@ def _set_wrapper_defaults(options, model=nil)
163163

164164
unless options[:only] || options[:except]
165165
model ||= _default_wrap_model
166-
if !(model.respond_to?(:abstract_class?) && model.abstract_class?) && model.respond_to?(:column_names)
167-
options[:only] = model.column_names
166+
if model.respond_to?(:attribute_names) && model.attribute_names.present?
167+
options[:only] = model.attribute_names
168168
end
169169
end
170170

actionpack/test/controller/params_wrapper_test.rb

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,8 @@ def test_nested_params
133133
end
134134

135135
def test_derived_wrapped_keys_from_matching_model
136-
User.expects(:respond_to?).with(:abstract_class?).returns(false)
137-
User.expects(:respond_to?).with(:column_names).returns(true)
138-
User.expects(:column_names).returns(["username"])
136+
User.expects(:respond_to?).with(:attribute_names).returns(true)
137+
User.expects(:attribute_names).twice.returns(["username"])
139138

140139
with_default_wrapper_options do
141140
@request.env['CONTENT_TYPE'] = 'application/json'
@@ -146,9 +145,8 @@ def test_derived_wrapped_keys_from_matching_model
146145

147146
def test_derived_wrapped_keys_from_specified_model
148147
with_default_wrapper_options do
149-
Person.expects(:respond_to?).with(:abstract_class?).returns(false)
150-
Person.expects(:respond_to?).with(:column_names).returns(true)
151-
Person.expects(:column_names).returns(["username"])
148+
Person.expects(:respond_to?).with(:attribute_names).returns(true)
149+
Person.expects(:attribute_names).twice.returns(["username"])
152150

153151
UsersController.wrap_parameters Person
154152

@@ -159,8 +157,8 @@ def test_derived_wrapped_keys_from_specified_model
159157
end
160158

161159
def test_not_wrapping_abstract_model
162-
User.expects(:respond_to?).with(:abstract_class?).returns(true)
163-
User.expects(:abstract_class?).returns(true)
160+
User.expects(:respond_to?).with(:attribute_names).returns(true)
161+
User.expects(:attribute_names).returns([])
164162

165163
with_default_wrapper_options do
166164
@request.env['CONTENT_TYPE'] = 'application/json'
@@ -198,13 +196,13 @@ def parse
198196
end
199197

200198
class SampleOne
201-
def self.column_names
199+
def self.attribute_names
202200
["username"]
203201
end
204202
end
205203

206204
class SampleTwo
207-
def self.column_names
205+
def self.attribute_names
208206
["title"]
209207
end
210208
end

activerecord/CHANGELOG

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
*Rails 3.1.0 (unreleased)*
22

3+
* Add ActiveRecord::Base.attribute_names to return a list of attribute names. This will return an empty array if the model is abstract or table does not exists. [Prem Sichanugrist]
4+
35
* CSV Fixtures are deprecated and support will be removed in Rails 3.2.0
46

57
* AR#new, AR#create, AR#create!, AR#update_attributes and AR#update_attributes! all accept a second hash as option that allows you

activerecord/lib/active_record/base.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,14 @@ def attribute_method?(attribute)
767767
super || (table_exists? && column_names.include?(attribute.to_s.sub(/=$/, '')))
768768
end
769769

770+
def attribute_names
771+
@attribute_names ||= if !abstract_class? && table_exists?
772+
column_names
773+
else
774+
[]
775+
end
776+
end
777+
770778
# Set the lookup ancestors for ActiveModel.
771779
def lookup_ancestors #:nodoc:
772780
klass = self

activerecord/test/cases/base_test.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1790,4 +1790,17 @@ def test_marshal_round_trip
17901790

17911791
assert_equal expected.attributes, actual.attributes
17921792
end
1793+
1794+
def test_attribute_names
1795+
assert_equal ["id", "type", "ruby_type", "firm_id", "firm_name", "name", "client_of", "rating", "account_id"],
1796+
Company.attribute_names
1797+
end
1798+
1799+
def test_attribute_names_on_table_not_exists
1800+
assert_equal [], NonExistentTable.attribute_names
1801+
end
1802+
1803+
def test_attribtue_names_on_abstract_class
1804+
assert_equal [], AbstractCompany.attribute_names
1805+
end
17931806
end

0 commit comments

Comments
 (0)