Module: SimplyStored::SimpleDB::Associations::ClassMethods

Defined in:
lib/simply_stored/simpledb/associations.rb

Instance Method Summary collapse

Instance Method Details

#belongs_to(klass_name) ⇒ Object



9
10
11
12
# File 'lib/simply_stored/simpledb/associations.rb', line 9

def belongs_to(klass_name)
  define_belongs_to_getter(klass_name)
  define_belongs_to_setter(klass_name)
end

#define_belongs_to_getter(klass_name) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
# File 'lib/simply_stored/simpledb/associations.rb', line 38

def define_belongs_to_getter(klass_name)
  define_method klass_name.to_s do
    klass = self.class.get_class_from_name(klass_name)
    cached_version = instance_variable_get("@_cached_belongs_to_#{klass_name}")
    if cached_version.nil? and self["#{klass_name}_id"].present?
      cached_version = klass.find(self.send("#{klass_name}_id"), :auto_load => true)
      instance_variable_set("@_cached_belongs_to_#{klass_name}", cached_version)
    end
    cached_version
  end
end

#define_belongs_to_setter(klass_name) ⇒ Object



50
51
52
53
54
55
56
57
# File 'lib/simply_stored/simpledb/associations.rb', line 50

def define_belongs_to_setter(klass_name)
  define_method "#{klass_name}=" do |val|
    klass = self.class.get_class_from_name(klass_name)
    raise ArgumentError, "expected #{klass} got #{val.class}" unless val.is_a?(klass)
    self.send("#{klass_name}_id=", val.id)
    instance_variable_set("@_cached_belongs_to_#{klass_name}", val)
  end
end

#define_has_many_dependent_clearing(klass_name, options) ⇒ Object



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/simply_stored/simpledb/associations.rb', line 164

def define_has_many_dependent_clearing(klass_name, options)
  # add method to list of methods to run when deleted
  @_clear_dependents_after_delete_methods ||= []
  @_clear_dependents_after_delete_methods << "has_many_clear_#{klass_name}_after_destroy"

  # define actual clearing/deleting
  define_method "has_many_clear_#{klass_name}_after_destroy" do
    klass = self.class.get_class_from_name(klass_name)
    dependents = klass.send("find_all_by_#{self.class.foreign_key}".to_sym, self.id)
    if options[:dependent] == :nullify
      dependents.each do |dependent|
        dependent.send("#{self.class.foreign_key}=", nil)
      end
    elsif options[:dependent] == :destroy
      dependents.each do |dependent|
        dependent.delete
      end
    else
      raise ArgumentError, "unknown dependent method: #{options[:dependent].inspect}"
    end
  end
end

#define_has_many_getter(klass_name, options) ⇒ Object



108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/simply_stored/simpledb/associations.rb', line 108

def define_has_many_getter(klass_name, options)
  define_method klass_name.to_s do
    klass = self.class.get_class_from_name(klass_name)
    cached_version = instance_variable_get("@_cached_has_many_#{klass_name}")
    if cached_version
      return cached_version
    else
      cached_version = klass.send("find_all_by_#{self.class.foreign_key}".to_sym, self.id, {:auto_load => true})
      instance_variable_set("@_cached_has_many_#{klass_name}", cached_version)
      return cached_version
    end
  end
end

#define_has_many_setter_add(klass_name, options) ⇒ Object



122
123
124
125
126
127
128
129
130
131
# File 'lib/simply_stored/simpledb/associations.rb', line 122

def define_has_many_setter_add(klass_name, options)
  define_method "add_#{klass_name.to_s.singularize}" do |val|
    klass = self.class.get_class_from_name(klass_name)
    raise ArgumentError, "expected #{klass} got #{val.class}" unless val.is_a?(klass)
    val.send("#{self.class.foreign_key}=", self.id)
    val.save(false)
    cached_version = instance_variable_get("@_cached_has_many_#{klass_name}") || []
    instance_variable_set("@_cached_has_many_#{klass_name}", cached_version << val)
  end
end

#define_has_many_setter_remove(klass_name, options) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/simply_stored/simpledb/associations.rb', line 133

