Browse files

Define attribute query methods to avoid method_missing calls. Closes #…

…3677.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3679 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
1 parent 660952e commit 1a06d324df43bfb3287293934f0ef34a7c790a34 @jeremy jeremy committed Feb 27, 2006
Showing with 13 additions and 7 deletions.
  1. +2 −0 activerecord/CHANGELOG
  2. +8 −5 activerecord/lib/active_record/base.rb
  3. +3 −2 activerecord/test/base_test.rb
View
2 activerecord/CHANGELOG
@@ -1,5 +1,7 @@
*SVN*
+* Define attribute query methods to avoid method_missing calls. #3677 [jonathan@bluewire.net.nz]
+
* ActiveRecord::Base.remove_connection explicitly closes database connections and doesn't corrupt the connection cache. Introducing the disconnect! instance method for the PostgreSQL, MySQL, and SQL Server adapters; implementations for the others are welcome. #3591 [Simon Stapleton, Tom Ward]
* Added support for nested scopes #3407 [anna@wota.jp]. Examples:
View
13 activerecord/lib/active_record/base.rb
@@ -1544,19 +1544,19 @@ def ensure_proper_type
# table with a master_id foreign key can instantiate master through Client#master.
def method_missing(method_id, *args, &block)
method_name = method_id.to_s
- if @attributes.include?(method_name)
+ if @attributes.include?(method_name) or
+ (md = /\?$/.match(method_name) and
+ @attributes.include?(method_name = md.pre_match))
define_read_methods if self.class.read_methods.empty? && self.class.generate_read_methods
- read_attribute(method_name)
+ md ? query_attribute(method_name) : read_attribute(method_name)
elsif self.class.primary_key.to_s == method_name
id
- elsif md = /(=|\?|_before_type_cast)$/.match(method_name)
+ elsif md = /(=|_before_type_cast)$/.match(method_name)
attribute_name, method_type = md.pre_match, md.to_s
if @attributes.include?(attribute_name)
case method_type
when '='
write_attribute(attribute_name, args.first)
- when '?'
- query_attribute(attribute_name)
when '_before_type_cast'
read_attribute_before_type_cast(attribute_name)
end
@@ -1610,12 +1610,15 @@ def define_read_method(symbol, attr_name, column)
unless attr_name.to_s == self.class.primary_key.to_s
access_code = access_code.insert(0, "raise NoMethodError, 'missing attribute: #{attr_name}', caller unless @attributes.has_key?('#{attr_name}'); ")
self.class.read_methods << attr_name
+ self.class.read_methods << "#{attr_name}?"
end
begin
self.class.class_eval("def #{symbol}; #{access_code}; end")
+ self.class.class_eval("def #{symbol}?; query_attribute('#{attr_name}'); end")
rescue SyntaxError => err
self.class.read_methods.delete(attr_name)
+ self.class.read_methods.delete("#{attr_name}?")
if logger
logger.warn "Exception occured during reader method compilation."
logger.warn "Maybe #{attr_name} is not a valid Ruby identifier?"
View
5 activerecord/test/base_test.rb
@@ -1163,7 +1163,8 @@ def test_base_class
private
def assert_readers(model, exceptions)
- expected_readers = model.column_names - (model.serialized_attributes.keys + exceptions + ['id'])
- assert_equal expected_readers.sort, model.read_methods.to_a.sort
+ expected_readers = Set.new(model.column_names - (model.serialized_attributes.keys + exceptions + ['id']))
+ expected_readers += expected_readers.map { |col| "#{col}?" }
+ assert_equal expected_readers, model.read_methods
end
end

0 comments on commit 1a06d32

Please sign in to comment.