aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/associations/builder/has_one.rb
diff options
context:
space:
mode:
authorJon Leighton <j@jonathanleighton.com>2011-03-02 21:24:56 +0000
committerJon Leighton <j@jonathanleighton.com>2011-03-04 09:30:27 +0000
commit735844db712c511dd8abf36a5279318fbc0ff9d0 (patch)
tree5fbd5d224ef85d8c878bf221db98b422c9345466 /activerecord/lib/active_record/associations/builder/has_one.rb
parent9a98c766e045aebc2ef6d5b716936b73407f095d (diff)
parentb171b9e73dcc6a89b1da652da61c5127fe605b51 (diff)
downloadrails-735844db712c511dd8abf36a5279318fbc0ff9d0.tar.gz
rails-735844db712c511dd8abf36a5279318fbc0ff9d0.tar.bz2
rails-735844db712c511dd8abf36a5279318fbc0ff9d0.zip
Merge branch 'master' into nested_has_many_through
Conflicts: activerecord/CHANGELOG activerecord/lib/active_record/association_preload.rb activerecord/lib/active_record/associations.rb activerecord/lib/active_record/associations/class_methods/join_dependency.rb activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb activerecord/lib/active_record/associations/has_many_association.rb activerecord/lib/active_record/associations/has_many_through_association.rb activerecord/lib/active_record/associations/has_one_association.rb activerecord/lib/active_record/associations/has_one_through_association.rb activerecord/lib/active_record/associations/through_association_scope.rb activerecord/lib/active_record/reflection.rb activerecord/test/cases/associations/has_many_through_associations_test.rb activerecord/test/cases/associations/has_one_through_associations_test.rb activerecord/test/cases/reflection_test.rb activerecord/test/cases/relations_test.rb activerecord/test/fixtures/memberships.yml activerecord/test/models/categorization.rb activerecord/test/models/category.rb activerecord/test/models/member.rb activerecord/test/models/reference.rb activerecord/test/models/tagging.rb
Diffstat (limited to 'activerecord/lib/active_record/associations/builder/has_one.rb')
-rw-r--r--activerecord/lib/active_record/associations/builder/has_one.rb61
1 files changed, 61 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/associations/builder/has_one.rb b/activerecord/lib/active_record/associations/builder/has_one.rb
new file mode 100644
index 0000000000..07ba5d088e
--- /dev/null
+++ b/activerecord/lib/active_record/associations/builder/has_one.rb
@@ -0,0 +1,61 @@
+module ActiveRecord::Associations::Builder
+ class HasOne < SingularAssociation #:nodoc:
+ self.macro = :has_one
+
+ self.valid_options += [:order, :as]
+
+ class_attribute :through_options
+ self.through_options = [:through, :source, :source_type]
+
+ def constructable?
+ !options[:through]
+ end
+
+ def build
+ reflection = super
+ configure_dependency unless options[:through]
+ reflection
+ end
+
+ private
+
+ def validate_options
+ valid_options = self.class.valid_options
+ valid_options += self.class.through_options if options[:through]
+ options.assert_valid_keys(valid_options)
+ end
+
+ def configure_dependency
+ if options[:dependent]
+ unless [:destroy, :delete, :nullify, :restrict].include?(options[:dependent])
+ raise ArgumentError, "The :dependent option expects either :destroy, :delete, " \
+ ":nullify or :restrict (#{options[:dependent].inspect})"
+ end
+
+ send("define_#{options[:dependent]}_dependency_method")
+ model.before_destroy dependency_method_name
+ end
+ end
+
+ def dependency_method_name
+ "has_one_dependent_#{options[:dependent]}_for_#{name}"
+ end
+
+ def define_destroy_dependency_method
+ model.send(:class_eval, <<-eoruby, __FILE__, __LINE__ + 1)
+ def #{dependency_method_name}
+ association(#{name.to_sym.inspect}).delete
+ end
+ eoruby
+ end
+ alias :define_delete_dependency_method :define_destroy_dependency_method
+ alias :define_nullify_dependency_method :define_destroy_dependency_method
+
+ def define_restrict_dependency_method
+ name = self.name
+ model.redefine_method(dependency_method_name) do
+ raise ActiveRecord::DeleteRestrictionError.new(name) unless send(name).nil?
+ end
+ end
+ end
+end