acts-as-joinable 0.2 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Rakefile CHANGED
@@ -5,7 +5,7 @@ require 'rake/gempackagetask'
5
5
  spec = Gem::Specification.new do |s|
6
6
  s.name = "acts-as-joinable"
7
7
  s.authors = ["Lance Pollard"]
8
- s.version = "0.2"
8
+ s.version = "0.2.2"
9
9
  s.summary = "ActsAsJoinable: DRYing up Many-to-Many Relationships in ActiveRecord"
10
10
  s.homepage = "http://github.com/viatropos/acts-as-joinable"
11
11
  s.email = "lancejpollard@gmail.com"
@@ -41,6 +41,7 @@ module ActsAsJoinable
41
41
  end
42
42
 
43
43
  include ActsAsJoinable::Core
44
+ include ActsAsJoinable::Dirty
44
45
  end
45
46
  end
46
47
  end
@@ -1,3 +1,5 @@
1
+ # http://github.com/pluginaweek/preferences/blob/master/lib/preferences.rb
2
+ # add changes so you can track when the join model changes
1
3
  module ActsAsJoinable
2
4
  module Core
3
5
  def self.included(base)
@@ -8,7 +10,21 @@ module ActsAsJoinable
8
10
  end
9
11
 
10
12
  module ClassMethods
11
-
13
+ def add_around_filters_for_join(options, attribute, filter, filter_type)
14
+ options[filter_type] = filter if filter
15
+ =begin
16
+ if filter
17
+ options[filter_type] = lambda { |parent, child|
18
+ parent.write_join_attribute(attribute, child.id)
19
+ filter.call(self)
20
+ }
21
+ else
22
+ options[filter_type] = lambda { |parent, child|
23
+ parent.write_join_attribute(attribute, child.id)
24
+ }
25
+ end
26
+ =end
27
+ end
12
28
  # custom parent, self, and child contexts
13
29
  # Group...
14
30
  # acts_as_joinable_on :groups,
@@ -59,6 +75,8 @@ module ActsAsJoinable
59
75
 
60
76
  scope_name = opts[:named_scope]
61
77
 
78
+ autosave = opts[:autosave] != false
79
+
62
80
  joins.map!(&:to_sym)
63
81
 
64
82
  # class name of the model we're joining to self
@@ -110,8 +128,8 @@ module ActsAsJoinable
110
128
  :conditions => sql
111
129
  }
112
130
 
113
- options[:before_add] = before_add if before_add
114
- options[:after_add] = after_add if after_add
131
+ add_around_filters_for_join(options, "#{singular_type.to_s}_id".to_sym, before_add, :before_add)
132
+ add_around_filters_for_join(options, "#{singular_type.to_s}_id".to_sym, after_add, :after_add)
115
133
 
116
134
  # relationships == [:parent, :child]
117
135
  relationships.each do |relationship|
@@ -275,16 +293,13 @@ module ActsAsJoinable
275
293
 
276
294
  def add_has_one(singular_type, plural_type, relationship_with_context, class_name, join_context, join_value, options)
277
295
  define_method singular_type do
278
- send(plural_type).last
296
+ send(plural_type)[-1]#.last
279
297
  end
280
298
  define_method "#{singular_type}=" do |value|
281
- #send(relationship_with_context).delete_all
299
+ return value if send(plural_type).map(&:id).include?(value.id)
282
300
 
283
- #send(relationship_with_context).delete_all
301
+ send(plural_type) << value unless value.blank?
284
302
 
285
- unless value.blank?
286
- send(plural_type) << value
287
- end
288
303
  if value.blank?
289
304
  send(plural_type).delete_all
290
305
  else
@@ -337,6 +352,10 @@ module ActsAsJoinable
337
352
  end
338
353
 
339
354
  module InstanceMethods
355
+ def write_join_attribute(name, value)
356
+
357
+ end
358
+
340
359
  def destroy_relationships
341
360
  #conditions = %Q|(`relationships`.parent_type IN ("#{self.class.name}","#{self.class.base_class.name}") AND `relationships`.parent_id = #{self.id}) OR (`relationships`.child_type IN ("#{self.class.name}","#{self.class.base_class.name}") AND `relationships`.child_id = #{self.id})|
342
361
  classes = [self.class.name, self.class.base_class.name].compact.uniq
