Skip to content

Commit

Permalink
Deal with global config better between AR::Base and AR::Model
Browse files Browse the repository at this point in the history
  • Loading branch information
jonleighton committed Dec 24, 2011
1 parent 8c67e70 commit ba7ec73
Show file tree
Hide file tree
Showing 12 changed files with 147 additions and 83 deletions.
1 change: 1 addition & 0 deletions activerecord/lib/active_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ module ActiveRecord

autoload :Base
autoload :Callbacks
autoload :Configuration
autoload :Core
autoload :CounterCache
autoload :DynamicMatchers
Expand Down
5 changes: 1 addition & 4 deletions activerecord/lib/active_record/attribute_methods/read.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ module Read

ATTRIBUTE_TYPES_CACHED_BY_DEFAULT = [:datetime, :timestamp, :time, :date]

included do
cattr_accessor :attribute_types_cached_by_default, :instance_writer => false
self.attribute_types_cached_by_default = ATTRIBUTE_TYPES_CACHED_BY_DEFAULT
end
Configuration.define :attribute_types_cached_by_default, ATTRIBUTE_TYPES_CACHED_BY_DEFAULT

module ClassMethods
# +cache_attributes+ allows you to declare which converted attribute values should
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ module AttributeMethods
module TimeZoneConversion
extend ActiveSupport::Concern

included do
cattr_accessor :time_zone_aware_attributes, :instance_writer => false
self.time_zone_aware_attributes = false
Configuration.define :time_zone_aware_attributes, false

included do
class_attribute :skip_time_zone_conversion_for_attributes, :instance_writer => false
self.skip_time_zone_conversion_for_attributes = []
end
Expand Down
1 change: 0 additions & 1 deletion activerecord/lib/active_record/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,6 @@ module ActiveRecord #:nodoc:
# instances in the current object space.
class Base
include ActiveRecord::Model

self.connection_handler = ConnectionAdapters::ConnectionHandler.new
end
end
36 changes: 36 additions & 0 deletions activerecord/lib/active_record/configuration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
require 'active_support/concern'

module ActiveRecord
# This module allows configuration options to be specified in a way such that
# ActiveRecord::Base and ActiveRecord::Model will have access to the same value,
# and will automatically get the appropriate readers and writers defined.
#
# In the future, we should probably move away from defining global config
# directly on ActiveRecord::Base / ActiveRecord::Model.
module Configuration #:nodoc:
extend ActiveSupport::Concern

module ClassMethods
end

def self.define(name, default = nil)
singleton_class.send(:attr_accessor, name)

[self, ClassMethods].each do |klass|
klass.class_eval <<-CODE, __FILE__, __LINE__
def #{name}
ActiveRecord::Configuration.#{name}
end
CODE
end

ClassMethods.class_eval <<-CODE, __FILE__, __LINE__
def #{name}=(val)
ActiveRecord::Configuration.#{name} = val
end
CODE

send("#{name}=", default) unless default.nil?
end
end
end
117 changes: 57 additions & 60 deletions activerecord/lib/active_record/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,67 +4,64 @@ module ActiveRecord
module Core
extend ActiveSupport::Concern

included do
##
# :singleton-method:
# Accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class,
# which is then passed on to any new database connections made and which can be retrieved on both
# a class and instance level by calling +logger+.
cattr_accessor :logger, :instance_writer => false

##
# :singleton-method:
# Contains the database configuration - as is typically stored in config/database.yml -
# as a Hash.
#
# For example, the following database.yml...
#
# development:
# adapter: sqlite3
# database: db/development.sqlite3
#
# production:
# adapter: sqlite3
# database: db/production.sqlite3
#
# ...would result in ActiveRecord::Base.configurations to look like this:
#
# {
# 'development' => {
# 'adapter' => 'sqlite3',
# 'database' => 'db/development.sqlite3'
# },
# 'production' => {
# 'adapter' => 'sqlite3',
# 'database' => 'db/production.sqlite3'
# }
# }
cattr_accessor :configurations, :instance_writer => false
self.configurations = {}

##
# :singleton-method:
# Determines whether to use Time.local (using :local) or Time.utc (using :utc) when pulling
# dates and times from the database. This is set to :local by default.
cattr_accessor :default_timezone, :instance_writer => false
self.default_timezone = :local

##
# :singleton-method:
# Specifies the format to use when dumping the database schema with Rails'
# Rakefile. If :sql, the schema is dumped as (potentially database-
# specific) SQL statements. If :ruby, the schema is dumped as an
# ActiveRecord::Schema file which can be loaded into any database that
# supports migrations. Use :ruby if you want to have different database
# adapters for, e.g., your development and test environments.
cattr_accessor :schema_format , :instance_writer => false
self.schema_format = :ruby
##
# :singleton-method:
# Accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class,
# which is then passed on to any new database connections made and which can be retrieved on both
# a class and instance level by calling +logger+.
Configuration.define :logger

