Skip to content

Commit

Permalink
[dm-constraints] calling :constraint option keyword check through a h…
Browse files Browse the repository at this point in the history
…ook into the DataMapper::Associations's 'has' method

Signed-off-by: Balint Erdi <balint.erdi@gmail.com>
  • Loading branch information
balinterdi authored and Dan Kubb committed Jan 15, 2009
1 parent afed67b commit 90bcd9e
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 49 deletions.
60 changes: 11 additions & 49 deletions dm-constraints/lib/dm-constraints.rb
Expand Up @@ -52,64 +52,26 @@ def initialize(name, repository_name, child_model, parent_model, options = {})
end
end

module DataMapper
module Associations
DELETE_CONSTRAINT_OPTIONS = [:protect, :destroy, :destroy!, :set_nil, :skip]
def has(cardinality, name, options = {})

# NOTE: the reason for this fix is that with the ability to pass in two
# hashes into has() there might be instances where people attempt to
# pass in the options into the name part and not know why things aren't
# working for them.
if name.kind_of?(Hash)
name_through, through = name.keys.first, name.values.first
cardinality_string = cardinality.to_s == 'Infinity' ? 'n' : cardinality.inspect
warn("In #{self.name} 'has #{cardinality_string}, #{name_through.inspect} => #{through.inspect}' is deprecated. Use 'has #{cardinality_string}, #{name_through.inspect}, :through => #{through.inspect}' instead")
end

options = options.merge(extract_min_max(cardinality))
options = options.merge(extract_throughness(name))

# do not remove this. There is alot of confusion on people's
# part about what the first argument to has() is. For the record it
# is the min cardinality and max cardinality of the association.
# simply put, it constraints the number of resources that will be
# returned by the association. It is not, as has been assumed,
# the number of results on the left and right hand side of the
# reltionship.
if options[:min] == n && options[:max] == n
raise ArgumentError, 'Cardinality may not be n..n. The cardinality specifies the min/max number of results from the association', caller
end

klass = options[:max] == 1 ? OneToOne : OneToMany
klass = ManyToMany if options[:through] == DataMapper::Resource
relationship = klass.setup(options.delete(:name), self, options)

delete_constraint_options = DELETE_CONSTRAINT_OPTIONS.map { |o| ":#{o}" }
raise ArgumentError, ":constraint option must be one of #{delete_constraint_options * ', '}" if options[:constraint] && !DELETE_CONSTRAINT_OPTIONS.include?(options[:constraint])

# Please leave this in - I will release contextual serialization soon
# which requires this -- guyvdb
# TODO convert this to a hook in the plugin once hooks work on class
# methods
self.init_has_relationship_for_serialization(relationship) if self.respond_to?(:init_has_relationship_for_serialization)

relationship
end
end
end

module DataMapper
module Constraints

include DeleteConstraint

module ClassMethods
include DeleteConstraint::ClassMethods
end

def self.included(model)
model.class_eval <<-EOS, __FILE__, __LINE__
model.extend(ClassMethods)
model.class_eval do
before_class_method :has, :check_delete_constraint_type
if method_defined?(:destroy)
before :destroy, :check_delete_constraints
end
EOS
end
end

end

class AutoMigrator
Expand Down
19 changes: 19 additions & 0 deletions dm-constraints/lib/dm-constraints/delete_constraint.rb
@@ -1,6 +1,23 @@
module DataMapper
module Constraints
module DeleteConstraint

def self.included(base)
base.extend(ClassMethods)
end

module ClassMethods
DELETE_CONSTRAINT_OPTIONS = [:protect, :destroy, :destroy!, :set_nil, :skip]
def check_delete_constraint_type(cardinality, name, options = {})
constraint_type = options[:constraint]
return if constraint_type.nil?
delete_constraint_options = DELETE_CONSTRAINT_OPTIONS.map { |o| ":#{o}" }
if !DELETE_CONSTRAINT_OPTIONS.include?(constraint_type)
raise ArgumentError, ":constraint option must be one of #{delete_constraint_options * ', '}"
end
end
end

def check_delete_constraints
model.relationships.each do |rel_name, rel|
children = self.send(rel_name)
Expand All @@ -23,6 +40,8 @@ def check_delete_constraints
end # case
end # relationships
end # check_delete_constraints


end # DeleteConstraint
end # Constraints
end # DataMapper

0 comments on commit 90bcd9e

Please sign in to comment.