def define_has_many_setter_remove(klass_name, options)
  define_method "remove_#{klass_name.to_s.singularize}" do |val|
    klass = self.class.get_class_from_name(klass_name)
    raise ArgumentError, "expected #{klass} got #{val.class}" unless val.is_a?(klass)
    raise ArgumentError, "cannot remove not mine" unless val.send(self.class.foreign_key.to_sym) == self.id
    if options[:clear] == :nullify
      val.send("#{self.class.foreign_key}=", nil) 
      val.save(false)
    elsif options[:clear] == :destroy
      val.delete
    else
      raise "Unknown option for clear: #{option[:clear]}"
    end
    cached_version = instance_variable_get("@_cached_has_many_#{klass_name}") || []
    instance_variable_set("@_cached_has_many_#{klass_name}", cached_version.delete_if{|x| x.id == val.id})
  end
end

#define_has_many_setter_remove_all(klass_name, options) ⇒ Object



151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/simply_stored/simpledb/associations.rb', line 151

def define_has_many_setter_remove_all(klass_name, options)
  define_method "remove_all_#{klass_name}" do
    klass = self.class.get_class_from_name(klass_name)

    all = klass.send("find_all_by_#{self.class.foreign_key}".to_sym, self.id)

    all.each do |item|
      self.send("remove_#{klass_name.to_s.singularize}", item)
    end
    instance_variable_set("@_cached_has_many_#{klass_name}", [])
  end
end

#define_has_one_dependent_clearing(klass_name, options) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/simply_stored/simpledb/associations.rb', line 89

def define_has_one_dependent_clearing(klass_name, options)
  # add method to list of methods to run when deleted
  @_clear_dependents_after_delete_methods ||= []
  @_clear_dependents_after_delete_methods << "has_one_clear_#{klass_name}_after_destroy"

  # define actual clearing/deleting
  define_method "has_one_clear_#{klass_name}_after_destroy" do
    klass = self.class.get_class_from_name(klass_name)
    dependent = klass.send("find_by_#{self.class.foreign_key}".to_sym, self.id)
    if options[:dependent] == :nullify
      dependent.send("#{self.class.foreign_key}=", nil) if dependent
    elsif options[:dependent] == :destroy
      dependent.delete if dependent
    else
      raise ArgumentError, "unknown dependent method: #{options[:dependent].inspect}"
    end
  end
end

#define_has_one_getter(klass_name, options) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/simply_stored/simpledb/associations.rb', line 59

def define_has_one_getter(klass_name, options)
  define_method klass_name.to_s do
    klass = self.class.get_class_from_name(klass_name)
    cached_version = instance_variable_get("@_cached_has_one_#{klass_name}")
    if cached_version
      return cached_version
    else
      cached_version = klass.send("find_by_#{self.class.foreign_key}".to_sym, self.id, {:auto_load => true})
      instance_variable_set("@_cached_has_one_#{klass_name}", cached_version)
      return cached_version
    end
  end
end

#define_has_one_setter(klass_name, options) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/simply_stored/simpledb/associations.rb', line 73

def define_has_one_setter(klass_name, options)
  define_method "#{klass_name}=" do |val|
    klass = self.class.get_class_from_name(klass_name)
    raise ArgumentError, "expected #{klass} got #{val.class}" unless val.is_a?(klass)

    # clear old
    old = self.send("#{klass_name}")
    old.send("#{self.class.foreign_key}=", nil) if old && options[:clear] == :nullify
    old.delete if old && options[:clear] == :destroy

    # store new
    val.send("#{self.class.foreign_key}=", self.id)
    instance_variable_set("@_cached_has_one_#{klass_name}", val)
  end
end

#has_many(klass_name, options = {}) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/simply_stored/simpledb/associations.rb', line 25

def has_many(klass_name, options = {})
  options = {
    :clear => :nullify, # or :destroy
    :dependent => :nullify # or :destroy
  }.update(options)
    
  define_has_many_getter(klass_name, options)
  define_has_many_setter_add(klass_name, options)
  define_has_many_setter_remove(klass_name, options)
  define_has_many_setter_remove_all(klass_name, options)
  define_has_many_dependent_clearing(klass_name, options)
end

#has_one(klass_name, options = {}) ⇒ Object



14
15
16
17
18
19
20
21
22
23
# File 'lib/simply_stored/simpledb/associations.rb', line 14

def has_one(klass_name, options = {})
  options = {
    :clear => :nullify, # or :destroy
    :dependent => :nullify # or :destroy
  }.update(options)
    
 define_has_one_getter(klass_name, options)
 define_has_one_setter(klass_name, options)
 define_has_one_dependent_clearing(klass_name, options)
end