diff --git a/lib/dirty_associations/base.rb b/lib/dirty_associations/base.rb new file mode 100644 index 0000000..ddc424c --- /dev/null +++ b/lib/dirty_associations/base.rb @@ -0,0 +1,4 @@ +module DirtyAssociations + class Base + end +end \ No newline at end of file diff --git a/lib/dirty_associations/builder.rb b/lib/dirty_associations/builder.rb index 37e1924..81b3800 100644 --- a/lib/dirty_associations/builder.rb +++ b/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 @@ -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 diff --git a/lib/dirty_associations/collection_methods.rb b/lib/dirty_associations/collection_methods.rb new file mode 100644 index 0000000..3eca6da --- /dev/null +++ b/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 \ No newline at end of file diff --git a/lib/dirty_associations/instance_methods.rb b/lib/dirty_associations/instance_methods.rb index 6b090f3..266cdd9 100644 --- a/lib/dirty_associations/instance_methods.rb +++ b/lib/dirty_associations/instance_methods.rb @@ -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 diff --git a/test/builder_test.rb b/test/builder_test.rb index 5e82ef7..0997e65 100644 --- a/test/builder_test.rb +++ b/test/builder_test.rb @@ -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 @@ -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 \ No newline at end of file diff --git a/test/dirty_associations_test.rb b/test/dirty_associations_test.rb index c746ad2..0fda012 100644 --- a/test/dirty_associations_test.rb +++ b/test/dirty_associations_test.rb @@ -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?)