Skip to content

Commit

Permalink
Merge pull request #570 from sikachu/decouple_actionpack
Browse files Browse the repository at this point in the history
Make ParamsWrapper use a well-defined API and not rely on AR methods
  • Loading branch information
josevalim committed May 15, 2011
2 parents 6e581cc + d77b306 commit d043d65
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 14 deletions.
2 changes: 1 addition & 1 deletion actionpack/CHANGELOG
Expand Up @@ -17,7 +17,7 @@
class PostsController < ActionController::Base class PostsController < ActionController::Base
stream :only => :index stream :only => :index
end end

Please read the docs at `ActionController::Streaming` for more information. Please read the docs at `ActionController::Streaming` for more information.


* Added `ActionDispatch::Request.ignore_accept_header` to ignore accept headers and only consider the format given as parameter [José Valim] * Added `ActionDispatch::Request.ignore_accept_header` to ignore accept headers and only consider the format given as parameter [José Valim]
Expand Down
6 changes: 3 additions & 3 deletions actionpack/lib/action_controller/metal/params_wrapper.rb
Expand Up @@ -145,7 +145,7 @@ def _default_wrap_model #:nodoc:
begin begin
model_klass = model_name.constantize model_klass = model_name.constantize
rescue NameError, ArgumentError => e rescue NameError, ArgumentError => e
if e.message =~ /is not missing constant|uninitialized constant #{model_name}/ if e.message =~ /is not missing constant|uninitialized constant #{model_name}/
namespaces = model_name.split("::") namespaces = model_name.split("::")
namespaces.delete_at(-2) namespaces.delete_at(-2)
break if namespaces.last == model_name break if namespaces.last == model_name
Expand All @@ -163,8 +163,8 @@ def _set_wrapper_defaults(options, model=nil)


unless options[:only] || options[:except] unless options[:only] || options[:except]
model ||= _default_wrap_model model ||= _default_wrap_model
if !(model.respond_to?(:abstract_class?) && model.abstract_class?) && model.respond_to?(:column_names) if model.respond_to?(:attribute_names) && model.attribute_names.present?
options[:only] = model.column_names options[:only] = model.attribute_names
end end
end end


Expand Down
18 changes: 8 additions & 10 deletions actionpack/test/controller/params_wrapper_test.rb
Expand Up @@ -133,9 +133,8 @@ def test_nested_params
end end


def test_derived_wrapped_keys_from_matching_model def test_derived_wrapped_keys_from_matching_model
User.expects(:respond_to?).with(:abstract_class?).returns(false) User.expects(:respond_to?).with(:attribute_names).returns(true)
User.expects(:respond_to?).with(:column_names).returns(true) User.expects(:attribute_names).twice.returns(["username"])
User.expects(:column_names).returns(["username"])


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


def test_derived_wrapped_keys_from_specified_model def test_derived_wrapped_keys_from_specified_model
with_default_wrapper_options do with_default_wrapper_options do
Person.expects(:respond_to?).with(:abstract_class?).returns(false) Person.expects(:respond_to?).with(:attribute_names).returns(true)
Person.expects(:respond_to?).with(:column_names).returns(true) Person.expects(:attribute_names).twice.returns(["username"])
Person.expects(:column_names).returns(["username"])


UsersController.wrap_parameters Person UsersController.wrap_parameters Person


Expand All @@ -159,8 +157,8 @@ def test_derived_wrapped_keys_from_specified_model
end end


def test_not_wrapping_abstract_model def test_not_wrapping_abstract_model
User.expects(:respond_to?).with(:abstract_class?).returns(true) User.expects(:respond_to?).with(:attribute_names).returns(true)
User.expects(:abstract_class?).returns(true) User.expects(:attribute_names).returns([])


with_default_wrapper_options do with_default_wrapper_options do
@request.env['CONTENT_TYPE'] = 'application/json' @request.env['CONTENT_TYPE'] = 'application/json'
Expand Down Expand Up @@ -198,13 +196,13 @@ def parse
end end


class SampleOne class SampleOne
def self.column_names def self.attribute_names
["username"] ["username"]
end end
end end


class SampleTwo class SampleTwo
def self.column_names def self.attribute_names
["title"] ["title"]
end end
end end
Expand Down
2 changes: 2 additions & 0 deletions activerecord/CHANGELOG
@@ -1,5 +1,7 @@
*Rails 3.1.0 (unreleased)* *Rails 3.1.0 (unreleased)*


* 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]

* CSV Fixtures are deprecated and support will be removed in Rails 3.2.0 * CSV Fixtures are deprecated and support will be removed in Rails 3.2.0


* AR#new, AR#create, AR#create!, AR#update_attributes and AR#update_attributes! all accept a second hash as option that allows you * AR#new, AR#create, AR#create!, AR#update_attributes and AR#update_attributes! all accept a second hash as option that allows you
Expand Down
8 changes: 8 additions & 0 deletions activerecord/lib/active_record/base.rb
Expand Up @@ -767,6 +767,14 @@ def attribute_method?(attribute)
super || (table_exists? && column_names.include?(attribute.to_s.sub(/=$/, ''))) super || (table_exists? && column_names.include?(attribute.to_s.sub(/=$/, '')))
end end


def attribute_names
@attribute_names ||= if !abstract_class? && table_exists?
column_names
else
[]
end
end

# Set the lookup ancestors for ActiveModel. # Set the lookup ancestors for ActiveModel.
def lookup_ancestors #:nodoc: def lookup_ancestors #:nodoc:
klass = self klass = self
Expand Down
13 changes: 13 additions & 0 deletions activerecord/test/cases/base_test.rb
Expand Up @@ -1790,4 +1790,17 @@ def test_marshal_round_trip


assert_equal expected.attributes, actual.attributes assert_equal expected.attributes, actual.attributes
end end

def test_attribute_names
assert_equal ["id", "type", "ruby_type", "firm_id", "firm_name", "name", "client_of", "rating", "account_id"],
Company.attribute_names
end

def test_attribute_names_on_table_not_exists
assert_equal [], NonExistentTable.attribute_names
end

def test_attribtue_names_on_abstract_class
assert_equal [], AbstractCompany.attribute_names
end
end end

0 comments on commit d043d65

Please sign in to comment.