diff --git a/actionpack/test/activerecord/polymorphic_routes_test.rb b/actionpack/test/activerecord/polymorphic_routes_test.rb index fc829aa6b4a70..90e7f4ae5965e 100644 --- a/actionpack/test/activerecord/polymorphic_routes_test.rb +++ b/actionpack/test/activerecord/polymorphic_routes_test.rb @@ -2,36 +2,36 @@ require 'fixtures/project' class Task < ActiveRecord::Base - set_table_name 'projects' + self.table_name = 'projects' end class Step < ActiveRecord::Base - set_table_name 'projects' + self.table_name = 'projects' end class Bid < ActiveRecord::Base - set_table_name 'projects' + self.table_name = 'projects' end class Tax < ActiveRecord::Base - set_table_name 'projects' + self.table_name = 'projects' end class Fax < ActiveRecord::Base - set_table_name 'projects' + self.table_name = 'projects' end class Series < ActiveRecord::Base - set_table_name 'projects' + self.table_name = 'projects' end module Blog class Post < ActiveRecord::Base - set_table_name 'projects' + self.table_name = 'projects' end class Blog < ActiveRecord::Base - set_table_name 'projects' + self.table_name = 'projects' end def self.use_relative_model_naming? diff --git a/actionpack/test/fixtures/developer.rb b/actionpack/test/fixtures/developer.rb index c70eda34c6d38..dd14548facc1b 100644 --- a/actionpack/test/fixtures/developer.rb +++ b/actionpack/test/fixtures/developer.rb @@ -5,5 +5,5 @@ class Developer < ActiveRecord::Base end class DeVeLoPeR < ActiveRecord::Base - set_table_name "developers" + self.table_name = "developers" end diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 6fbcfb4c14789..2d15b04334488 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,5 +1,21 @@ ## Rails 3.2.0 (unreleased) ## +* Deprecated `set_table_name`. Use `self.table_name=` instead, or define your own + `self.table_name` method: + + class Project < ActiveRecord::Base + self.table_name = "project" + end + + class Post < ActiveRecord::Base + def self.table_name + "special_" + super + end + end + Post.table_name # => "special_posts" + + *Jon Leighton* + * Generated association methods are created within a separate module to allow overriding and composition using `super`. For a class named `MyModel`, the module is named `MyModel::GeneratedFeatureMethods`. It is included into the model class immediately after diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index e1908312b8260..bccf1b9b77f31 100644 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -23,6 +23,7 @@ require 'active_support/core_ext/module/introspection' require 'active_support/core_ext/object/duplicable' require 'active_support/core_ext/object/blank' +require 'active_support/deprecation' require 'arel' require 'active_record/errors' require 'active_record/log_subscriber' @@ -624,14 +625,61 @@ def serialize(attr_name, class_name = Object) # the table name guess for an Invoice class becomes "myapp_invoices". # Invoice::Lineitem becomes "myapp_invoice_lineitems". # - # You can also overwrite this class method to allow for unguessable - # links, such as a Mouse class with a link to a "mice" table. Example: + # You can also set your own table name explicitly: # # class Mouse < ActiveRecord::Base - # set_table_name "mice" + # self.table_name = "mice" # end + # + # Alternatively, you can override the table_name method to define your + # own computation. (Possibly using super to manipulate the default + # table name.) Example: + # + # class Post < ActiveRecord::Base + # def self.table_name + # "special_" + super + # end + # end + # Post.table_name # => "special_posts" def table_name - reset_table_name + reset_table_name unless defined?(@table_name) + @table_name + end + + # Sets the table name explicitly. Example: + # + # class Project < ActiveRecord::Base + # self.table_name = "project" + # end + # + # You can also just define your own self.table_name method; see + # the documentation for ActiveRecord::Base#table_name. + def table_name=(value) + @quoted_table_name = nil + @arel_table = nil + @table_name = value + @relation = Relation.new(self, arel_table) + end + + def set_table_name(value = nil, &block) #:nodoc: + if block + ActiveSupport::Deprecation.warn( + "Calling set_table_name is deprecated. If you need to lazily evaluate " \ + "the table name, define your own `self.table_name` class method. You can use `super` " \ + "to get the default table name where you would have called `original_table_name`." + ) + + @quoted_table_name = nil + define_attr_method :table_name, value, &block + @arel_table = nil + @relation = Relation.new(self, arel_table) + else + ActiveSupport::Deprecation.warn( + "Calling set_table_name is deprecated. Please use `self.table_name = 'the_name'` instead." + ) + + self.table_name = value + end end # Returns a quoted version of the table name, used to construct SQL statements. @@ -641,9 +689,13 @@ def quoted_table_name # Computes the table name, (re)sets it internally, and returns it. def reset_table_name #:nodoc: - return if abstract_class? - - self.table_name = compute_table_name + if superclass.abstract_class? + self.table_name = superclass.table_name || compute_table_name + elsif abstract_class? + self.table_name = superclass == Base ? nil : superclass.table_name + else + self.table_name = compute_table_name + end end def full_table_name_prefix #:nodoc: @@ -668,21 +720,6 @@ def reset_sequence_name #:nodoc: default end - # Sets the table name. If the value is nil or false then the value returned by the given - # block is used. - # - # class Project < ActiveRecord::Base - # set_table_name "project" - # end - def set_table_name(value = nil, &block) - @quoted_table_name = nil - define_attr_method :table_name, value, &block - @arel_table = nil - - @relation = Relation.new(self, arel_table) - end - alias :table_name= :set_table_name - # 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. diff --git a/activerecord/test/cases/adapters/mysql/schema_test.rb b/activerecord/test/cases/adapters/mysql/schema_test.rb index 1aa034ed53987..29f885c6e731a 100644 --- a/activerecord/test/cases/adapters/mysql/schema_test.rb +++ b/activerecord/test/cases/adapters/mysql/schema_test.rb @@ -14,7 +14,7 @@ def setup @db_name = db @omgpost = Class.new(ActiveRecord::Base) do - set_table_name "#{db}.#{table}" + self.table_name = "#{db}.#{table}" def self.name; 'Post'; end end end diff --git a/activerecord/test/cases/adapters/mysql2/schema_test.rb b/activerecord/test/cases/adapters/mysql2/schema_test.rb index 49514e15391fe..d5676bc522577 100644 --- a/activerecord/test/cases/adapters/mysql2/schema_test.rb +++ b/activerecord/test/cases/adapters/mysql2/schema_test.rb @@ -14,7 +14,7 @@ def setup @db_name = db @omgpost = Class.new(ActiveRecord::Base) do - set_table_name "#{db}.#{table}" + self.table_name = "#{db}.#{table}" def self.name; 'Post'; end end end diff --git a/activerecord/test/cases/adapters/postgresql/schema_test.rb b/activerecord/test/cases/adapters/postgresql/schema_test.rb index 467e5d7b8618d..d08f0b324d54d 100644 --- a/activerecord/test/cases/adapters/postgresql/schema_test.rb +++ b/activerecord/test/cases/adapters/postgresql/schema_test.rb @@ -26,23 +26,23 @@ class SchemaTest < ActiveRecord::TestCase PK_TABLE_NAME = 'table_with_pk' class Thing1 < ActiveRecord::Base - set_table_name "test_schema.things" + self.table_name = "test_schema.things" end class Thing2 < ActiveRecord::Base - set_table_name "test_schema2.things" + self.table_name = "test_schema2.things" end class Thing3 < ActiveRecord::Base - set_table_name 'test_schema."things.table"' + self.table_name = 'test_schema."things.table"' end class Thing4 < ActiveRecord::Base - set_table_name 'test_schema."Things"' + self.table_name = 'test_schema."Things"' end class Thing5 < ActiveRecord::Base - set_table_name 'things' + self.table_name = 'things' end def setup diff --git a/activerecord/test/cases/adapters/postgresql/view_test.rb b/activerecord/test/cases/adapters/postgresql/view_test.rb index 303ba9245a53b..66e07b71a064d 100644 --- a/activerecord/test/cases/adapters/postgresql/view_test.rb +++ b/activerecord/test/cases/adapters/postgresql/view_test.rb @@ -14,7 +14,7 @@ class ViewTest < ActiveRecord::TestCase ] class ThingView < ActiveRecord::Base - set_table_name 'test_schema.view_things' + self.table_name = 'test_schema.view_things' end def setup diff --git a/activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb b/activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb index d75791cab98c1..7965bb404c7b1 100644 --- a/activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb +++ b/activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb @@ -4,7 +4,7 @@ module Namespaced class Post < ActiveRecord::Base - set_table_name 'posts' + self.table_name = 'posts' has_one :tagging, :as => :taggable, :class_name => 'Tagging' end end diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb index 32a33894220bb..b49510b2020a5 100644 --- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb @@ -23,7 +23,7 @@ require 'active_support/core_ext/string/conversions' class ProjectWithAfterCreateHook < ActiveRecord::Base - set_table_name 'projects' + self.table_name = 'projects' has_and_belongs_to_many :developers, :class_name => "DeveloperForProjectWithAfterCreateHook", :join_table => "developers_projects", @@ -39,7 +39,7 @@ def add_david end class DeveloperForProjectWithAfterCreateHook < ActiveRecord::Base - set_table_name 'developers' + self.table_name = 'developers' has_and_belongs_to_many :projects, :class_name => "ProjectWithAfterCreateHook", :join_table => "developers_projects", @@ -48,7 +48,7 @@ class DeveloperForProjectWithAfterCreateHook < ActiveRecord::Base end class ProjectWithSymbolsForKeys < ActiveRecord::Base - set_table_name 'projects' + self.table_name = 'projects' has_and_belongs_to_many :developers, :class_name => "DeveloperWithSymbolsForKeys", :join_table => :developers_projects, @@ -57,7 +57,7 @@ class ProjectWithSymbolsForKeys < ActiveRecord::Base end class DeveloperWithSymbolsForKeys < ActiveRecord::Base - set_table_name 'developers' + self.table_name = 'developers' has_and_belongs_to_many :projects, :class_name => "ProjectWithSymbolsForKeys", :join_table => :developers_projects, @@ -66,7 +66,7 @@ class DeveloperWithSymbolsForKeys < ActiveRecord::Base end class DeveloperWithCounterSQL < ActiveRecord::Base - set_table_name 'developers' + self.table_name = 'developers' has_and_belongs_to_many :projects, :class_name => "DeveloperWithCounterSQL", :join_table => "developers_projects", diff --git a/activerecord/test/cases/associations/join_model_test.rb b/activerecord/test/cases/associations/join_model_test.rb index 4ce8b85098c44..995afef796145 100644 --- a/activerecord/test/cases/associations/join_model_test.rb +++ b/activerecord/test/cases/associations/join_model_test.rb @@ -733,7 +733,7 @@ def find_post_with_dependency(post_id, association, association_name, dependency class_name = "PostWith#{association.to_s.classify}#{dependency.to_s.classify}" Post.find(post_id).update_column :type, class_name klass = Object.const_set(class_name, Class.new(ActiveRecord::Base)) - klass.set_table_name 'posts' + klass.table_name = 'posts' klass.send(association, association_name, :as => :taggable, :dependent => dependency) klass.find(post_id) end diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index cda5d1f2b7a4b..523b0c74edf4a 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -1431,16 +1431,19 @@ def test_set_table_name_with_value k = Class.new( ActiveRecord::Base ) k.table_name = "foo" assert_equal "foo", k.table_name - k.set_table_name "bar" + + assert_deprecated do + k.set_table_name "bar" + end assert_equal "bar", k.table_name end def test_switching_between_table_name assert_difference("GoodJoke.count") do - Joke.set_table_name "cold_jokes" + Joke.table_name = "cold_jokes" Joke.create - Joke.set_table_name "funny_jokes" + Joke.table_name = "funny_jokes" Joke.create end end @@ -1448,19 +1451,29 @@ def test_switching_between_table_name def test_quoted_table_name_after_set_table_name klass = Class.new(ActiveRecord::Base) - klass.set_table_name "foo" + klass.table_name = "foo" assert_equal "foo", klass.table_name assert_equal klass.connection.quote_table_name("foo"), klass.quoted_table_name - klass.set_table_name "bar" + klass.table_name = "bar" assert_equal "bar", klass.table_name assert_equal klass.connection.quote_table_name("bar"), klass.quoted_table_name end def test_set_table_name_with_block k = Class.new( ActiveRecord::Base ) - k.set_table_name { "ks" } - assert_equal "ks", k.table_name + assert_deprecated do + k.set_table_name "foo" + k.set_table_name { original_table_name + "ks" } + end + assert_equal "fooks", k.table_name + end + + def test_set_table_name_with_inheritance + k = Class.new( ActiveRecord::Base ) + def k.name; "Foo"; end + def k.table_name; super + "ks"; end + assert_equal "foosks", k.table_name end def test_set_primary_key_with_value diff --git a/activerecord/test/cases/callbacks_test.rb b/activerecord/test/cases/callbacks_test.rb index 7f4d25790bf6a..769076922605f 100644 --- a/activerecord/test/cases/callbacks_test.rb +++ b/activerecord/test/cases/callbacks_test.rb @@ -1,7 +1,7 @@ require "cases/helper" class CallbackDeveloper < ActiveRecord::Base - set_table_name 'developers' + self.table_name = 'developers' class << self def callback_string(callback_method) @@ -48,7 +48,7 @@ class CallbackDeveloperWithFalseValidation < CallbackDeveloper end class ParentDeveloper < ActiveRecord::Base - set_table_name 'developers' + self.table_name = 'developers' attr_accessor :after_save_called before_validation {|record| record.after_save_called = true} end @@ -58,7 +58,7 @@ class ChildDeveloper < ParentDeveloper end class RecursiveCallbackDeveloper < ActiveRecord::Base - set_table_name 'developers' + self.table_name = 'developers' before_save :on_before_save after_save :on_after_save @@ -79,7 +79,7 @@ def on_after_save end class ImmutableDeveloper < ActiveRecord::Base - set_table_name 'developers' + self.table_name = 'developers' validates_inclusion_of :salary, :in => 50000..200000 @@ -98,7 +98,7 @@ def cancel end class ImmutableMethodDeveloper < ActiveRecord::Base - set_table_name 'developers' + self.table_name = 'developers' validates_inclusion_of :salary, :in => 50000..200000 @@ -118,7 +118,7 @@ def cancelled? end class OnCallbacksDeveloper < ActiveRecord::Base - set_table_name 'developers' + self.table_name = 'developers' before_validation { history << :before_validation } before_validation(:on => :create){ history << :before_validation_on_create } @@ -138,7 +138,7 @@ def history end class CallbackCancellationDeveloper < ActiveRecord::Base - set_table_name 'developers' + self.table_name = 'developers' attr_reader :after_save_called, :after_create_called, :after_update_called, :after_destroy_called attr_accessor :cancel_before_save, :cancel_before_create, :cancel_before_update, :cancel_before_destroy diff --git a/activerecord/test/cases/locking_test.rb b/activerecord/test/cases/locking_test.rb index e9bd7f07b6646..de017022d7225 100644 --- a/activerecord/test/cases/locking_test.rb +++ b/activerecord/test/cases/locking_test.rb @@ -10,7 +10,7 @@ class LockWithoutDefault < ActiveRecord::Base; end class LockWithCustomColumnWithoutDefault < ActiveRecord::Base - set_table_name :lock_without_defaults_cust + self.table_name = :lock_without_defaults_cust set_locking_column :custom_lock_version end diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 3e219f2a49726..00c811194c81e 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -1027,7 +1027,7 @@ def test_keeping_default_and_notnull_constaint_on_change t.column :title, :string end person_klass = Class.new(Person) - person_klass.set_table_name 'testings' + person_klass.table_name = 'testings' person_klass.connection.add_column "testings", "wealth", :integer, :null => false, :default => 99 person_klass.reset_column_information diff --git a/activerecord/test/cases/transaction_callbacks_test.rb b/activerecord/test/cases/transaction_callbacks_test.rb index 85f222bca2c6f..f8b3e01a49000 100644 --- a/activerecord/test/cases/transaction_callbacks_test.rb +++ b/activerecord/test/cases/transaction_callbacks_test.rb @@ -6,7 +6,7 @@ class TransactionCallbacksTest < ActiveRecord::TestCase fixtures :topics class TopicWithCallbacks < ActiveRecord::Base - set_table_name :topics + self.table_name = :topics after_commit{|record| record.send(:do_after_commit, nil)} after_commit(:on => :create){|record| record.send(:do_after_commit, :create)} @@ -252,7 +252,7 @@ class TransactionObserverCallbacksTest < ActiveRecord::TestCase fixtures :topics class TopicWithObserverAttached < ActiveRecord::Base - set_table_name :topics + self.table_name = :topics def history @history ||= [] end diff --git a/activerecord/test/cases/validations_test.rb b/activerecord/test/cases/validations_test.rb index c3e494866bd4f..e575a98170c92 100644 --- a/activerecord/test/cases/validations_test.rb +++ b/activerecord/test/cases/validations_test.rb @@ -8,7 +8,7 @@ require 'models/company' class ProtectedPerson < ActiveRecord::Base - set_table_name 'people' + self.table_name = 'people' attr_accessor :addon attr_protected :first_name end diff --git a/activerecord/test/models/joke.rb b/activerecord/test/models/joke.rb index d7f01e59e60f0..edda4655dc70d 100644 --- a/activerecord/test/models/joke.rb +++ b/activerecord/test/models/joke.rb @@ -1,7 +1,7 @@ class Joke < ActiveRecord::Base - set_table_name 'funny_jokes' + self.table_name = 'funny_jokes' end class GoodJoke < ActiveRecord::Base - set_table_name 'funny_jokes' + self.table_name = 'funny_jokes' end diff --git a/activerecord/test/models/liquid.rb b/activerecord/test/models/liquid.rb index b96c054f6c42b..3fcd5e4b69603 100644 --- a/activerecord/test/models/liquid.rb +++ b/activerecord/test/models/liquid.rb @@ -1,5 +1,5 @@ class Liquid < ActiveRecord::Base - set_table_name :liquid + self.table_name = :liquid has_many :molecules, :uniq => true end diff --git a/activerecord/test/models/warehouse_thing.rb b/activerecord/test/models/warehouse_thing.rb index 6ace1183cc808..f20bd1a24529a 100644 --- a/activerecord/test/models/warehouse_thing.rb +++ b/activerecord/test/models/warehouse_thing.rb @@ -1,5 +1,5 @@ class WarehouseThing < ActiveRecord::Base - set_table_name "warehouse-things" + self.table_name = "warehouse-things" validates_uniqueness_of :value -end \ No newline at end of file +end diff --git a/railties/guides/source/active_record_basics.textile b/railties/guides/source/active_record_basics.textile index 66ad7b0255831..487f8b70f9883 100644 --- a/railties/guides/source/active_record_basics.textile +++ b/railties/guides/source/active_record_basics.textile @@ -101,11 +101,11 @@ h3. Overriding the Naming Conventions What if you need to follow a different naming convention or need to use your Rails application with a legacy database? No problem, you can easily override the default conventions. -You can use the +ActiveRecord::Base.set_table_name+ method to specify the table name that should be used: +You can use the +ActiveRecord::Base.table_name=+ method to specify the table name that should be used: class Product < ActiveRecord::Base - set_table_name "PRODUCT" + self.table_name = "PRODUCT" end