diff options
Diffstat (limited to 'activerecord')
15 files changed, 144 insertions, 29 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 1822ba8e0e..aeb3773c99 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,5 +1,24 @@ ## Rails 4.0.0 (unreleased) ## +* `ActiveRelation#inspect` no longer calls `#to_a` + + *Brian Cardarella* + +* Add `collate` and `ctype` support to PostgreSQL. These are available for PostgreSQL 8.4 or later. + Example: + + development: + adapter: postgresql + host: localhost + database: rails_development + username: foo + password: bar + encoding: UTF8 + collate: ja_JP.UTF8 + ctype: ja_JP.UTF8 + + *kennyj* + * `FinderMethods#exists?` now returns `false` with the `false` argument. *Egor Lynko* diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 68f8bbeb1c..a62fce4756 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1167,6 +1167,8 @@ module ActiveRecord # If true, always save the associated objects or destroy them if marked for destruction, # when saving the parent object. If false, never save or destroy the associated objects. # By default, only save associated objects that are new records. + # + # Note that <tt>accepts_nested_attributes_for</tt> sets <tt>:autosave</tt> to <tt>true</tt>. # [:inverse_of] # Specifies the name of the <tt>belongs_to</tt> association on the associated object # that is the inverse of this <tt>has_many</tt> association. Does not work in combination @@ -1288,6 +1290,8 @@ module ActiveRecord # If true, always save the associated object or destroy it if marked for destruction, # when saving the parent object. If false, never save or destroy the associated object. # By default, only save the associated object if it's a new record. + # + # Note that <tt>accepts_nested_attributes_for</tt> sets <tt>:autosave</tt> to <tt>true</tt>. # [:inverse_of] # Specifies the name of the <tt>belongs_to</tt> association on the associated object # that is the inverse of this <tt>has_one</tt> association. Does not work in combination @@ -1404,6 +1408,8 @@ module ActiveRecord # saving the parent object. # If false, never save or destroy the associated object. # By default, only save the associated object if it's a new record. + # + # Note that <tt>accepts_nested_attributes_for</tt> sets <tt>:autosave</tt> to <tt>true</tt>. # [:touch] # If true, the associated object will be touched (the updated_at/on attributes set to now) # when this record is either saved or destroyed. If you specify a symbol, that attribute @@ -1589,6 +1595,8 @@ module ActiveRecord # If false, never save or destroy the associated objects. # By default, only save associated objects that are new records. # + # Note that <tt>accepts_nested_attributes_for</tt> sets <tt>:autosave</tt> to <tt>true</tt>. + # # Option examples: # has_and_belongs_to_many :projects # has_and_belongs_to_many :projects, :include => [ :milestones, :manager ] diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index f5794a4e54..2b0ba2f479 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -68,10 +68,12 @@ module ActiveRecord # column_exists?(:suppliers, :name, :string, :limit => 100) def column_exists?(table_name, column_name, type = nil, options = {}) columns(table_name).any?{ |c| c.name == column_name.to_s && - (!type || c.type == type) && - (!options[:limit] || c.limit == options[:limit]) && - (!options[:precision] || c.precision == options[:precision]) && - (!options[:scale] || c.scale == options[:scale]) } + (!type || c.type == type) && + (!options.key?(:limit) || c.limit == options[:limit]) && + (!options.key?(:precision) || c.precision == options[:precision]) && + (!options.key?(:scale) || c.scale == options[:scale]) && + (!options.key?(:default) || c.default == options[:default]) && + (!options.key?(:null) || c.null == options[:null]) } end # Creates a new table with the name +table_name+. +table_name+ may either diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index c6ec946b73..78ecb1cdc5 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -148,13 +148,10 @@ db_namespace = namespace :db do # desc "Retrieves the collation for the current environment's database" task :collation => [:environment, :load_config] do - config = ActiveRecord::Base.configurations[Rails.env || 'development'] - case config['adapter'] - when /mysql/ - ActiveRecord::Base.establish_connection(config) - puts ActiveRecord::Base.connection.collation - else - $stderr.puts 'sorry, your database adapter is not supported yet, feel free to submit a patch' + begin + puts ActiveRecord::Tasks::DatabaseTasks.collation_current + rescue NoMethodError + $stderr.puts 'Sorry, your database adapter is not supported yet, feel free to submit a patch' end end @@ -274,7 +271,7 @@ db_namespace = namespace :db do ENV['ISC_USER'] = config['username'].to_s if config['username'] ENV['ISC_PASSWORD'] = config['password'].to_s if config['password'] end - + def firebird_db_string(config) FireRuby::Database.db_string_for(config.symbolize_keys) end @@ -435,7 +432,7 @@ namespace :railties do task :migrations => :'db:load_config' do to_load = ENV['FROM'].blank? ? :all : ENV['FROM'].split(",").map {|n| n.strip } railties = {} - Rails.application.railties.all do |railtie| + Rails.application.railties.each do |railtie| next unless to_load == :all || to_load.include?(railtie.railtie_name) if railtie.respond_to?(:paths) && (path = railtie.paths['db/migrate'].first) diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index fe3aa00a74..e268d451e0 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -492,10 +492,6 @@ module ActiveRecord end end - def inspect - to_a.inspect - end - def pretty_print(q) q.pp(self.to_a) end diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index e6a67b76fe..974cd326ef 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -146,8 +146,8 @@ module ActiveRecord to_a end - # Returns true if a record exists in the table that matches the +id+ or - # conditions given, or false otherwise. The argument can take five forms: + # Returns +true+ if a record exists in the table that matches the +id+ or + # conditions given, or +false+ otherwise. The argument can take six forms: # # * Integer - Finds the record with this primary key. # * String - Finds the record with a primary key corresponding to this @@ -155,8 +155,9 @@ module ActiveRecord # * Array - Finds the record that matches these +find+-style conditions # (such as <tt>['color = ?', 'red']</tt>). # * Hash - Finds the record that matches these +find+-style conditions - # (such as <tt>{:color => 'red'}</tt>). - # * No args - Returns false if the table is empty, true otherwise. + # (such as <tt>{color: 'red'}</tt>). + # * +false+ - Returns always +false+. + # * No args - Returns +false+ if the table is empty, +true+ otherwise. # # For more information about specifying conditions as a Hash or Array, # see the Conditions section in the introduction to ActiveRecord::Base. @@ -168,7 +169,8 @@ module ActiveRecord # Person.exists?(5) # Person.exists?('5') # Person.exists?(['name LIKE ?', "%#{query}%"]) - # Person.exists?(:name => "David") + # Person.exists?(name: 'David') + # Person.exists?(false) # Person.exists? def exists?(conditions = :none) conditions = conditions.id if ActiveRecord::Model === conditions diff --git a/activerecord/lib/active_record/tasks/database_tasks.rb b/activerecord/lib/active_record/tasks/database_tasks.rb index 999b2ebc85..f1241502f5 100644 --- a/activerecord/lib/active_record/tasks/database_tasks.rb +++ b/activerecord/lib/active_record/tasks/database_tasks.rb @@ -56,6 +56,15 @@ module ActiveRecord class_for_adapter(configuration['adapter']).new(*arguments).charset end + def collation_current(environment = Rails.env) + collation ActiveRecord::Base.configurations[environment] + end + + def collation(*arguments) + configuration = arguments.first + class_for_adapter(configuration['adapter']).new(*arguments).collation + end + def purge(configuration) class_for_adapter(configuration['adapter']).new(configuration).purge end diff --git a/activerecord/lib/active_record/tasks/mysql_database_tasks.rb b/activerecord/lib/active_record/tasks/mysql_database_tasks.rb index b39cd2282f..bf62dfd5b5 100644 --- a/activerecord/lib/active_record/tasks/mysql_database_tasks.rb +++ b/activerecord/lib/active_record/tasks/mysql_database_tasks.rb @@ -44,6 +44,10 @@ module ActiveRecord connection.charset end + def collation + connection.collation + end + def structure_dump(filename) establish_connection configuration File.open(filename, "w:utf-8") { |f| f << ActiveRecord::Base.connection.structure_dump } diff --git a/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb b/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb index a210392e53..4139460273 100644 --- a/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb +++ b/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb @@ -29,6 +29,10 @@ module ActiveRecord connection.encoding end + def collation + connection.collate + end + def purge clear_active_connections! drop diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index b8481175b2..3ea6201d60 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -193,7 +193,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_no_sql_should_be_fired_if_association_already_loaded Car.create(:name => 'honda') bulbs = Car.first.bulbs - bulbs.inspect # to load all instances of bulbs + bulbs.to_a # to load all instances of bulbs assert_no_queries do bulbs.first() diff --git a/activerecord/test/cases/migration/change_schema_test.rb b/activerecord/test/cases/migration/change_schema_test.rb index ab61a4dcef..ce9be66069 100644 --- a/activerecord/test/cases/migration/change_schema_test.rb +++ b/activerecord/test/cases/migration/change_schema_test.rb @@ -291,14 +291,20 @@ module ActiveRecord def test_column_exists_with_definition connection.create_table :testings do |t| - t.column :foo, :string, :limit => 100 - t.column :bar, :decimal, :precision => 8, :scale => 2 + t.column :foo, :string, limit: 100 + t.column :bar, :decimal, precision: 8, scale: 2 + t.column :taggable_id, :integer, null: false + t.column :taggable_type, :string, default: 'Photo' end - assert connection.column_exists?(:testings, :foo, :string, :limit => 100) - refute connection.column_exists?(:testings, :foo, :string, :limit => 50) - assert connection.column_exists?(:testings, :bar, :decimal, :precision => 8, :scale => 2) - refute connection.column_exists?(:testings, :bar, :decimal, :precision => 10, :scale => 2) + assert connection.column_exists?(:testings, :foo, :string, limit: 100) + refute connection.column_exists?(:testings, :foo, :string, limit: nil) + assert connection.column_exists?(:testings, :bar, :decimal, precision: 8, scale: 2) + refute connection.column_exists?(:testings, :bar, :decimal, precision: nil, scale: nil) + assert connection.column_exists?(:testings, :taggable_id, :integer, null: false) + refute connection.column_exists?(:testings, :taggable_id, :integer, null: true) + assert connection.column_exists?(:testings, :taggable_type, :string, default: 'Photo') + refute connection.column_exists?(:testings, :taggable_type, :string, default: nil) end def test_column_exists_on_table_with_no_options_parameter_supplied diff --git a/activerecord/test/cases/tasks/database_tasks_test.rb b/activerecord/test/cases/tasks/database_tasks_test.rb index 5f36b2c841..8c96a8aaa1 100644 --- a/activerecord/test/cases/tasks/database_tasks_test.rb +++ b/activerecord/test/cases/tasks/database_tasks_test.rb @@ -251,6 +251,17 @@ module ActiveRecord end end + class DatabaseTasksCollationTest < ActiveRecord::TestCase + include DatabaseTasksSetupper + + ADAPTERS_TASKS.each do |k, v| + define_method("test_#{k}_collation") do + eval("@#{v}").expects(:collation) + ActiveRecord::Tasks::DatabaseTasks.collation 'adapter' => k + end + end + end + class DatabaseTasksStructureDumpTest < ActiveRecord::TestCase include DatabaseTasksSetupper diff --git a/activerecord/test/cases/tasks/mysql_rake_test.rb b/activerecord/test/cases/tasks/mysql_rake_test.rb index 42a11b0171..9a0eb423bd 100644 --- a/activerecord/test/cases/tasks/mysql_rake_test.rb +++ b/activerecord/test/cases/tasks/mysql_rake_test.rb @@ -195,6 +195,24 @@ module ActiveRecord end end + class MysqlDBCollationTest < ActiveRecord::TestCase + def setup + @connection = stub(:create_database => true) + @configuration = { + 'adapter' => 'mysql', + 'database' => 'my-app-db' + } + + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:establish_connection).returns(true) + end + + def test_db_retrieves_collation + @connection.expects(:collation) + ActiveRecord::Tasks::DatabaseTasks.collation @configuration + end + end + class MySQLStructureDumpTest < ActiveRecord::TestCase def setup @connection = stub(:structure_dump => true) diff --git a/activerecord/test/cases/tasks/postgresql_rake_test.rb b/activerecord/test/cases/tasks/postgresql_rake_test.rb index 75ae7db4c9..df1075d816 100644 --- a/activerecord/test/cases/tasks/postgresql_rake_test.rb +++ b/activerecord/test/cases/tasks/postgresql_rake_test.rb @@ -159,6 +159,24 @@ module ActiveRecord end end + class PostgreSQLDBCollationTest < ActiveRecord::TestCase + def setup + @connection = stub(:create_database => true) + @configuration = { + 'adapter' => 'postgresql', + 'database' => 'my-app-db' + } + + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:establish_connection).returns(true) + end + + def test_db_retrieves_collation + @connection.expects(:collate) + ActiveRecord::Tasks::DatabaseTasks.collation @configuration + end + end + class PostgreSQLStructureDumpTest < ActiveRecord::TestCase def setup @connection = stub(:structure_dump => true) diff --git a/activerecord/test/cases/tasks/sqlite_rake_test.rb b/activerecord/test/cases/tasks/sqlite_rake_test.rb index b5557fc953..06a1d0ffc2 100644 --- a/activerecord/test/cases/tasks/sqlite_rake_test.rb +++ b/activerecord/test/cases/tasks/sqlite_rake_test.rb @@ -124,6 +124,27 @@ module ActiveRecord end end + class SqliteDBCollationTest < ActiveRecord::TestCase + def setup + @database = 'db_create.sqlite3' + @connection = stub :connection + @configuration = { + 'adapter' => 'sqlite3', + 'database' => @database + } + + File.stubs(:exist?).returns(false) + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:establish_connection).returns(true) + end + + def test_db_retrieves_collation + assert_raise NoMethodError do + ActiveRecord::Tasks::DatabaseTasks.collation @configuration, '/rails/root' + end + end + end + class SqliteStructureDumpTest < ActiveRecord::TestCase def setup @database = "db_create.sqlite3" |