diff options
Diffstat (limited to 'activerecord/lib')
21 files changed, 96 insertions, 2 deletions
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index d623ddb915..ee87cb9b41 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1,5 +1,6 @@ require 'active_support/core_ext/module/delegation' require 'active_support/core_ext/enumerable' +require 'active_support/core_ext/object/blank' module ActiveRecord class InverseOfAssociationNotFoundError < ActiveRecordError #:nodoc: @@ -85,6 +86,15 @@ module ActiveRecord end end + # This error is raised when trying to destroy a parent instance in a N:1, 1:1 assosications + # (has_many, has_one) when there is at least 1 child assosociated instance. + # ex: if @project.tasks.size > 0, DeleteRestrictionError will be raised when trying to destroy @project + class DeleteRestrictionError < ActiveRecordError #:nodoc: + def initialize(reflection) + super("Cannot delete record because of dependent #{reflection.name}") + end + end + # See ActiveRecord::Associations::ClassMethods for documentation. module Associations # :nodoc: extend ActiveSupport::Concern @@ -830,6 +840,8 @@ module ActiveRecord # objects are deleted *without* calling their +destroy+ method. If set to <tt>:nullify</tt> all associated # objects' foreign keys are set to +NULL+ *without* calling their +save+ callbacks. *Warning:* This option is ignored when also using # the <tt>:through</tt> option. + # the <tt>:through</tt> option. If set to <tt>:restrict</tt> + # this object cannot be deleted if it has any associated object. # [:finder_sql] # Specify a complete SQL statement to fetch the association. This is a good way to go for complex # associations that depend on multiple tables. Note: When this option is used, +find_in_collection+ is _not_ added. @@ -1468,9 +1480,15 @@ module ActiveRecord # Creates before_destroy callback methods that nullify, delete or destroy # has_many associated objects, according to the defined :dependent rule. + # If the association is marked as :dependent => :restrict, create a callback + # that prevents deleting entirely. # # See HasManyAssociation#delete_records. Dependent associations # delete children, otherwise foreign key is set to NULL. + # See HasManyAssociation#delete_records. Dependent associations + # delete children if the option is set to :destroy or :delete_all, set the + # foreign key to NULL if the option is set to :nullify, and do not touch the + # child records if the option is set to :restrict. # # The +extra_conditions+ parameter, which is not used within the main # Active Record codebase, is meant to allow plugins to define extra @@ -1530,14 +1548,24 @@ module ActiveRecord %@#{dependent_conditions}@) end CALLBACK + when :restrict + method_name = "has_many_dependent_restrict_for_#{reflection.name}".to_sym + define_method(method_name) do + unless send(reflection.name).empty? + raise DeleteRestrictionError.new(reflection) + end + end + before_destroy method_name else - raise ArgumentError, "The :dependent option expects either :destroy, :delete_all, or :nullify (#{reflection.options[:dependent].inspect})" + raise ArgumentError, "The :dependent option expects either :destroy, :delete_all, :nullify or :restrict (#{reflection.options[:dependent].inspect})" end end end # Creates before_destroy callback methods that nullify, delete or destroy # has_one associated objects, according to the defined :dependent rule. + # If the association is marked as :dependent => :restrict, create a callback + # that prevents deleting entirely. def configure_dependency_for_has_one(reflection) if reflection.options.include?(:dependent) name = reflection.options[:dependent] @@ -1558,8 +1586,16 @@ module ActiveRecord association.update_attribute(#{reflection.primary_key_name.inspect}, nil) if association end eoruby + when :restrict + method_name = "has_one_dependent_restrict_for_#{reflection.name}".to_sym + define_method(method_name) do + unless send(reflection.name).nil? + raise DeleteRestrictionError.new(reflection) + end + end + before_destroy method_name else - raise ArgumentError, "The :dependent option expects either :destroy, :delete or :nullify (#{reflection.options[:dependent].inspect})" + raise ArgumentError, "The :dependent option expects either :destroy, :delete, :nullify or :restrict (#{reflection.options[:dependent].inspect})" end before_destroy method_name diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb index bd2acd4340..5338bb099d 100644 --- a/activerecord/lib/active_record/associations/has_many_through_association.rb +++ b/activerecord/lib/active_record/associations/has_many_through_association.rb @@ -1,4 +1,5 @@ require "active_record/associations/through_association_scope" +require 'active_support/core_ext/object/blank' module ActiveRecord module Associations diff --git a/activerecord/lib/active_record/attribute_methods/dirty.rb b/activerecord/lib/active_record/attribute_methods/dirty.rb index a8698a2f5a..435aea9b09 100644 --- a/activerecord/lib/active_record/attribute_methods/dirty.rb +++ b/activerecord/lib/active_record/attribute_methods/dirty.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/object/blank' + module ActiveRecord module AttributeMethods module Dirty diff --git a/activerecord/lib/active_record/attribute_methods/query.rb b/activerecord/lib/active_record/attribute_methods/query.rb index a949d80120..948809c65a 100644 --- a/activerecord/lib/active_record/attribute_methods/query.rb +++ b/activerecord/lib/active_record/attribute_methods/query.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/object/blank' + module ActiveRecord module AttributeMethods module Query diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 367b4ce217..b81434c1f7 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -13,6 +13,8 @@ require 'active_support/core_ext/hash/slice' require 'active_support/core_ext/string/behavior' require 'active_support/core_ext/object/singleton_class' require 'active_support/core_ext/module/delegation' +require 'active_support/core_ext/object/duplicable' +require 'active_support/core_ext/object/blank' require 'arel' require 'active_record/errors' diff --git a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb index 020acbbe5a..1e095110f2 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/object/duplicable' + module ActiveRecord module ConnectionAdapters # :nodoc: module QueryCache diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb index 64faaef4a0..046825d43f 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -1,3 +1,4 @@ +require 'active_support/core_ext/object/blank' require 'date' require 'set' require 'bigdecimal' diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb index 521bd810d0..55d9d20bb5 100644 --- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb @@ -1,5 +1,6 @@ require 'active_record/connection_adapters/abstract_adapter' require 'active_support/core_ext/kernel/requires' +require 'active_support/core_ext/object/blank' require 'set' module MysqlCompat #:nodoc: diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index c9a5f00dfd..2ae26246a2 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -1,5 +1,6 @@ require 'active_record/connection_adapters/abstract_adapter' require 'active_support/core_ext/kernel/requires' +require 'active_support/core_ext/object/blank' begin require_library_or_gem 'pg' @@ -651,6 +652,27 @@ module ActiveRecord end end + # Creates a schema for the given user + # + # Example: + # create_schema('products', 'postgres') + def create_schema(schema_name, pg_username) + execute("CREATE SCHEMA \"#{schema_name}\" AUTHORIZATION \"#{pg_username}\"") + end + + # Drops a schema + # + # Example: + # drop_schema('products') + def drop_schema(schema_name) + execute("DROP SCHEMA \"#{schema_name}\"") + end + + # Returns an array of all schemas in the database + def all_schemas + query('SELECT schema_name FROM information_schema.schemata').flatten + end + # Returns the list of all tables in the schema search path or a specified schema. def tables(name = nil) query(<<-SQL, name).map { |row| row[0] } diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb index 79f70f07cd..22f0e60083 100644 --- a/activerecord/lib/active_record/fixtures.rb +++ b/activerecord/lib/active_record/fixtures.rb @@ -4,6 +4,7 @@ require 'csv' require 'zlib' require 'active_support/dependencies' require 'active_support/core_ext/logger' +require 'active_support/core_ext/object/blank' if RUBY_VERSION < '1.9' module YAML #:nodoc: diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb index 394e1587e1..11c21a9207 100644 --- a/activerecord/lib/active_record/named_scope.rb +++ b/activerecord/lib/active_record/named_scope.rb @@ -1,6 +1,7 @@ require 'active_support/core_ext/array' require 'active_support/core_ext/hash/except' require 'active_support/core_ext/object/singleton_class' +require 'active_support/core_ext/object/blank' module ActiveRecord module NamedScope diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb index 76ec7eb681..ee2d420194 100644 --- a/activerecord/lib/active_record/nested_attributes.rb +++ b/activerecord/lib/active_record/nested_attributes.rb @@ -1,5 +1,6 @@ require 'active_support/core_ext/hash/except' require 'active_support/core_ext/object/try' +require 'active_support/core_ext/object/blank' module ActiveRecord module NestedAttributes #:nodoc: diff --git a/activerecord/lib/active_record/query_cache.rb b/activerecord/lib/active_record/query_cache.rb index eb92bc2545..093c6c1e55 100644 --- a/activerecord/lib/active_record/query_cache.rb +++ b/activerecord/lib/active_record/query_cache.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/object/blank' + module ActiveRecord class QueryCache module ClassMethods diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index 0229793a9a..06485b9033 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -85,8 +85,14 @@ namespace :db do end when 'postgresql' @encoding = config[:encoding] || ENV['CHARSET'] || 'utf8' + schema_search_path = config['schema_search_path'] || 'public' + first_in_schema_search_path = schema_search_path.split(',').first.strip begin ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public')) + unless ActiveRecord::Base.connection.all_schemas.include?(first_in_schema_search_path) + ActiveRecord::Base.connection.create_schema(first_in_schema_search_path, config['username']) + $stderr.puts "Schema #{first_in_schema_search_path} has been created." + end ActiveRecord::Base.connection.create_database(config['database'], config.merge('encoding' => @encoding)) ActiveRecord::Base.establish_connection(config) rescue diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index a20c152eeb..8577ec58f7 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/object/blank' + module ActiveRecord class Relation JoinOperation = Struct.new(:relation, :join_class, :on) diff --git a/activerecord/lib/active_record/relation/batches.rb b/activerecord/lib/active_record/relation/batches.rb index 4a260d4caa..cb57b445e5 100644 --- a/activerecord/lib/active_record/relation/batches.rb +++ b/activerecord/lib/active_record/relation/batches.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/object/blank' + module ActiveRecord module Batches # :nodoc: # Yields each record that was found by the find +options+. The find is diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb index e77424a64b..a5ea6e7e3a 100644 --- a/activerecord/lib/active_record/relation/calculations.rb +++ b/activerecord/lib/active_record/relation/calculations.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/object/blank' + module ActiveRecord module Calculations # Count operates using three different approaches. diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index c1cce679b6..37aaac0894 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/object/blank' + module ActiveRecord module FinderMethods # Find operates with four different retrieval approaches: diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 0250e739b8..e224781016 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/object/blank' + module ActiveRecord module QueryMethods extend ActiveSupport::Concern diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb index 2841ff1239..a17de1bdbb 100644 --- a/activerecord/lib/active_record/relation/spawn_methods.rb +++ b/activerecord/lib/active_record/relation/spawn_methods.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/object/blank' + module ActiveRecord module SpawnMethods def merge(r) diff --git a/activerecord/lib/active_record/schema.rb b/activerecord/lib/active_record/schema.rb index a996a0ebac..a833356d15 100644 --- a/activerecord/lib/active_record/schema.rb +++ b/activerecord/lib/active_record/schema.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/object/blank' + module ActiveRecord # Allows programmers to programmatically define a schema in a portable # DSL. This means you can define tables, indexes, etc. without using SQL |