activeshepherd 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,11 @@
1
+ class ActiveShepherd::ChangesValidator
2
+ attr_reader :errors, :record
3
+
4
+ def initialize(record)
5
+ @record = record
6
+ end
7
+
8
+ def validate(changes)
9
+ @errors = []
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class ActiveShepherd::ClassValidator
2
+ attr_reader :errors, :klass
3
+
4
+ def initialize(klass)
5
+ @klass = klass
6
+ @erros = []
7
+ end
8
+
9
+ def validate
10
+ end
11
+ end
@@ -0,0 +1,22 @@
1
+ class ActiveShepherd::DeepReverseChanges < Struct.new(:changes)
2
+ def reverse
3
+ changer = ->(h) {
4
+ unless h.is_a?(Hash)
5
+ binding.pry
6
+ end
7
+ h.each_with_object({}) do |(k,v), new_hash|
8
+ if v.is_a?(Array) && v.size == 2
9
+ new_hash[k] = [v.last, v.first]
10
+ elsif v.is_a?(Hash)
11
+ new_hash[k] = changer.call(v)
12
+ elsif :_create == k.to_sym
13
+ new_hash[:_destroy] = v
14
+ elsif :_destroy == k.to_sym
15
+ new_hash[:_create] = v
16
+ end
17
+ end
18
+ }
19
+
20
+ changer.call(changes)
21
+ end
22
+ end
@@ -0,0 +1,81 @@
1
+ module ActiveShepherd
2
+ class Method
3
+ attr_reader :associations, :attributes
4
+
5
+ def self.inherited(base)
6
+ # If you're looking for magic, you've come to the right place
7
+ return unless base.name.match /Methods::/
8
+ apply_or_query, state_or_changes = base.name.demodulize.underscore.split('_', 2)
9
+ method_name = "#{apply_or_query}_#{state_or_changes}"
10
+ action_proc = ->(*args) { new(*args).send(method_name) }
11
+ base.singleton_class.send :define_method, method_name, &action_proc
12
+ end
13
+
14
+ attr_reader :aggregate
15
+
16
+ def initialize(*args)
17
+ @aggregate = args.shift
18
+ @associations = {}
19
+ @attributes = {}
20
+
21
+ setup *args
22
+ end
23
+
24
+ def recurse(model, foreign_key)
25
+ Aggregate.new model, foreign_key
26
+ end
27
+
28
+ def traverse!
29
+ Traversal.new(
30
+ self,
31
+ attributes: attributes,
32
+ associations: associations,
33
+ ).traverse
34
+ end
35
+ end
36
+
37
+ class QueryMethod < ActiveShepherd::Method
38
+ attr_reader :query
39
+
40
+ def initialize(*args)
41
+ super
42
+ @query = {}
43
+ end
44
+
45
+ def setup
46
+ @associations = aggregate.traversable_associations
47
+ end
48
+ end
49
+
50
+ class ApplyMethod < ActiveShepherd::Method
51
+ attr_reader :meta_action
52
+
53
+ def create?
54
+ meta_action == :_create
55
+ end
56
+
57
+ def destroy?
58
+ meta_action == :_destroy
59
+ end
60
+
61
+ def setup(hash)
62
+ hash.each do |key, value|
63
+ traversable_association = aggregate.traversable_associations[key]
64
+ if traversable_association.present?
65
+ associations[key] = [traversable_association, value]
66
+ elsif aggregate.untraversable_association_names.include? key
67
+ elsif [:_create, :_destroy].include? key
68
+ @meta_action = key
69
+ elsif aggregate.raw_attributes.keys.include? key.to_s
70
+ attributes[key] = value
71
+ else
72
+ raise ActiveShepherd::AggregateMismatchError, "Attribute `#{key}' "\
73
+ "invalid for `#{aggregate.model.class.name}'"
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ # Set up namespace for the method classes
80
+ Methods = Module.new
81
+ end
@@ -0,0 +1,53 @@
1
+ class ActiveShepherd::Methods::ApplyChanges < ActiveShepherd::ApplyMethod
2
+ def apply_changes
3
+ aggregate.model.mark_for_destruction if destroy?
4
+ traverse!
5
+ end
6
+
7
+ def handle_attribute(attribute_name, before_and_after)
8
+ before, after = before_and_after
9
+ current_value = aggregate.model.send(attribute_name)
10
+
11
+ before = aggregate.deserialize_value(attribute_name, before)
12
+ after = aggregate.deserialize_value(attribute_name, after)
13
+
14
+ unless current_value == before
15
+ raise ::ActiveShepherd::AggregateRoot::BadChangeError, "Expecting "\
16
+ "`#{attribute_name} to be `#{before.inspect}', not "\
17
+ "`#{current_value.inspect}'"
18
+ end
19
+
20
+ aggregate.model.send "#{attribute_name}=", after
21
+ end
22
+
23
+ def handle_has_many_association(reflection, collection_changes)
24
+ apply_changes_to_has_many_association reflection, collection_changes
25
+ end
26
+
27
+ def handle_has_one_association(reflection, changes)
28
+ associated_model = aggregate.model.public_send reflection.name
29
+ self.class.apply_changes recurse(associated_model, reflection.foreign_key),
30
+ changes
31
+ end
32
+
33
+ private
34
+
35
+ def apply_changes_to_has_many_association(reflection, collection_changes)
36
+ association = aggregate.model.send reflection.name
37
+
38
+ collection_changes.each do |index, changes|
39
+ # FIXME
40
+ association.build until association.size >= (index + 1)
41
+ # /FIXME
42
+
43
+ associated_model = association[index]
44
+ if associated_model.nil?
45
+ raise ::ActiveShepherd::AggregateRoot::BadChangeError,
46
+ "Can't find record ##{index}"
47
+ end
48
+ self.class.apply_changes recurse(associated_model, reflection.foreign_key),
49
+ changes
50
+ end
51
+ end
52
+ end
53
+
@@ -0,0 +1,58 @@
1
+ class ActiveShepherd::Methods::ApplyState < ActiveShepherd::ApplyMethod
2
+ def apply_state
3
+ mark_all_associated_objects_for_destruction
4
+ apply_default_state_to_root_model
5
+ traverse!
6
+ end
7
+
8
+ def handle_attribute(attribute_name, raw_value)
9
+ value = aggregate.deserialize_value attribute_name, raw_value
10
+ aggregate.model.send "#{attribute_name}=", value
11
+ end
12
+
13
+ def handle_has_many_association(reflection, collection_state)
14
+ association = aggregate.model.send reflection.name
15
+ collection_state.each do |state|
16
+ associated_model = association.build
17
+ self.class.apply_state recurse(associated_model, reflection.foreign_key),
18
+ state
19
+ end
20
+ end
21
+
22
+ def handle_has_one_association(reflection, state)
23
+ associated_model = aggregate.model.send "build_#{reflection.name}"
24
+ self.class.apply_state recurse(associated_model, reflection.foreign_key),
25
+ state
26
+ end
27
+
28
+ private
29
+
30
+ def apply_default_state_to_root_model
31
+ default_attributes = aggregate.default_attributes
32
+ ignored_attribute_names = attributes.keys.map(&:to_s) + aggregate.excluded_attributes
33
+
34
+ (default_attributes.keys - ignored_attribute_names).each do |attribute_name|
35
+ current_value = aggregate.model.attributes[attribute_name]
36
+ default_value = default_attributes[attribute_name]
37
+
38
+ unless aggregate.deserialize_value(attribute_name, default_value) == default_value
39
+ raise 'Have not handled this use case yet; serialized attributes with a default value'
40
+ end
41
+
42
+ next if default_value == current_value
43
+
44
+ aggregate.model.send("#{attribute_name}=", default_value)
45
+ end
46
+ end
47
+
48
+ def mark_all_associated_objects_for_destruction
49
+ aggregate.traversable_associations.each do |name, association_reflection|
50
+ if association_reflection.macro == :has_many
51
+ aggregate.model.send(name).each { |record| record.mark_for_destruction }
52
+ elsif association_reflection.macro == :has_one
53
+ aggregate.model.send(name).try(&:mark_for_destruction)
54
+ end
55
+ end
56
+ end
57
+ end
58
+
@@ -0,0 +1,53 @@
1
+ class ActiveShepherd::Methods::QueryChanges < ActiveShepherd::QueryMethod
2
+ def query_changes
3
+ traverse!
4
+ set_meta_action
5
+ query
6
+ end
7
+
8
+ def handle_attribute(attribute_name, before, after)
9
+ query[attribute_name] = [before, after]
10
+ end
11
+
12
+ def handle_has_many_association(reflection)
13
+ association = aggregate.model.send reflection.name
14
+
15
+ collection_changes = association.each.with_object({}).with_index do |(associated_model, h), index|
16
+ changes = self.class.query_changes recurse(associated_model, reflection.foreign_key)
17
+ h[index] = changes unless changes.blank?
18
+ end
19
+
20
+ unless collection_changes.blank?
21
+ query[reflection.name] = collection_changes
22
+ end
23
+ end
24
+
25
+ def handle_has_one_association(reflection)
26
+ associated_model = aggregate.model.send reflection.name
27
+ return unless associated_model.present?
28
+
29
+ changes = self.class.query_changes recurse(associated_model, reflection.foreign_key)
30
+ query[reflection.name] = changes unless changes.blank?
31
+ end
32
+
33
+ def setup
34
+ super
35
+ @attributes = aggregate.model.changes.each_with_object({}) do |(name,changes),h|
36
+ next if aggregate.excluded_attributes.include? name.to_s
37
+ h[name.to_sym] = changes.map do |raw_value|
38
+ aggregate.serialize_value name, raw_value
39
+ end
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def set_meta_action
46
+ if not aggregate.model.persisted?
47
+ query[:_create] = '1'
48
+ elsif aggregate.model.marked_for_destruction?
49
+ query[:_destroy] = '1'
50
+ end
51
+ end
52
+ end
53
+
@@ -0,0 +1,38 @@
1
+ class ActiveShepherd::Methods::QueryState < ActiveShepherd::QueryMethod
2
+ def query_state
3
+ traverse!
4
+ query
5
+ end
6
+
7
+ def handle_attribute(name, value)
8
+ query[name] = value
9
+ end
10
+
11
+ def handle_has_many_association(reflection)
12
+ association = aggregate.model.send reflection.name
13
+ collection_state = association.map do |associated_model|
14
+ self.class.query_state recurse(associated_model, reflection.foreign_key)
15
+ end
16
+ query[reflection.name] = collection_state unless collection_state.blank?
17
+ end
18
+
19
+ def handle_has_one_association(reflection)
20
+ associated_model = aggregate.model.send reflection.name
21
+ if associated_model
22
+ state = self.class.query_state recurse(associated_model, reflection.foreign_key)
23
+ query[reflection.name] = state unless state.blank?
24
+ end
25
+ end
26
+
27
+ def setup
28
+ super
29
+ @attributes = aggregate.raw_attributes.each_with_object({}) do |(name,raw),h|
30
+ next if aggregate.excluded_attributes.include? name
31
+ value = aggregate.serialize_value name, raw
32
+ unless value == aggregate.default_attributes[name]
33
+ h[name.to_sym] = value
34
+ end
35
+ end
36
+ end
37
+ end
38
+
@@ -0,0 +1,34 @@
1
+ class ActiveShepherd::Traversal
2
+ attr_reader :attributes, :associations, :visitor
3
+
4
+ def initialize(visitor, params = {})
5
+ @associations = params[:associations]
6
+ @attributes = params[:attributes]
7
+ @visitor = visitor
8
+ end
9
+
10
+ def traverse
11
+ attributes.each do |attribute_name, object|
12
+ visit :handle_attribute, attribute_name, object
13
+ end
14
+
15
+ associations.each do |name, (reflection, object)|
16
+ if reflection.macro == :has_many
17
+ visit :handle_has_many_association, reflection, object
18
+ elsif reflection.macro == :has_one
19
+ visit :handle_has_one_association, reflection, object
20
+ end
21
+ end
22
+ end
23
+
24
+ def visit(method_name, arg1, arg2)
25
+ if visitor.respond_to? method_name
26
+ if visitor.method(method_name).arity == 2
27
+ visitor.public_send method_name, arg1, arg2
28
+ else
29
+ visitor.public_send method_name, arg1, *Array.wrap(arg2)
30
+ end
31
+ end
32
+ end
33
+ end
34
+
@@ -0,0 +1,3 @@
1
+ module ActiveShepherd
2
+ VERSION = "0.8.0"
3
+ end
@@ -0,0 +1 @@
1
+ require 'active_shepherd'
data/tags ADDED
@@ -0,0 +1,123 @@
1
+ !_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
2
+ !_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
3
+ !_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
4
+ !_TAG_PROGRAM_NAME Exuberant Ctags //
5
+ !_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
6
+ !_TAG_PROGRAM_VERSION 5.8 //
7
+ ActiveShepherd lib/active_shepherd.rb /^module ActiveShepherd ; end$/;" m
8
+ ActiveShepherd lib/active_shepherd.rb /^module ActiveShepherd$/;" m
9
+ ActiveShepherd lib/active_shepherd/active_record_shim.rb /^module ActiveShepherd$/;" m
10
+ ActiveShepherd lib/active_shepherd/aggregate.rb /^class ActiveShepherd::Aggregate$/;" c
11
+ ActiveShepherd lib/active_shepherd/aggregate_root.rb /^module ActiveShepherd::AggregateRoot$/;" m
12
+ ActiveShepherd lib/active_shepherd/apply_changes.rb /^class ActiveShepherd::ApplyChanges < ActiveShepherd::StateMethod$/;" c
13
+ ActiveShepherd lib/active_shepherd/apply_state.rb /^class ActiveShepherd::ApplyState < ActiveShepherd::StateMethod$/;" c
14
+ ActiveShepherd lib/active_shepherd/deep_reverse_changes.rb /^class ActiveShepherd::DeepReverseChanges < Struct.new(:changes)$/;" c
15
+ ActiveShepherd lib/active_shepherd/query_changes.rb /^class ActiveShepherd::QueryChanges < ActiveShepherd::StateMethod$/;" c
16
+ ActiveShepherd lib/active_shepherd/query_state.rb /^class ActiveShepherd::QueryState < ActiveShepherd::StateMethod$/;" c
17
+ ActiveShepherd lib/active_shepherd/state_method.rb /^class ActiveShepherd::StateMethod$/;" c
18
+ ActiveShepherd lib/active_shepherd/version.rb /^module ActiveShepherd$/;" m
19
+ AggregateTest test/unit/aggregate_test.rb /^class AggregateTest < MiniTest::Unit::TestCase$/;" c
20
+ ClassMethods lib/active_shepherd/aggregate_root.rb /^ module ClassMethods$/;" m class:ActiveShepherd
21
+ Comment test/setup_test_models.rb /^class Comment < ActiveRecord::Base$/;" c
22
+ IntegrationTest test/integration/project_todo_scenario_test.rb /^class IntegrationTest < MiniTest::Unit::TestCase$/;" c
23
+ Project test/setup_test_models.rb /^class Project < ActiveRecord::Base$/;" c
24
+ Project test/setup_test_models.rb /^class Project::Comment < Comment$/;" c
25
+ Project test/setup_test_models.rb /^class Project::Detail < ActiveRecord::Base$/;" c
26
+ Project test/setup_test_models.rb /^class Project::Todo < ActiveRecord::Base$/;" c
27
+ Project test/setup_test_models.rb /^class Project::TodoAssignment < ActiveRecord::Base$/;" c
28
+ Project test/setup_test_models.rb /^class Project::TodoList < ActiveRecord::Base$/;" c
29
+ able_to_act_as_aggregate_root? lib/active_shepherd/active_record_shim.rb /^ def able_to_act_as_aggregate_root?$/;" f class:ActiveShepherd.enable
30
+ act_as_aggregate_root! lib/active_shepherd/active_record_shim.rb /^ def act_as_aggregate_root!$/;" f class:ActiveShepherd.enable
31
+ add_changes_on_association lib/active_shepherd/query_changes.rb /^ def add_changes_on_association(association_reflection)$/;" f class:ActiveShepherd
32
+ add_changes_on_associations lib/active_shepherd/query_changes.rb /^ def add_changes_on_associations$/;" f class:ActiveShepherd
33
+ add_changes_on_has_many_association lib/active_shepherd/query_changes.rb /^ def add_changes_on_has_many_association(name, foreign_key)$/;" f class:ActiveShepherd
34
+ add_changes_on_has_one_association lib/active_shepherd/query_changes.rb /^ def add_changes_on_has_one_association(name, foreign_key)$/;" f class:ActiveShepherd
35
+ add_changes_on_root_model lib/active_shepherd/query_changes.rb /^ def add_changes_on_root_model$/;" f class:ActiveShepherd
36
+ add_state_from_association lib/active_shepherd/query_state.rb /^ def add_state_from_association(name, association_reflection)$/;" f class:ActiveShepherd
37
+ add_state_from_root_model lib/active_shepherd/query_state.rb /^ def add_state_from_root_model$/;" f class:ActiveShepherd
38
+ aggregate_changes lib/active_shepherd/aggregate_root.rb /^ def aggregate_changes$/;" f class:ActiveShepherd
39
+ aggregate_changes= lib/active_shepherd/aggregate_root.rb /^ def aggregate_changes=(changes)$/;" f class:ActiveShepherd
40
+ aggregate_state lib/active_shepherd/aggregate_root.rb /^ def aggregate_state$/;" f class:ActiveShepherd
41
+ aggregate_state= lib/active_shepherd/aggregate_root.rb /^ def aggregate_state=(blob)$/;" f class:ActiveShepherd
42
+ aggro lib/active_shepherd/aggregate_root.rb /^ def aggro$/;" f class:ActiveShepherd
43
+ apply_changes lib/active_shepherd/apply_changes.rb /^ def apply_changes$/;" f class:ActiveShepherd
44
+ apply_changes_to_associated_model lib/active_shepherd/apply_changes.rb /^ def apply_changes_to_associated_model(model, foreign_key, changes)$/;" f class:ActiveShepherd
45
+ apply_changes_to_association lib/active_shepherd/apply_changes.rb /^ def apply_changes_to_association(association_reflection, changes_or_changes_set)$/;" f class:ActiveShepherd
46
+ apply_changes_to_associations lib/active_shepherd/apply_changes.rb /^ def apply_changes_to_associations$/;" f class:ActiveShepherd
47
+ apply_changes_to_attribute lib/active_shepherd/apply_changes.rb /^ def apply_changes_to_attribute(attribute_name, before, after)$/;" f class:ActiveShepherd
48
+ apply_changes_to_has_many_association lib/active_shepherd/apply_changes.rb /^ def apply_changes_to_has_many_association(association_reflection, foreign_key, changes_set)$/;" f class:ActiveShepherd
49
+ apply_changes_to_has_one_association lib/active_shepherd/apply_changes.rb /^ def apply_changes_to_has_one_association(association_reflection, foreign_key, changes)$/;" f class:ActiveShepherd
50
+ apply_changes_to_root_model lib/active_shepherd/apply_changes.rb /^ def apply_changes_to_root_model$/;" f class:ActiveShepherd
51
+ apply_default_state_to_root_model lib/active_shepherd/apply_state.rb /^ def apply_default_state_to_root_model$/;" f class:ActiveShepherd
52
+ apply_state lib/active_shepherd/apply_state.rb /^ def apply_state$/;" f class:ActiveShepherd
53
+ apply_state_to_associated_model lib/active_shepherd/apply_state.rb /^ def apply_state_to_associated_model(associated_model, foreign_key, state)$/;" f class:ActiveShepherd
54
+ apply_state_to_association lib/active_shepherd/apply_state.rb /^ def apply_state_to_association(association_reflection, state)$/;" f class:ActiveShepherd
55
+ apply_state_to_associations lib/active_shepherd/apply_state.rb /^ def apply_state_to_associations$/;" f class:ActiveShepherd
56
+ apply_state_to_has_many_association lib/active_shepherd/apply_state.rb /^ def apply_state_to_has_many_association(association_reflection, foreign_key, state_set)$/;" f class:ActiveShepherd
57
+ apply_state_to_has_one_association lib/active_shepherd/apply_state.rb /^ def apply_state_to_has_one_association(association_reflection, foreign_key, state)$/;" f class:ActiveShepherd
58
+ apply_state_to_root_model lib/active_shepherd/apply_state.rb /^ def apply_state_to_root_model$/;" f class:ActiveShepherd
59
+ association_state lib/active_shepherd/query_state.rb /^ def association_state(name, association_reflection)$/;" f class:ActiveShepherd
60
+ associations lib/active_shepherd/aggregate.rb /^ def associations$/;" f class:ActiveShepherd
61
+ associations lib/active_shepherd/state_method.rb /^ def associations$/;" f class:ActiveShepherd
62
+ attributes lib/active_shepherd/state_method.rb /^ def attributes$/;" f class:ActiveShepherd
63
+ behave_like_an_aggregate? lib/active_shepherd/aggregate_root.rb /^ def behave_like_an_aggregate?$/;" f class:ActiveShepherd.ClassMethods
64
+ build_persisted_state test/integration/project_todo_scenario_test.rb /^ def build_persisted_state$/;" f class:IntegrationTest.test_state_getter_does_not_walk_read_only_associations.test_state_setter_does_not_walk_read_only_associations
65
+ changes lib/active_shepherd/aggregate.rb /^ def changes$/;" f class:ActiveShepherd
66
+ changes= lib/active_shepherd/aggregate.rb /^ def changes=(hash)$/;" f class:ActiveShepherd
67
+ changes_for_associated_model lib/active_shepherd/query_changes.rb /^ def changes_for_associated_model(model, foreign_key)$/;" f class:ActiveShepherd
68
+ deep_reverse_changes lib/active_shepherd.rb /^ def self.deep_reverse_changes(changes)$/;" F class:ActiveShepherd
69
+ default_attributes lib/active_shepherd/aggregate.rb /^ def default_attributes$/;" f class:ActiveShepherd
70
+ deserialize_value lib/active_shepherd/aggregate.rb /^ def deserialize_value(attribute_name, value)$/;" f class:ActiveShepherd
71
+ dump test/setup_test_models.rb /^ def self.dump(fruit)$/;" F class:Project
72
+ enable lib/active_shepherd/active_record_shim.rb /^ def self.enable!(activerecord_base)$/;" F class:ActiveShepherd
73
+ handle_create_or_destroy_keys lib/active_shepherd/apply_changes.rb /^ def handle_create_or_destroy_keys$/;" f class:ActiveShepherd
74
+ included lib/active_shepherd/aggregate_root.rb /^ def self.included(base)$/;" F class:ActiveShepherd
75
+ inherited lib/active_shepherd/state_method.rb /^ def self.inherited(base)$/;" F class:ActiveShepherd
76
+ initialize lib/active_shepherd/aggregate.rb /^ def initialize(model, excluded_attributes = [])$/;" f class:ActiveShepherd
77
+ initialize lib/active_shepherd/state_method.rb /^ def initialize(aggregate, hash = {})$/;" f class:ActiveShepherd
78
+ load test/setup_test_models.rb /^ def self.load(blob)$/;" F class:Project
79
+ mark_all_associated_objects_for_destruction lib/active_shepherd/apply_state.rb /^ def mark_all_associated_objects_for_destruction$/;" f class:ActiveShepherd
80
+ query_changes lib/active_shepherd/query_changes.rb /^ def query_changes$/;" f class:ActiveShepherd
81
+ query_state lib/active_shepherd/query_state.rb /^ def query_state$/;" f class:ActiveShepherd
82
+ reverse lib/active_shepherd/deep_reverse_changes.rb /^ def reverse$/;" f class:ActiveShepherd
83
+ reverse_aggregate_changes= lib/active_shepherd/aggregate_root.rb /^ def reverse_aggregate_changes=(changes)$/;" f class:ActiveShepherd
84
+ reverse_changes test/integration/project_todo_scenario_test.rb /^ def reverse_changes$/;" f class:IntegrationTest.test_state_getter_does_not_walk_read_only_associations.test_state_setter_does_not_walk_read_only_associations
85
+ run_through_serializer lib/active_shepherd/aggregate.rb /^ def run_through_serializer(attribute_name, value, method)$/;" f class:ActiveShepherd
86
+ serialize_value lib/active_shepherd/aggregate.rb /^ def serialize_value(attribute_name, value)$/;" f class:ActiveShepherd
87
+ set_create_or_destroy_keys lib/active_shepherd/query_changes.rb /^ def set_create_or_destroy_keys$/;" f class:ActiveShepherd
88
+ setup test/integration/project_todo_scenario_test.rb /^ def setup$/;" f class:IntegrationTest
89
+ split_hash lib/active_shepherd/state_method.rb /^ def split_hash$/;" f class:ActiveShepherd
90
+ state lib/active_shepherd/aggregate.rb /^ def state$/;" f class:ActiveShepherd
91
+ state= lib/active_shepherd/aggregate.rb /^ def state=(hash)$/;" f class:ActiveShepherd
92
+ state_of_associated_model lib/active_shepherd/query_state.rb /^ def state_of_associated_model(model, foreign_key)$/;" f class:ActiveShepherd
93
+ state_setter_can_set_timestamps test/integration/project_todo_scenario_test.rb /^ def state_setter_can_set_timestamps$/;" f class:IntegrationTest.test_state_getter_does_not_walk_read_only_associations.test_state_setter_does_not_walk_read_only_associations
94
+ test_all_changes_to_associated_objects_show_up_in_aggregate_changes test/integration/project_todo_scenario_test.rb /^ def test_all_changes_to_associated_objects_show_up_in_aggregate_changes$/;" f class:IntegrationTest.test_state_getter_does_not_walk_read_only_associations.test_state_setter_does_not_walk_read_only_associations
95
+ test_applying_changes_shows_up_in_model_and_its_associations test/integration/project_todo_scenario_test.rb /^ def test_applying_changes_shows_up_in_model_and_its_associations$/;" f class:IntegrationTest.test_state_getter_does_not_walk_read_only_associations.test_state_setter_does_not_walk_read_only_associations
96
+ test_applying_reverse_changes_invokes_apply_change_on_the_reverse_hash test/integration/project_todo_scenario_test.rb /^ def test_applying_reverse_changes_invokes_apply_change_on_the_reverse_hash$/;" f class:IntegrationTest.test_state_getter_does_not_walk_read_only_associations.test_state_setter_does_not_walk_read_only_associations
97
+ test_changes_getter_ignores_foreign_key_relationship_to_parent_object test/integration/project_todo_scenario_test.rb /^ def test_changes_getter_ignores_foreign_key_relationship_to_parent_object$/;" f class:IntegrationTest.test_state_getter_does_not_walk_read_only_associations.test_state_setter_does_not_walk_read_only_associations
98
+ test_does_not_walk_associations_to_other_entities test/integration/project_todo_scenario_test.rb /^ def test_does_not_walk_associations_to_other_entities$/;" f class:IntegrationTest
99
+ test_state_changes_getter_and_setter_respect_serialized_attributes test/integration/project_todo_scenario_test.rb /^ def test_state_changes_getter_and_setter_respect_serialized_attributes$/;" f class:IntegrationTest.test_state_getter_does_not_walk_read_only_associations.test_state_setter_does_not_walk_read_only_associations
100
+ test_state_getter_does_not_walk_read_only_associations test/integration/project_todo_scenario_test.rb /^ def test_state_getter_does_not_walk_read_only_associations$/;" f class:IntegrationTest
101
+ test_state_getter_gets_attributes test/integration/project_todo_scenario_test.rb /^ def test_state_getter_gets_attributes$/;" f class:IntegrationTest
102
+ test_state_getter_gets_attributes_on_has_one_associated_object test/integration/project_todo_scenario_test.rb /^ def test_state_getter_gets_attributes_on_has_one_associated_object$/;" f class:IntegrationTest
103
+ test_state_getter_ignores_default_scope_attributes test/integration/project_todo_scenario_test.rb /^ def test_state_getter_ignores_default_scope_attributes$/;" f class:IntegrationTest
104
+ test_state_getter_ignores_foreign_key_relationship_to_parent_object test/integration/project_todo_scenario_test.rb /^ def test_state_getter_ignores_foreign_key_relationship_to_parent_object$/;" f class:IntegrationTest.test_state_getter_does_not_walk_read_only_associations.test_state_setter_does_not_walk_read_only_associations
105
+ test_state_getter_ignores_has_many_through_associations test/integration/project_todo_scenario_test.rb /^ def test_state_getter_ignores_has_many_through_associations$/;" f class:IntegrationTest
106
+ test_state_getter_rejects_id test/integration/project_todo_scenario_test.rb /^ def test_state_getter_rejects_id$/;" f class:IntegrationTest
107
+ test_state_getter_rejects_unpopulated_associations test/integration/project_todo_scenario_test.rb /^ def test_state_getter_rejects_unpopulated_associations$/;" f class:IntegrationTest
108
+ test_state_getter_respects_serialized_attributes test/integration/project_todo_scenario_test.rb /^ def test_state_getter_respects_serialized_attributes$/;" f class:IntegrationTest.test_state_getter_does_not_walk_read_only_associations.test_state_setter_does_not_walk_read_only_associations
109
+ test_state_getter_symbolizes_all_keys test/integration/project_todo_scenario_test.rb /^ def test_state_getter_symbolizes_all_keys$/;" f class:IntegrationTest.test_state_getter_does_not_walk_read_only_associations.test_state_setter_does_not_walk_read_only_associations
110
+ test_state_setter_does_not_walk_read_only_associations test/integration/project_todo_scenario_test.rb /^ def test_state_setter_does_not_walk_read_only_associations$/;" f class:IntegrationTest.test_state_getter_does_not_walk_read_only_associations
111
+ test_state_setter_ignores_has_many_through_associations test/integration/project_todo_scenario_test.rb /^ def test_state_setter_ignores_has_many_through_associations$/;" f class:IntegrationTest
112
+ test_state_setter_marks_existing_associations_for_deletion test/integration/project_todo_scenario_test.rb /^ def test_state_setter_marks_existing_associations_for_deletion$/;" f class:IntegrationTest.test_state_getter_does_not_walk_read_only_associations.test_state_setter_does_not_walk_read_only_associations
113
+ test_state_setter_populates_object_graph test/integration/project_todo_scenario_test.rb /^ def test_state_setter_populates_object_graph$/;" f class:IntegrationTest.test_state_getter_does_not_walk_read_only_associations.test_state_setter_does_not_walk_read_only_associations
114
+ test_state_setter_resets_unsupplied_attributes_to_default test/integration/project_todo_scenario_test.rb /^ def test_state_setter_resets_unsupplied_attributes_to_default$/;" f class:IntegrationTest.test_state_getter_does_not_walk_read_only_associations.test_state_setter_does_not_walk_read_only_associations
115
+ test_state_setter_respects_serialized_attributes test/integration/project_todo_scenario_test.rb /^ def test_state_setter_respects_serialized_attributes$/;" f class:IntegrationTest.test_state_getter_does_not_walk_read_only_associations.test_state_setter_does_not_walk_read_only_associations
116
+ test_state_setter_sets_attributes test/integration/project_todo_scenario_test.rb /^ def test_state_setter_sets_attributes$/;" f class:IntegrationTest
117
+ test_state_setter_sets_attributes_on_has_many_associated_object test/integration/project_todo_scenario_test.rb /^ def test_state_setter_sets_attributes_on_has_many_associated_object$/;" f class:IntegrationTest
118
+ test_state_setter_sets_attributes_on_has_one_associated_object test/integration/project_todo_scenario_test.rb /^ def test_state_setter_sets_attributes_on_has_one_associated_object$/;" f class:IntegrationTest
119
+ traversable_associations lib/active_shepherd/aggregate.rb /^ def traversable_associations$/;" f class:ActiveShepherd
120
+ traverse_association? lib/active_shepherd/aggregate.rb /^ def traverse_association?(association)$/;" f class:ActiveShepherd
121
+ untraversable_association_names lib/active_shepherd/aggregate.rb /^ def untraversable_association_names$/;" f class:ActiveShepherd
122
+ untraversable_associations lib/active_shepherd/aggregate.rb /^ def untraversable_associations$/;" f class:ActiveShepherd
123
+ valid_aggregate_changes? lib/active_shepherd/aggregate_root.rb /^ def valid_aggregate_changes?(changes)$/;" f class:ActiveShepherd