Skip to content

Commit

Permalink
Adding collection module for creating dirty association collection me…
Browse files Browse the repository at this point in the history
…thods.
  • Loading branch information
caseydreier committed Jan 23, 2010
1 parent 595672f commit dfbc4f7
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 20 deletions.
4 changes: 4 additions & 0 deletions lib/dirty_associations/base.rb
@@ -0,0 +1,4 @@
module DirtyAssociations
class Base
end
end
13 changes: 12 additions & 1 deletion lib/dirty_associations/builder.rb
@@ -1,6 +1,17 @@
require 'active_support'

module DirtyAssociations
class Builder < Struct.new :association_name, :base
include CollectionMethods
# include SingularMethods

attr_accessor :association_name_singular

def initialize(association_name,base)
super(association_name,base)
self.association_name_singular = self.association_name.to_s.singularize.to_sym
end

# Generates the methods used to track the association's changes
# For collection associations:
# * collection_plural_were
Expand All @@ -27,7 +38,7 @@ class Builder < Struct.new :association_name, :base
# * collection_singular_id_removed?
# * collection_singular_id_added?
def generate_dirty_methods!
generate_collection_methods if is_collection?
generate_collection_methods! if is_collection?
generate_singular_methods if is_singular?
end

Expand Down
36 changes: 36 additions & 0 deletions lib/dirty_associations/collection_methods.rb
@@ -0,0 +1,36 @@
module DirtyAssociations
module CollectionMethods

# Creates methods for dirty collections associations
def generate_collection_methods!
generate_collection_object_methods!
generate_collection_id_methods!
end

def generate_collection_id_methods!
base.instance_eval <<-EOV
def #{association_name_singular}_ids_were; (original_associations["#{association_name_singular}_original_ids".to_sym] || []).uniq; end;
def #{association_name_singular}_ids_removed(); #{association_name_singular}_ids_were - #{association_name_singular}_ids; end;
def #{association_name_singular}_ids_removed?(); !#{association_name_singular}_ids_removed.empty?; end;
def #{association_name_singular}_ids_added(); #{association_name_singular}_ids - #{association_name_singular}_ids_were; end;
def #{association_name_singular}_ids_added?(); !#{association_name_singular}_ids_added.empty?; end;
def #{association_name_singular}_ids_changed?(); #{association_name_singular}_ids_added? || #{association_name_singular}_ids_removed?; end;
EOV
end

def generate_collection_object_methods!
base.instance_eval <<-EOV
def #{association_name}_were; (original_associations["#{association_name_singular}_original_ids".to_sym] || []).uniq; end;
def #{association_name}_removed(); #{association_name_singular}_ids_were - #{association_name_singular}_ids; end;
def #{association_name}_removed?(); !#{association_name_singular}_ids_removed.empty?; end;
def #{association_name}_added(); #{association_name_singular}_ids - #{association_name}_ids_were; end;
def #{association_name}_added?(); !#{association_name_singular}_ids_added.empty?; end;
def #{association_name}_changed?(); #{association_name_singular}_ids_added? || #{association_name_singular}_ids_removed?; end;
EOV

end



end
end
12 changes: 0 additions & 12 deletions lib/dirty_associations/instance_methods.rb
Expand Up @@ -46,18 +46,6 @@ def associations_changed?

private

# Generates custom methods for tracking association id history for collection methods (has_many, habtm)
def generate_collection_methods(assoc_name)
instance_eval <<-EOV
def #{assoc_name}_ids_were; (original_associations["#{assoc_name}_original_ids".to_sym] || []).uniq; end;
def #{assoc_name}_ids_removed(); #{assoc_name}_ids_were - #{assoc_name}_ids; end;
def #{assoc_name}_ids_removed?(); !#{assoc_name.to_s.singularize}_ids_removed.empty?; end;
def #{assoc_name}_ids_added(); #{assoc_name}_ids - #{assoc_name}_ids_were; end;
def #{assoc_name}_ids_added?(); !#{assoc_name}_ids_added.empty?; end;
def #{assoc_name}_ids_changed?(); #{assoc_name}_ids_added? || #{assoc_name}_ids_removed?; end;
EOV
end

# Copy the initial ids from the association
def record_initial_association_ids!(reflection)
assoc_name = reflection.to_s.singularize
Expand Down
28 changes: 28 additions & 0 deletions test/builder_test.rb
Expand Up @@ -13,8 +13,16 @@ class BuilderTest < ActiveSupport::TestCase
builder = DirtyAssociations::Builder.new(:keywords, task)
assert !builder.association_name.blank?
assert !builder.base.blank?
assert !builder.association_name_singular.blank?
end

test "on initialize, the builder sets the singular version of the association name" do
task = Task.first
builder = DirtyAssociations::Builder.new(:keywords, task)
assert_equal :keyword, builder.association_name_singular
end


test "the method, is_singular?, should return a boolean false if the association is a collection association" do
task = Task.first
builder = DirtyAssociations::Builder.new(:keywords, task) # keywords is habtm
Expand All @@ -39,6 +47,26 @@ class BuilderTest < ActiveSupport::TestCase
assert !builder.is_collection?
end

test "calling generate_dirty_methods! will create a series of methods for a collection association" do
task = Task.first
builder = DirtyAssociations::Builder.new(:keywords, task)
builder.generate_dirty_methods!

assert task.respond_to?(:keywords_were)
assert task.respond_to?(:keywords_changed?)
assert task.respond_to?(:keywords_added?)
assert task.respond_to?(:keywords_added)
assert task.respond_to?(:keywords_removed?)
assert task.respond_to?(:keywords_removed)

assert task.respond_to?(:keyword_ids_were)
assert task.respond_to?(:keyword_ids_changed?)
assert task.respond_to?(:keyword_ids_added?)
assert task.respond_to?(:keyword_ids_added)
assert task.respond_to?(:keyword_ids_removed?)
assert task.respond_to?(:keyword_ids_removed)
end



end
7 changes: 0 additions & 7 deletions test/dirty_associations_test.rb
Expand Up @@ -26,13 +26,6 @@ class Keyword < ActiveRecord::Base
test "calling begin_tracking_associations initializes the tracking variables" do
t = Task.first
t.track_association_changes do

assert t.respond_to?(:keyword_ids_changed?)
assert t.respond_to?(:keyword_ids_added?)
assert t.respond_to?(:keyword_ids_added)
assert t.respond_to?(:keyword_ids_removed?)
assert t.respond_to?(:keyword_ids_removed)
assert t.respond_to?(:clear_association_changes)

assert t.respond_to?(:todo_ids_changed?)
assert t.respond_to?(:todo_ids_added?)
Expand Down

0 comments on commit dfbc4f7

Please sign in to comment.