From 62fd1d3716b4b5fd1d91cdcc77003efe80fc5a7e Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Thu, 30 Jul 2009 17:49:14 -0500 Subject: Start separating primary key concerns --- activerecord/lib/active_record.rb | 1 + .../lib/active_record/attribute_methods.rb | 30 ++++++++++ .../active_record/attribute_methods/primary_key.rb | 44 +++++++++++++++ activerecord/lib/active_record/base.rb | 66 +--------------------- 4 files changed, 76 insertions(+), 65 deletions(-) create mode 100644 activerecord/lib/active_record/attribute_methods/primary_key.rb diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb index b2c1c9c024..5e9ce0600a 100644 --- a/activerecord/lib/active_record.rb +++ b/activerecord/lib/active_record.rb @@ -73,6 +73,7 @@ module ActiveRecord module AttributeMethods autoload :BeforeTypeCast, 'active_record/attribute_methods/before_type_cast' autoload :Dirty, 'active_record/attribute_methods/dirty' + autoload :PrimaryKey, 'active_record/attribute_methods/primary_key' autoload :Query, 'active_record/attribute_methods/query' autoload :Read, 'active_record/attribute_methods/read' autoload :TimeZoneConversion, 'active_record/attribute_methods/time_zone_conversion' diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb index 0d444f0239..5cb536af1f 100644 --- a/activerecord/lib/active_record/attribute_methods.rb +++ b/activerecord/lib/active_record/attribute_methods.rb @@ -39,6 +39,36 @@ module ActiveRecord undefine_attribute_methods end + # Defines an "attribute" method (like +inheritance_column+ or + # +table_name+). A new (class) method will be created with the + # given name. If a value is specified, the new method will + # return that value (as a string). Otherwise, the given block + # will be used to compute the value of the method. + # + # The original method will be aliased, with the new name being + # prefixed with "original_". This allows the new method to + # access the original value. + # + # Example: + # + # class A < ActiveRecord::Base + # define_attr_method :primary_key, "sysid" + # define_attr_method( :inheritance_column ) do + # original_inheritance_column + "_id" + # end + # end + def define_attr_method(name, value=nil, &block) + sing = metaclass + sing.send :alias_method, "original_#{name}", name + if block_given? + sing.send :define_method, name, &block + else + # use eval instead of a block to work around a memory leak in dev + # mode in fcgi + sing.class_eval "def #{name}; #{value.to_s.inspect}; end" + end + end + # Returns MatchData if method_name is an attribute method. def match_attribute_method?(method_name) rebuild_attribute_method_regexp unless defined?(@@attribute_method_regexp) && @@attribute_method_regexp diff --git a/activerecord/lib/active_record/attribute_methods/primary_key.rb b/activerecord/lib/active_record/attribute_methods/primary_key.rb new file mode 100644 index 0000000000..365fdeb55a --- /dev/null +++ b/activerecord/lib/active_record/attribute_methods/primary_key.rb @@ -0,0 +1,44 @@ +module ActiveRecord + module AttributeMethods + module PrimaryKey + extend ActiveSupport::Concern + + module ClassMethods + # Defines the primary key field -- can be overridden in subclasses. Overwriting will negate any effect of the + # primary_key_prefix_type setting, though. + def primary_key + reset_primary_key + end + + def reset_primary_key #:nodoc: + key = get_primary_key(base_class.name) + set_primary_key(key) + key + end + + def get_primary_key(base_name) #:nodoc: + key = 'id' + case primary_key_prefix_type + when :table_name + key = base_name.to_s.foreign_key(false) + when :table_name_with_underscore + key = base_name.to_s.foreign_key + end + key + end + + # Sets the name of the primary key column to use to the given value, + # or (if the value is nil or false) to the value returned by the given + # block. + # + # class Project < ActiveRecord::Base + # set_primary_key "sysid" + # end + def set_primary_key(value = nil, &block) + define_attr_method :primary_key, value, &block + end + alias :primary_key= :set_primary_key + end + end + end +end diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 7fabb5bfc6..ce93ea8eee 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1225,29 +1225,6 @@ module ActiveRecord #:nodoc: name end - # Defines the primary key field -- can be overridden in subclasses. Overwriting will negate any effect of the - # primary_key_prefix_type setting, though. - def primary_key - reset_primary_key - end - - def reset_primary_key #:nodoc: - key = get_primary_key(base_class.name) - set_primary_key(key) - key - end - - def get_primary_key(base_name) #:nodoc: - key = 'id' - case primary_key_prefix_type - when :table_name - key = base_name.to_s.foreign_key(false) - when :table_name_with_underscore - key = base_name.to_s.foreign_key - end - key - end - # Defines the column name for use with single table inheritance # -- can be set in subclasses like so: self.inheritance_column = "type_id" def inheritance_column @@ -1277,18 +1254,6 @@ module ActiveRecord #:nodoc: end alias :table_name= :set_table_name - # Sets the name of the primary key column to use to the given value, - # or (if the value is nil or false) to the value returned by the given - # block. - # - # class Project < ActiveRecord::Base - # set_primary_key "sysid" - # end - def set_primary_key(value = nil, &block) - define_attr_method :primary_key, value, &block - end - alias :primary_key= :set_primary_key - # Sets the name of the inheritance column to use to the given value, # or (if the value # is nil or false) to the value returned by the # given block. @@ -2077,36 +2042,6 @@ module ActiveRecord #:nodoc: end end - # Defines an "attribute" method (like +inheritance_column+ or - # +table_name+). A new (class) method will be created with the - # given name. If a value is specified, the new method will - # return that value (as a string). Otherwise, the given block - # will be used to compute the value of the method. - # - # The original method will be aliased, with the new name being - # prefixed with "original_". This allows the new method to - # access the original value. - # - # Example: - # - # class A < ActiveRecord::Base - # define_attr_method :primary_key, "sysid" - # define_attr_method( :inheritance_column ) do - # original_inheritance_column + "_id" - # end - # end - def define_attr_method(name, value=nil, &block) - sing = metaclass - sing.send :alias_method, "original_#{name}", name - if block_given? - sing.send :define_method, name, &block - else - # use eval instead of a block to work around a memory leak in dev - # mode in fcgi - sing.class_eval "def #{name}; #{value.to_s.inspect}; end" - end - end - protected # Scope parameters to method calls within the block. Takes a hash of method_name => parameters hash. # method_name may be :find or :create. :find parameters may include the :conditions, :joins, @@ -3184,6 +3119,7 @@ module ActiveRecord #:nodoc: include Locking::Optimistic, Locking::Pessimistic include AttributeMethods include AttributeMethods::Read, AttributeMethods::Write, AttributeMethods::BeforeTypeCast, AttributeMethods::Query + include AttributeMethods::PrimaryKey include AttributeMethods::TimeZoneConversion include AttributeMethods::Dirty include Callbacks, ActiveModel::Observing, Timestamp -- cgit v1.2.3