@@ -0,0 +1,116 @@
1
+ module ActsAsJoinable
2
+ module Dirty
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ base.send :include, InstanceMethods
6
+ end
7
+
8
+ module ClassMethods
9
+
10
+ end
11
+
12
+ module InstanceMethods
13
+ def write_join_attribute(name, value, context = nil)
14
+ name = name.to_s
15
+ assert_valid_join_attribute(name)
16
+
17
+ join_attributes_changed = join_attributes_changed_context(context)
18
+
19
+ if join_attributes_changed.include?(name)
20
+ old = join_attributes_changed[name]
21
+ join_attributes_changed.delete(name) unless join_attribute_value_changed?(name, old, value)
22
+ else
23
+ old = clone_join_attribute_value(name, context)
24
+ join_attributes_changed[name] = old if join_attribute_value_changed?(name, old, value)
25
+ end
26
+
27
+ join_attributes_context(context)[name] = value
28
+
29
+ value
30
+ end
31
+
32
+ def join_attributes_changed?(context = nil)
33
+ !join_attributes_changed_context(context).empty?
34
+ end
35
+
36
+ def join_attributes_changed(context = nil)
37
+ join_attributes_changed_context(context).keys
38
+ end
39
+
40
+ def join_attribute_changes(context = nil)
41
+ join_attributes_changed(context).inject({}) do |changes, join_attribute|
42
+ changes[join_attribute] = join_attribute_change(join_attribute, context)
43
+ changes
44
+ end
45
+ end
46
+
47
+ def reload(*args) #:nodoc:
48
+ result = super
49
+
50
+ @join_attributes.clear if @join_attributes
51
+ @join_attributes_changed.clear if @join_attributes_changed
52
+
53
+ result
54
+ end
55
+
56
+ private
57
+
58
+ def assert_valid_join_attribute(name)
59
+ #raise(ArgumentError, "Unknown join_attribute: #{name}") unless join_attribute_definitions.include?(name)
60
+ end
61
+
62
+ def join_attributes_context(context)
63
+ @join_attributes ||= {}
64
+ @join_attributes[context.is_a?(Symbol) ? context.to_s : context] ||= {}
65
+ end
66
+
67
+ def join_attributes_context_loaded?(context)
68
+ true #join_attribute_definitions.length == join_attributes_context(context).length
69
+ end
70
+
71
+ # Generates a clone of the current value stored for the join_attribute with
72
+ # the given name / context
73
+ def clone_join_attribute_value(name, context)
74
+ value = join_attribute(name, context)
75
+ value.duplicable? ? value.clone : value
76
+ rescue TypeError, NoMethodError
77
+ value
78
+ end
79
+
80
+ def join_attribute(name, context = nil)
81
+ join_attributes_context(context)[name]
82
+ end
83
+
84
+ # Keeps track of all join_attributes that have been changed so that they can
85
+ # be properly updated in the database. Maps context -> join_attribute -> value.
86
+ def join_attributes_changed_context(context)
87
+ @join_attributes_changed ||= {}
88
+ @join_attributes_changed[context.is_a?(Symbol) ? context.to_s : context] ||= {}
89
+ end
90
+
91
+ def join_attribute_changed?(name, context)
92
+ join_attributes_changed_context(context).include?(name)
93
+ end
94
+
95
+ def join_attribute_change(name, context)
96
+ [join_attributes_changed_context(context)[name], join_attribute(name, context)] if join_attribute_changed?(name, context)
97
+ end
98
+
99
+ def join_attribute_was(name, context)
100
+ join_attribute_changed?(name, context) ? join_attributes_changed_context(context)[name] : join_attribute(name, context)
101
+ end
102
+
103
+ def join_attribute_will_change!(name, context)
104
+ join_attributes_changed_context(context)[name] = clone_join_attribute_value(name, context)
105
+ end
106
+
107
+ def reset_join_attribute!(name, context)
108
+ write_join_attribute(name, join_attributes_changed_context(context)[name], context) if join_attribute_changed?(name, context)
109
+ end
110
+
111
+ def join_attribute_value_changed?(name, old, value)
112
+ old != value
113
+ end
114
+ end
115
+ end
116
+ end
@@ -78,7 +78,7 @@ class ActsAsJoinableTest < ActiveRecord::TestCase
78
78
  end
79
79
 
80
80
  # parent, child, and self
81
- assert_queries(2) do
81
+ assert_queries(3) do
82
82
  group.destroy
83
83
  end
84
84
 
@@ -93,6 +93,22 @@ class ActsAsJoinableTest < ActiveRecord::TestCase
93
93
 
94
94
  end
95
95
 
96
+ context "dirty join attributes" do
97
+ setup do
98
+ Group.delete_all
99
+ @group = Group.create!
100
+ end
101
+
102
+ should "get dirty attributes" do
103
+ assert !@group.join_attributes_changed?
104
+
105
+ @group.posts << Post.create!
106
+
107
+ assert @group.join_attributes_changed?
108
+ puts @group.join_attribute_changes.inspect
109
+ end
110
+ end
111
+
96
112
  teardown do
97
113
  destroy_models
98
114
  end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts-as-joinable
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- version: "0.2"
9
+ - 2
10
+ version: 0.2.2
10
11
  platform: ruby
11
12
  authors:
12
13
  - Lance Pollard
@@ -14,7 +15,7 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-10-22 00:00:00 -05:00
18
+ date: 2010-10-26 00:00:00 -05:00
18
19
  default_executable:
19
20
  dependencies: []
20
21
 
@@ -34,6 +35,7 @@ files:
34
35
  - lib/acts-as-joinable.rb
35
36
  - lib/acts_as_joinable/active_record_patch.rb
36
37
  - lib/acts_as_joinable/core.rb
38
+ - lib/acts_as_joinable/dirty.rb
37
39
  - rails/init.rb
38
40
  - test/database.rb
39
41
  - test/lib/asset.rb