Skip to content

Commit

Permalink
Add the ability to specify table_name_prefix on individual modules
Browse files Browse the repository at this point in the history
[rails#4032 state:committed]

Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
  • Loading branch information
pixeltrix authored and jeremy committed Mar 29, 2010
1 parent bc2af91 commit 03d5d0b
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 1 deletion.
2 changes: 2 additions & 0 deletions activerecord/CHANGELOG
@@ -1,5 +1,7 @@
*2.3.6 (pending)*

* To prefix the table names of all models in a module, define self.table_name_prefix on the module. #4032 [Andrew White]

* Association inverses for belongs_to, has_one, and has_many. Optimization to reduce database queries. #3533 [Murray Steele]

# post.comments sets each comment's post without needing to :include
Expand Down
9 changes: 8 additions & 1 deletion activerecord/lib/active_record/base.rb
Expand Up @@ -461,6 +461,9 @@ def self.reset_subclasses #:nodoc:
# Accessor for the name of the prefix string to prepend to every table name. So if set to "basecamp_", all
# table names will be named like "basecamp_projects", "basecamp_people", etc. This is a convenient way of creating a namespace
# for tables in a shared database. By default, the prefix is the empty string.
#
# If you are organising your models within modules you can add a prefix to the models within a namespace by defining
# a singleton method in the parent module called table_name_prefix which returns your chosen prefix.
cattr_accessor :table_name_prefix, :instance_writer => false
@@table_name_prefix = ""

Expand Down Expand Up @@ -1171,7 +1174,7 @@ def reset_table_name #:nodoc:
contained = contained.singularize if parent.pluralize_table_names
contained << '_'
end
name = "#{table_name_prefix}#{contained}#{undecorated_table_name(base.name)}#{table_name_suffix}"
name = "#{full_table_name_prefix}#{contained}#{undecorated_table_name(base.name)}#{table_name_suffix}"
end

set_table_name(name)
Expand Down Expand Up @@ -1201,6 +1204,10 @@ def get_primary_key(base_name) #:nodoc:
key
end

def full_table_name_prefix #:nodoc:
(parents.detect{ |p| p.respond_to?(:table_name_prefix) } || self).table_name_prefix
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
Expand Down
28 changes: 28 additions & 0 deletions activerecord/test/cases/modules_test.rb
Expand Up @@ -78,4 +78,32 @@ def test_eager_loading_in_modules
end
end
end

def test_module_table_name_prefix
assert_equal 'prefixed_companies', MyApplication::Business::Prefixed::Company.table_name, 'inferred table_name for ActiveRecord model in module with table_name_prefix'
assert_equal 'prefixed_companies', MyApplication::Business::Prefixed::Nested::Company.table_name, 'table_name for ActiveRecord model in nested module with a parent table_name_prefix'
assert_equal 'companies', MyApplication::Business::Prefixed::Firm.table_name, 'explicit table_name for ActiveRecord model in module with table_name_prefix should not be prefixed'
end

def test_module_table_name_prefix_with_global_prefix
classes = [ MyApplication::Business::Company,
MyApplication::Business::Firm,
MyApplication::Business::Client,
MyApplication::Business::Client::Contact,
MyApplication::Business::Developer,
MyApplication::Business::Project,
MyApplication::Business::Prefixed::Company,
MyApplication::Business::Prefixed::Nested::Company,
MyApplication::Billing::Account ]

ActiveRecord::Base.table_name_prefix = 'global_'
classes.each(&:reset_table_name)
assert_equal 'global_companies', MyApplication::Business::Company.table_name, 'inferred table_name for ActiveRecord model in module without table_name_prefix'
assert_equal 'prefixed_companies', MyApplication::Business::Prefixed::Company.table_name, 'inferred table_name for ActiveRecord model in module with table_name_prefix'
assert_equal 'prefixed_companies', MyApplication::Business::Prefixed::Nested::Company.table_name, 'table_name for ActiveRecord model in nested module with a parent table_name_prefix'
assert_equal 'companies', MyApplication::Business::Prefixed::Firm.table_name, 'explicit table_name for ActiveRecord model in module with table_name_prefix should not be prefixed'
ensure
ActiveRecord::Base.table_name_prefix = ''
classes.each(&:reset_table_name)
end
end
17 changes: 17 additions & 0 deletions activerecord/test/models/company_in_module.rb
Expand Up @@ -30,6 +30,23 @@ class Project < ActiveRecord::Base
has_and_belongs_to_many :developers
end

module Prefixed
def self.table_name_prefix
'prefixed_'
end

class Company < ActiveRecord::Base
end

class Firm < Company
self.table_name = 'companies'
end

module Nested
class Company < ActiveRecord::Base
end
end
end
end

module Billing
Expand Down

0 comments on commit 03d5d0b

Please sign in to comment.