##
# :singleton-method:
# Contains the database configuration - as is typically stored in config/database.yml -
# as a Hash.
#
# For example, the following database.yml...
#
# development:
# adapter: sqlite3
# database: db/development.sqlite3
#
# production:
# adapter: sqlite3
# database: db/production.sqlite3
#
# ...would result in ActiveRecord::Base.configurations to look like this:
#
# {
# 'development' => {
# 'adapter' => 'sqlite3',
# 'database' => 'db/development.sqlite3'
# },
# 'production' => {
# 'adapter' => 'sqlite3',
# 'database' => 'db/production.sqlite3'
# }
# }
Configuration.define :configurations, {}

##
# :singleton-method:
# Determines whether to use Time.local (using :local) or Time.utc (using :utc) when pulling
# dates and times from the database. This is set to :local by default.
Configuration.define :default_timezone, :local

##
# :singleton-method:
# Specifies the format to use when dumping the database schema with Rails'
# Rakefile. If :sql, the schema is dumped as (potentially database-
# specific) SQL statements. If :ruby, the schema is dumped as an
# ActiveRecord::Schema file which can be loaded into any database that
# supports migrations. Use :ruby if you want to have different database
# adapters for, e.g., your development and test environments.
Configuration.define :schema_format, :ruby

##
# :singleton-method:
# Specify whether or not to use timestamps for migration versions
Configuration.define :timestamped_migrations, true

##
# :singleton-method:
# Specify whether or not to use timestamps for migration versions
cattr_accessor :timestamped_migrations , :instance_writer => false
self.timestamped_migrations = true
included do

##
# :singleton-method:
Expand Down
5 changes: 1 addition & 4 deletions activerecord/lib/active_record/locking/optimistic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,7 @@ module Locking
module Optimistic
extend ActiveSupport::Concern

included do
cattr_accessor :lock_optimistically, :instance_writer => false
self.lock_optimistically = true
end
Configuration.define :lock_optimistically, true

def locking_enabled? #:nodoc:
self.class.locking_enabled?
Expand Down
4 changes: 3 additions & 1 deletion activerecord/lib/active_record/model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ def self.included(base)
base.class_eval do
include Tag

include Configuration

include ActiveRecord::Persistence
extend ActiveModel::Naming
extend QueryCache::ClassMethods
Expand Down Expand Up @@ -43,7 +45,7 @@ def self.included(base)

include Core

self.connection_handler = ActiveRecord::Base.connection_handler
self.connection_handler = Base.connection_handler
end
end
end
Expand Down
20 changes: 10 additions & 10 deletions activerecord/lib/active_record/model_schema.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
require 'active_support/concern'
require 'active_support/core_ext/class/attribute_accessors'

module ActiveRecord
module ModelSchema
extend ActiveSupport::Concern

included do
##
# :singleton-method:
# Accessor for the prefix type that will be prepended to every primary key column name.
# The options are :table_name and :table_name_with_underscore. If the first is specified,
# the Product class will look for "productid" instead of "id" as the primary column. If the
# latter is specified, the Product class will look for "product_id" instead of "id". Remember
# that this is a global setting for all Active Records.
cattr_accessor :primary_key_prefix_type, :instance_writer => false
self.primary_key_prefix_type = nil
##
# :singleton-method:
# Accessor for the prefix type that will be prepended to every primary key column name.
# The options are :table_name and :table_name_with_underscore. If the first is specified,
# the Product class will look for "productid" instead of "id" as the primary column. If the
# latter is specified, the Product class will look for "product_id" instead of "id". Remember
# that this is a global setting for all Active Records.
Configuration.define :primary_key_prefix_type

included do
##
# :singleton-method:
# Accessor for the name of the prefix string to prepend to every table name. So if set
Expand Down
1 change: 1 addition & 0 deletions activerecord/test/cases/attribute_methods/read_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def self.superclass; Base; end
def self.active_record_super; Base; end
def self.base_class; self; end

include ActiveRecord::Configuration
include ActiveRecord::AttributeMethods

def self.column_names
Expand Down
26 changes: 26 additions & 0 deletions activerecord/test/cases/configuration_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
require 'cases/helper'

class ConfigurationTest < ActiveRecord::TestCase
def test_configuration
@klass = Class.new do
include ActiveRecord::Configuration
end

ActiveRecord::Configuration.define :omg

ActiveRecord::Configuration.omg = "omg"

assert_equal "omg", @klass.new.omg
assert !@klass.new.respond_to?(:omg=)
assert_equal "omg", @klass.omg

@klass.omg = "wtf"

assert_equal "wtf", @klass.omg
assert_equal "wtf", @klass.new.omg
ensure
ActiveRecord::Configuration.send(:undef_method, :omg)
ActiveRecord::Configuration::ClassMethods.send(:undef_method, :omg)
ActiveRecord::Configuration::ClassMethods.send(:undef_method, :omg=)
end
end
9 changes: 9 additions & 0 deletions activerecord/test/cases/inclusion_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,13 @@ def test_adapter_connection
def test_connection_handler
assert_equal ActiveRecord::Base.connection_handler, @klass.connection_handler
end

def test_mirrored_configuration
ActiveRecord::Base.time_zone_aware_attributes = true
assert @klass.time_zone_aware_attributes
ActiveRecord::Base.time_zone_aware_attributes = false
assert !@klass.time_zone_aware_attributes
ensure
ActiveRecord::Base.time_zone_aware_attributes = false
end
end

0 comments on commit ba7ec73

Please sign in to comment.