joinfix 0.1.0 → 0.1.1

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.
Files changed (40) hide show
  1. data/README +1 -1
  2. data/lib/joinfix/fixtures.rb +130 -155
  3. data/lib/joinfix/fixtures_class.rb +95 -30
  4. data/lib/joinfix.rb +108 -45
  5. data/rails/log/development.log +71 -0
  6. data/rails/log/test.log +85 -0
  7. data/rails/test/test_helper.rb +1 -0
  8. data/test/belongs_to_polymorphic_test.rb +78 -0
  9. data/test/belongs_to_test.rb +135 -44
  10. data/test/belongs_to_with_options_test.rb +57 -0
  11. data/test/has_and_belongs_to_many_test.rb +36 -36
  12. data/test/has_and_belongs_to_many_with_options_test.rb +84 -0
  13. data/test/has_many_as_test.rb +66 -0
  14. data/test/has_many_test.rb +33 -69
  15. data/test/has_many_through_test.rb +79 -0
  16. data/test/has_many_through_with_options_test.rb +85 -0
  17. data/test/has_many_with_options_test.rb +63 -0
  18. data/test/has_one_test.rb +26 -27
  19. data/test/has_one_with_options_test.rb +57 -0
  20. data/test/joinfix_test.rb +5 -5
  21. data/test/joinfix_test_helper.rb +76 -16
  22. data/test/missing_fixture_test.rb +54 -0
  23. data/test/nested_test.rb +13 -6
  24. data/test/todo +15 -0
  25. metadata +48 -51
  26. data/test/fixtures/as_children.yml +0 -0
  27. data/test/fixtures/bt_children.yml +0 -0
  28. data/test/fixtures/bt_parents.yml +0 -30
  29. data/test/fixtures/habtm_children.yml +0 -0
  30. data/test/fixtures/habtm_children_habtm_parents.yml +0 -0
  31. data/test/fixtures/habtm_joins.yml +0 -0
  32. data/test/fixtures/habtm_parents.yml +0 -18
  33. data/test/fixtures/hm_children.yml +0 -0
  34. data/test/fixtures/hm_joins.yml +0 -0
  35. data/test/fixtures/hm_parents.yml +0 -34
  36. data/test/fixtures/ho_children.yml +0 -0
  37. data/test/fixtures/ho_parents.yml +0 -14
  38. data/test/fixtures/no_join_fixes.yml +0 -4
  39. data/test/fixtures/omap_no_join_fixes.yml +0 -7
  40. data/test/fixtures/polymorphic_children.yml +0 -0
data/lib/joinfix.rb CHANGED
@@ -6,15 +6,111 @@ require 'joinfix/fixture'
6
6
 
7
7
  # The actual JoinFix module contains methods managing joins. In practice, JoinFix
8
8
  # extends hashes that contain the entry data. Calls to the join_(type) methods define
9
- # the join using references like 'child_id_ref_child_table' => 'child_entry_name'.
10
- # Later on, these references can be resovled to yield, for example 'child_id' => 12.
9
+ # join references like ['child_id', 'child_table'] => 'child_entry_name'. This reference
10
+ # specifies that 'child_id' should be set to the primary key of 'child_entry_name' in
11
+ # 'child_table'.
11
12
  #
12
13
  # The join methods each take a child entry and a config. The instance calling the join
13
14
  # method is considered the parent entry. References are added where appropriate.
14
15
  # A separate join entry will be returned if required, as for has_and_belongs_to_many
15
16
  # or has_many :through.
17
+ #
18
+ # The configurations required by the join methods can be created from an ActiveRecord::Base
19
+ # class and the name of the association through the +configure+ method.
16
20
  module JoinFix
17
- # Convenience method for setting up a JoinFix.
21
+ class << self
22
+ # Returns true if the input macro allows for multiple joins.
23
+ #
24
+ # [:belongs_to, :has_one] => false
25
+ # [:has_many, :has_and_belongs_to_many] => true
26
+ def macro_allows_multiple(macro)
27
+ case macro.to_sym
28
+ when :belongs_to then false
29
+ when :has_one then false
30
+ when :has_many then true
31
+ when :has_and_belongs_to_many then true
32
+ end
33
+ end
34
+
35
+ def configure(klass, assoc_name)
36
+ association = association(klass, assoc_name)
37
+ send("configure_#{association.macro}", klass, association).with_indifferent_access
38
+ end
39
+
40
+ protected
41
+
42
+ def association(klass, assoc_name)
43
+ association = klass.reflect_on_association(assoc_name.to_sym)
44
+ raise ArgumentError, "Unknown association '#{assoc_name}' for '#{klass}'." unless association
45
+ association.check_validity!
46
+ association
47
+ end
48
+
49
+ def configure_belongs_to(klass, association)
50
+ join_config = {
51
+ :parent_table => klass.table_name,
52
+ :macro => association.macro,
53
+ :foreign_key => association.primary_key_name
54
+ }
55
+
56
+ if association.options[:polymorphic]
57
+ join_config[:polymorphic] = true
58
+ join_config[:associable] = association.name
59
+ join_config[:associable_type] = "#{association.name}_type"
60
+ else
61
+ join_config[:child_table] = association.table_name
62
+ end
63
+
64
+ join_config
65
+ end
66
+
67
+ def configure_has_one(klass, association)
68
+ join_config = {
69
+ :parent_table => klass.table_name,
70
+ :child_table => association.table_name,
71
+ :macro => association.macro,
72
+ :foreign_key => association.primary_key_name
73
+ }
74
+
75
+ join_config
76
+ end
77
+
78
+ def configure_has_many(klass, association)
79
+ join_config = {
80
+ :parent_table => klass.table_name,
81
+ :child_table => association.table_name,
82
+ :macro => association.macro,
83
+ :foreign_key => association.primary_key_name
84
+ }
85
+
86
+ if association.options[:as]
87
+ join_config[:as] = association.options[:as]
88
+ join_config[:parent_class] = klass.class_name
89
+ elsif association.options[:through]
90
+ join_config[:through] = association.options[:through]
91
+ join_config[:join_table] = association.through_reflection.table_name
92
+ join_config[:foreign_key] = association.through_reflection.primary_key_name
93
+ join_config[:association_foreign_key] = association.source_reflection.primary_key_name
94
+ end
95
+
96
+ join_config
97
+ end
98
+
99
+ def configure_has_and_belongs_to_many(klass, association)
100
+ join_config = {
101
+ :parent_table => klass.table_name,
102
+ :child_table => association.table_name,
103
+ :macro => association.macro,
104
+ :join_table => association.options[:join_table],
105
+ :foreign_key => association.primary_key_name,
106
+ :association_foreign_key => association.association_foreign_key
107
+ }
108
+
109
+ join_config
110
+ end
111
+ end
112
+
113
+ # Convenience method for setting up a JoinFix.
18
114
  def self.new(entry_name, hash={})
19
115
  hash.extend JoinFix
20
116
  hash.entry_name = entry_name
@@ -23,39 +119,6 @@ module JoinFix
23
119
 
24
120
  attr_accessor :entry_name
25
121
 
26
- # FUTURE! bring back if you start running methods
27
- # attr_accessor :addable,
28
- # Addable signifies whether or not the entry can be added as a fixture
29
- # At times processing on an entry is solely to generate other entries
30
- # (for example an entry 'set'). In these cases, set addable to false.
31
- #def addable?
32
- # addable.nil? ? true : addable
33
- #end
34
- #def set(input)
35
- # self.addable = false
36
- # super
37
- #end
38
-
39
- # Keys ending in '_id' and the key 'id' are treated as preserves keys.
40
- # id values will not be removed, or modified.
41
- def self.preserves?(key)
42
- # old version -- /^(.+(_ref_id|_type))|id$/
43
- key.to_s =~ /^(.+_id|id)$/
44
- end
45
-
46
- # Returns true if the input macro allows for multiple joins.
47
- #
48
- # [:belongs_to, :has_one] => false
49
- # [:has_many, :has_and_belongs_to_many] => true
50
- def self.macro_allows_multiple(macro)
51
- case macro.to_sym
52
- when :belongs_to then false
53
- when :has_one then false
54
- when :has_many then true
55
- when :has_and_belongs_to_many then true
56
- end
57
- end
58
-
59
122
  # extract_if extracts values where the key is specified
60
123
  # or returns true when passed to the optional block.
61
124
  def extract_if(keys=[], &block)
@@ -120,8 +183,6 @@ module JoinFix
120
183
  #
121
184
  # Required configurations:
122
185
  # * [:foreign_key, :association_foreign_key, :parent_table, :child_table]
123
- #
124
- # Optionally, :attributes can be supplied as defualts for the join entry
125
186
  def join_has_and_belongs_to_many(entry, config)
126
187
  # produces entries like:
127
188
  # join[foreign_key_ref_parent_table] = self.entry_name
@@ -130,12 +191,14 @@ module JoinFix
130
191
  # join[foreign_key_id] = self.id
131
192
  # join[association_foreign_key_id] = entry.id
132
193
  validate_inclusion(config, :foreign_key, :association_foreign_key, :parent_table, :child_table)
133
-
134
- join = config[:attributes] || {}
135
- join.extend JoinFix
136
- join[[config[:foreign_key], config[:parent_table]]] = self.entry_name
137
- join[[config[:association_foreign_key], config[:child_table]]] = entry.entry_name
138
- join
194
+
195
+ join_entry_name = self.entry_name < entry.entry_name ?
196
+ "#{self.entry_name}_#{entry.entry_name}" :
197
+ "#{entry.entry_name}_#{self.entry_name}"
198
+
199
+ JoinFix.new join_entry_name,
200
+ [config[:foreign_key], config[:parent_table]] => self.entry_name,
201
+ [config[:association_foreign_key], config[:child_table]] => entry.entry_name
139
202
  end
140
203
 
141
204
  # Creates the required key-value pairs for a 'has_many' association between
@@ -149,7 +212,7 @@ module JoinFix
149
212
  # * [:as (=association), :parent_table]
150
213
  #
151
214
  # Required configurations for has_many :through
152
- # * [:through (=join table), :foreign_key, :association_foreign_key, :parent_table, :child_table] and optionally [:attributes]
215
+ # * [:through (=join table), :foreign_key, :association_foreign_key, :parent_table, :child_table]
153
216
  def join_has_many(entry, config)
154
217
  if config[:as]
155
218
  # produces entries like:
@@ -0,0 +1,71 @@
1
+ # Logfile created on Sat May 12 23:25:35 Mountain Daylight Time 2007 by logger.rb/1.5.2.7
2
+ SQL (0.000000) SET SQL_AUTO_IS_NULL=0
3
+ SQL (0.040000) SELECT * FROM schema_info
4
+ SQL (0.010000) SHOW TABLES
5
+ SQL (0.040000) SHOW FIELDS FROM groups
6
+ SQL (0.030000) SHOW KEYS FROM groups
7
+ SQL (0.010000) SHOW FIELDS FROM inner_children
8
+ SQL (0.010000) SHOW KEYS FROM inner_children
9
+ SQL (0.030000) SHOW FIELDS FROM nested_children
10
+ SQL (0.010000) SHOW KEYS FROM nested_children
11
+ SQL (0.020000) SHOW FIELDS FROM nested_parents
12
+ SQL (0.020000) SHOW KEYS FROM nested_parents
13
+ SQL (0.230000) SHOW FIELDS FROM user_groups
14
+ SQL (0.010000) SHOW KEYS FROM user_groups
15
+ SQL (0.030000) SHOW FIELDS FROM users
16
+ SQL (0.010000) SHOW KEYS FROM users
17
+ SQL (0.000000) SET SQL_AUTO_IS_NULL=0
18
+ SQL (0.621000) DROP DATABASE IF EXISTS `joinfix_test`
19
+ SQL (0.451000) CREATE DATABASE `joinfix_test`
20
+ SQL (0.000000) SET SQL_AUTO_IS_NULL=0
21
+ SQL (0.000000) Mysql::Error: Unknown table 'groups': DROP TABLE groups
22
+ SQL (0.130000) CREATE TABLE groups (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `name` varchar(255) DEFAULT NULL) ENGINE=InnoDB
23
+ SQL (0.000000) Mysql::Error: Unknown table 'inner_children': DROP TABLE inner_children
24
+ SQL (0.100000) CREATE TABLE inner_children (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `field` varchar(255) DEFAULT NULL, `nested_child_id` int(11) DEFAULT NULL) ENGINE=InnoDB
25
+ SQL (0.000000) Mysql::Error: Unknown table 'nested_children': DROP TABLE nested_children
26
+ SQL (0.151000) CREATE TABLE nested_children (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `field` varchar(255) DEFAULT NULL, `nested_parent_id` int(11) DEFAULT NULL) ENGINE=InnoDB
27
+ SQL (0.000000) Mysql::Error: Unknown table 'nested_parents': DROP TABLE nested_parents
28
+ SQL (0.140000) CREATE TABLE nested_parents (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `field` varchar(255) DEFAULT NULL, `inner_child_id` int(11) DEFAULT NULL) ENGINE=InnoDB
29
+ SQL (0.000000) Mysql::Error: Unknown table 'user_groups': DROP TABLE user_groups
30
+ SQL (0.260000) CREATE TABLE user_groups (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `user_id` int(11) DEFAULT NULL, `group_id` int(11) DEFAULT NULL) ENGINE=InnoDB
31
+ SQL (0.000000) Mysql::Error: Unknown table 'users': DROP TABLE users
32
+ SQL (0.120000) CREATE TABLE users (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `login` varchar(255) DEFAULT NULL) ENGINE=InnoDB
33
+ SQL (0.141000) CREATE TABLE schema_info (version int(11))
34
+ SQL (0.060000) INSERT INTO schema_info (version) VALUES(0)
35
+ SQL (0.010000) SHOW FIELDS FROM schema_info
36
+ SQL (0.070000) UPDATE schema_info SET version = 6
37
+ SQL (0.021000) SET SQL_AUTO_IS_NULL=0
38
+ SQL (0.120000) SELECT * FROM schema_info
39
+ SQL (0.020000) SHOW TABLES
40
+ SQL (0.100000) SHOW FIELDS FROM groups
41
+ SQL (0.040000) SHOW KEYS FROM groups
42
+ SQL (0.110000) SHOW FIELDS FROM inner_children
43
+ SQL (0.030000) SHOW KEYS FROM inner_children
44
+ SQL (0.040000) SHOW FIELDS FROM nested_children
45
+ SQL (0.030000) SHOW KEYS FROM nested_children
46
+ SQL (0.080000) SHOW FIELDS FROM nested_parents
47
+ SQL (0.020000) SHOW KEYS FROM nested_parents
48
+ SQL (0.040000) SHOW FIELDS FROM user_groups
49
+ SQL (0.030000) SHOW KEYS FROM user_groups
50
+ SQL (0.061000) SHOW FIELDS FROM users
51
+ SQL (0.020000) SHOW KEYS FROM users
52
+ SQL (0.020000) SET SQL_AUTO_IS_NULL=0
53
+ SQL (0.601000) DROP DATABASE IF EXISTS `joinfix_test`
54
+ SQL (0.230000) CREATE DATABASE `joinfix_test`
55
+ SQL (0.020000) SET SQL_AUTO_IS_NULL=0
56
+ SQL (0.000000) Mysql::Error: #42S02Unknown table 'groups': DROP TABLE groups
57
+ SQL (0.111000) CREATE TABLE groups (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `name` varchar(255) DEFAULT NULL) ENGINE=InnoDB
58
+ SQL (0.000000) Mysql::Error: #42S02Unknown table 'inner_children': DROP TABLE inner_children
59
+ SQL (0.120000) CREATE TABLE inner_children (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `field` varchar(255) DEFAULT NULL, `nested_child_id` int(11) DEFAULT NULL) ENGINE=InnoDB
60
+ SQL (0.000000) Mysql::Error: #42S02Unknown table 'nested_children': DROP TABLE nested_children
61
+ SQL (0.110000) CREATE TABLE nested_children (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `field` varchar(255) DEFAULT NULL, `nested_parent_id` int(11) DEFAULT NULL) ENGINE=InnoDB
62
+ SQL (0.000000) Mysql::Error: #42S02Unknown table 'nested_parents': DROP TABLE nested_parents
63
+ SQL (0.130000) CREATE TABLE nested_parents (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `field` varchar(255) DEFAULT NULL, `inner_child_id` int(11) DEFAULT NULL) ENGINE=InnoDB
64
+ SQL (0.000000) Mysql::Error: #42S02Unknown table 'user_groups': DROP TABLE user_groups
65
+ SQL (0.190000) CREATE TABLE user_groups (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `user_id` int(11) DEFAULT NULL, `group_id` int(11) DEFAULT NULL) ENGINE=InnoDB
66
+ SQL (0.000000) Mysql::Error: #42S02Unknown table 'users': DROP TABLE users
67
+ SQL (0.101000) CREATE TABLE users (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `login` varchar(255) DEFAULT NULL) ENGINE=InnoDB
68
+ SQL (0.110000) CREATE TABLE schema_info (version int(11))
69
+ SQL (0.060000) INSERT INTO schema_info (version) VALUES(0)
70
+ SQL (0.050000) SHOW FIELDS FROM schema_info
71
+ SQL (0.150000) UPDATE schema_info SET version = 6
@@ -0,0 +1,85 @@
1
+ # Logfile created on Sat May 12 23:25:48 Mountain Daylight Time 2007 by logger.rb/1.5.2.7
2
+ SQL (0.000000) SET SQL_AUTO_IS_NULL=0
3
+ SQL (0.000000) BEGIN
4
+ SQL (0.000000) ROLLBACK
5
+ SQL (0.000000) BEGIN
6
+ SQL (0.000000) ROLLBACK
7
+ SQL (0.000000) BEGIN
8
+ NestedChild Load (0.000000) SELECT * FROM nested_children WHERE (nested_children.`id` = 1) 
9
+ NestedChild Load (0.010000) SELECT * FROM nested_children WHERE (nested_children.`field` = 3) LIMIT 1
10
+ SQL (0.000000) ROLLBACK
11
+ SQL (0.000000) BEGIN
12
+ NestedParent Load (0.000000) SELECT * FROM nested_parents WHERE (nested_parents.`id` = 4) 
13
+ NestedParent Load (0.000000) SELECT * FROM nested_parents WHERE (nested_parents.`id` = 1) 
14
+ NestedParent Load (0.000000) SELECT * FROM nested_parents WHERE (nested_parents.`id` = 3) 
15
+ NestedParent Load (0.000000) SELECT * FROM nested_parents WHERE (nested_parents.`id` = 2) 
16
+ NestedChild Load (0.000000) SELECT * FROM nested_children WHERE (nested_children.`field` = 1) LIMIT 1
17
+ NestedParent Load (0.000000) SELECT * FROM nested_parents WHERE (nested_parents.`id` = 4) 
18
+ NestedParent Load (0.000000) SELECT * FROM nested_parents WHERE (nested_parents.`field` = 1) LIMIT 1
19
+ NestedChild Load (0.000000) SELECT * FROM nested_children WHERE (nested_children.nested_parent_id = 4) 
20
+ InnerChild Load (0.000000) SELECT * FROM inner_children WHERE (inner_children.nested_child_id = 2) 
21
+ NestedParent Load (0.000000) SELECT * FROM nested_parents WHERE (nested_parents.inner_child_id = 2) 
22
+ NestedParent Load (0.000000) SELECT * FROM nested_parents WHERE (nested_parents.`field` = 1) LIMIT 1
23
+ InnerChild Load (0.000000) SELECT * FROM inner_children WHERE (inner_children.`id` = 3) 
24
+ NestedChild Load (0.010000) SELECT * FROM nested_children WHERE (nested_children.`id` = 3) 
25
+ NestedParent Load (0.000000) SELECT * FROM nested_parents WHERE (nested_parents.`id` = 1) 
26
+ InnerChild Load (0.000000) SELECT * FROM inner_children WHERE (inner_children.`field` = 3) LIMIT 1
27
+ NestedParent Load (0.000000) SELECT * FROM nested_parents WHERE (nested_parents.inner_child_id = 1) 
28
+ SQL (0.000000) ROLLBACK
29
+ SQL (0.000000) BEGIN
30
+ SQL (0.010000) ROLLBACK
31
+ SQL (0.000000) BEGIN
32
+ User Load (0.000000) SELECT * FROM users WHERE (users.`id` = 2) 
33
+ Group Load (0.020000) SELECT groups.* FROM groups INNER JOIN user_groups ON groups.id = user_groups.group_id WHERE ((user_groups.user_id = 2)) 
34
+ User Load (0.000000) SELECT * FROM users WHERE (users.`login` = 'jane') LIMIT 1
35
+ SQL (0.000000) SELECT count(*) AS count_all FROM groups INNER JOIN user_groups ON groups.id = user_groups.group_id WHERE ((user_groups.user_id = 3)) 
36
+ UserGroup Load (0.000000) SELECT * FROM user_groups WHERE (user_groups.`id` = 2) 
37
+ UserGroup Load (0.000000) SELECT * FROM user_groups WHERE (user_groups.`id` = 2) 
38
+ User Load (0.000000) SELECT * FROM users WHERE (users.`id` = 3) 
39
+ User Load (0.010000) SELECT * FROM users WHERE (users.`id` = 1) 
40
+ User Load (0.000000) SELECT * FROM users WHERE (users.`login` = 'sam') LIMIT 1
41
+ Group Load (0.000000) SELECT groups.* FROM groups INNER JOIN user_groups ON groups.id = user_groups.group_id WHERE ((user_groups.user_id = 1)) AND (groups.`name` = 'movers') LIMIT 1
42
+ User Load (0.000000) SELECT users.* FROM users INNER JOIN user_groups ON users.id = user_groups.user_id WHERE ((user_groups.group_id = 3)) 
43
+ SQL (0.000000) ROLLBACK
44
+ SQL (0.000000) SET SQL_AUTO_IS_NULL=0
45
+ SQL (0.000000) BEGIN
46
+ SQL (0.000000) ROLLBACK
47
+ SQL (0.000000) BEGIN
48
+ SQL (0.000000) ROLLBACK
49
+ SQL (0.000000) BEGIN
50
+ NestedChild Load (0.000000) SELECT * FROM nested_children WHERE (nested_children.`id` = 1) 
51
+ NestedChild Load (0.000000) SELECT * FROM nested_children WHERE (nested_children.`field` = 3) LIMIT 1
52
+ SQL (0.000000) ROLLBACK
53
+ SQL (0.000000) BEGIN
54
+ NestedParent Load (0.000000) SELECT * FROM nested_parents WHERE (nested_parents.`id` = 4) 
55
+ NestedParent Load (0.000000) SELECT * FROM nested_parents WHERE (nested_parents.`id` = 1) 
56
+ NestedParent Load (0.000000) SELECT * FROM nested_parents WHERE (nested_parents.`id` = 3) 
57
+ NestedParent Load (0.000000) SELECT * FROM nested_parents WHERE (nested_parents.`id` = 2) 
58
+ NestedChild Load (0.000000) SELECT * FROM nested_children WHERE (nested_children.`field` = 1) LIMIT 1
59
+ NestedParent Load (0.000000) SELECT * FROM nested_parents WHERE (nested_parents.`id` = 4) 
60
+ NestedParent Load (0.000000) SELECT * FROM nested_parents WHERE (nested_parents.`field` = 1) LIMIT 1
61
+ NestedChild Load (0.000000) SELECT * FROM nested_children WHERE (nested_children.nested_parent_id = 4) 
62
+ InnerChild Load (0.060000) SELECT * FROM inner_children WHERE (inner_children.nested_child_id = 2) 
63
+ NestedParent Load (0.030000) SELECT * FROM nested_parents WHERE (nested_parents.inner_child_id = 2) 
64
+ NestedParent Load (0.000000) SELECT * FROM nested_parents WHERE (nested_parents.`field` = 1) LIMIT 1
65
+ InnerChild Load (0.000000) SELECT * FROM inner_children WHERE (inner_children.`id` = 3) 
66
+ NestedChild Load (0.000000) SELECT * FROM nested_children WHERE (nested_children.`id` = 3) 
67
+ NestedParent Load (0.000000) SELECT * FROM nested_parents WHERE (nested_parents.`id` = 1) 
68
+ InnerChild Load (0.000000) SELECT * FROM inner_children WHERE (inner_children.`field` = 3) LIMIT 1
69
+ NestedParent Load (0.000000) SELECT * FROM nested_parents WHERE (nested_parents.inner_child_id = 1) 
70
+ SQL (0.000000) ROLLBACK
71
+ SQL (0.000000) BEGIN
72
+ SQL (0.000000) ROLLBACK
73
+ SQL (0.000000) BEGIN
74
+ User Load (0.010000) SELECT * FROM users WHERE (users.`id` = 2) 
75
+ Group Load (0.060000) SELECT groups.* FROM groups INNER JOIN user_groups ON groups.id = user_groups.group_id WHERE ((user_groups.user_id = 2)) 
76
+ User Load (0.000000) SELECT * FROM users WHERE (users.`login` = 'jane') LIMIT 1
77
+ SQL (0.010000) SELECT count(*) AS count_all FROM groups INNER JOIN user_groups ON groups.id = user_groups.group_id WHERE ((user_groups.user_id = 3)) 
78
+ UserGroup Load (0.000000) SELECT * FROM user_groups WHERE (user_groups.`id` = 2) 
79
+ UserGroup Load (0.000000) SELECT * FROM user_groups WHERE (user_groups.`id` = 2) 
80
+ User Load (0.000000) SELECT * FROM users WHERE (users.`id` = 3) 
81
+ User Load (0.000000) SELECT * FROM users WHERE (users.`id` = 1) 
82
+ User Load (0.000000) SELECT * FROM users WHERE (users.`login` = 'sam') LIMIT 1
83
+ Group Load (0.000000) SELECT groups.* FROM groups INNER JOIN user_groups ON groups.id = user_groups.group_id WHERE ((user_groups.user_id = 1)) AND (groups.`name` = 'movers') LIMIT 1
84
+ User Load (0.000000) SELECT users.* FROM users INNER JOIN user_groups ON users.id = user_groups.user_id WHERE ((user_groups.group_id = 4)) 
85
+ SQL (0.000000) ROLLBACK
@@ -1,6 +1,7 @@
1
1
  ENV["RAILS_ENV"] = "test"
2
2
  require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
3
3
  require 'test_help'
4
+ require 'gemdev'
4
5
  require 'joinfix'
5
6
 
6
7
  class Test::Unit::TestCase
@@ -0,0 +1,78 @@
1
+ require File.dirname(__FILE__) + '/joinfix_test_helper'
2
+
3
+ #
4
+ # polymorphic
5
+ #
6
+
7
+ class BelongsToPolymorphicMigration < ActiveRecord::Migration
8
+ def self.up
9
+ create_table :bt_polymorphics do |t|
10
+ t.column :field, :string
11
+ t.column :polymorph_id, :integer
12
+ t.column :polymorph_type, :string
13
+ end
14
+ create_table :bt_children do |t|
15
+ t.column :field, :string
16
+ end
17
+ create_table :polymorphic_children do |t|
18
+ t.column :field, :string
19
+ end
20
+ end
21
+
22
+ def self.down
23
+ drop_table :bt_polymorphics
24
+ drop_table :bt_children
25
+ drop_table :polymorphic_children
26
+ end
27
+ end
28
+
29
+ class BtPolymorphic < ActiveRecord::Base
30
+ belongs_to :polymorph,
31
+ :polymorphic => true
32
+ end
33
+
34
+ class PolymorphicChild < ActiveRecord::Base
35
+ has_many :bt_parents,
36
+ :as => :polymorph
37
+ end
38
+
39
+ class BelongsToPolymorphicTest < Test::Unit::TestCase
40
+ fixtures :bt_polymorphics, :polymorphic_children
41
+
42
+ def test_belongs_to_polymorphic
43
+ setup_fixtures(
44
+ :bt_polymorphics => %Q{
45
+ parent_entry:
46
+ field: parent value
47
+ polymorph_type: PolymorphicChild
48
+ polymorph:
49
+ child_entry:
50
+ field: child value},
51
+ :polymorphic_children => "")
52
+
53
+ assert_fixtures(
54
+ :bt_polymorphics => %Q{
55
+ parent_entry:
56
+ id: 1
57
+ polymorph_id: 1
58
+ polymorph_type: PolymorphicChild
59
+ field: parent value},
60
+ :polymorphic_children => %Q{
61
+ child_entry:
62
+ id: 1
63
+ field: child value})
64
+ end
65
+
66
+ def test_error_if_polymorphic_type_is_mising
67
+ error_test(MissingPolymorphicTypeError) do
68
+ setup_fixtures(
69
+ :bt_polymorphics => %Q{
70
+ parent_entry:
71
+ field: parent value
72
+ polymorph:
73
+ child_entry:
74
+ field: child value},
75
+ :polymorphic_children => "")
76
+ end
77
+ end
78
+ end
@@ -1,77 +1,168 @@
1
1
  require File.dirname(__FILE__) + '/joinfix_test_helper'
2
2
 
3
- class BtMigration < ActiveRecord::Migration
3
+ #
4
+ # belongs_to test
5
+ #
6
+
7
+ class BelongsToMigration < ActiveRecord::Migration
4
8
  def self.up
5
9
  create_table :bt_parents do |t|
6
10
  t.column :field, :string
7
11
  t.column :bt_child_id, :integer
8
- t.column :alt_id, :integer
9
- t.column :polymorph_id, :integer
10
- t.column :polymorph_type, :string
11
12
  end
12
13
  create_table :bt_children do |t|
13
14
  t.column :field, :string
14
15
  end
15
- create_table :polymorphic_children do |t|
16
- t.column :field, :string
17
- end
18
16
  end
19
17
 
20
18
  def self.down
21
19
  drop_table :bt_parents
22
20
  drop_table :bt_children
23
- drop_table :polymorphic_children
24
21
  end
25
22
  end
26
23
 
27
24
  class BtParent < ActiveRecord::Base
28
25
  belongs_to :bt_child
29
- belongs_to :child,
30
- :foreign_key => "alt_id",
31
- :class_name => "BtChild"
32
-
33
- belongs_to :polymorph,
34
- :polymorphic => true
35
26
  end
36
27
 
37
28
  class BtChild < ActiveRecord::Base
38
29
  end
39
30
 
40
- class PolymorphicChild < ActiveRecord::Base
41
- has_many :bt_parents,
42
- :as => :polymorph
43
- end
44
-
45
31
  class BelongsToTest < Test::Unit::TestCase
46
- fixtures :bt_parents, :bt_children, :polymorphic_children
32
+ fixtures :bt_parents, :bt_children
33
+
34
+ def test_belongs_to_without_child
35
+ setup_fixtures(
36
+ :bt_parents => %Q{
37
+ parent_entry:
38
+ field: parent value},
39
+ :bt_children => "")
40
+
41
+ assert_fixtures(
42
+ :bt_parents => %Q{
43
+ parent_entry:
44
+ id: 1
45
+ field: parent value},
46
+ :bt_children => "")
47
+ end
48
+
49
+ def test_belongs_to_with_child
50
+ setup_fixtures(
51
+ :bt_parents => %Q{
52
+ parent_entry:
53
+ field: parent value
54
+ bt_child:
55
+ child_entry:
56
+ field: child value},
57
+ :bt_children => "")
58
+
59
+ assert_fixtures(
60
+ :bt_parents => %Q{
61
+ parent_entry:
62
+ id: 1
63
+ bt_child_id: 1
64
+ field: parent value},
65
+ :bt_children => %Q{
66
+ child_entry:
67
+ id: 1
68
+ field: child value})
69
+ end
47
70
 
48
- def setup
71
+ def test_entries_merge_attributes_from_multiple_definitions
72
+ setup_fixtures(
73
+ :bt_parents => %Q{
74
+ parent_entry:
75
+ field: parent value
76
+ bt_child: child_entry},
77
+ :bt_children => %Q{
78
+ child_entry:
79
+ field: child value})
80
+
81
+ assert_fixtures(
82
+ :bt_parents => %Q{
83
+ parent_entry:
84
+ id: 1
85
+ bt_child_id: 1
86
+ field: parent value},
87
+ :bt_children => %Q{
88
+ child_entry:
89
+ id: 1
90
+ field: child value})
91
+ end
92
+
93
+ def test_id_respected_when_given
94
+ setup_fixtures(
95
+ :bt_parents => %Q{
96
+ parent_entry:
97
+ id: 10
98
+ bt_child: child_entry},
99
+ :bt_children => %Q{
100
+ child_entry:
101
+ id: 12})
102
+
103
+ assert_fixtures(
104
+ :bt_parents => %Q{
105
+ parent_entry:
106
+ id: 10
107
+ bt_child_id: 12},
108
+ :bt_children => %Q{
109
+ child_entry:
110
+ id: 12})
111
+ end
112
+
113
+ def test_error_if_foreign_key_is_already_set
114
+ error_test(ForeignKeySetError) do
115
+ setup_fixtures(
116
+ :bt_parents => %Q{
117
+ parent_entry:
118
+ id: 1
119
+ bt_child_id: 1
120
+ bt_child:
121
+ child_entry:
122
+ field: child value},
123
+ :bt_children => "")
124
+ end
125
+ end
126
+
127
+ def test_error_for_entry_collision
128
+ error_test(EntryCollisionError) do
129
+ setup_fixtures(
130
+ :bt_parents => %Q{
131
+ parent_entry:
132
+ id: 1
133
+ bt_child:
134
+ child_entry:
135
+ field: collision value},
136
+ :bt_children => %Q{
137
+ child_entry:
138
+ field: existing value
139
+ })
140
+ end
49
141
  end
50
142
 
51
- def teardown
143
+ def test_error_for_missing_entry_name
144
+ error_test(NoEntryNameError) do
145
+ setup_fixtures(
146
+ :bt_parents => %Q{
147
+ parent_entry:
148
+ id: 1
149
+ bt_child:
150
+ field: child value},
151
+ :bt_children => %Q{})
152
+ end
52
153
  end
53
154
 
54
- def test_belongs_to
55
- database_test(BtMigration) do
56
- entry = bt_parents(:without_child)
57
- assert_equal "without_child", entry.field
58
- assert_nil entry.bt_child
59
- assert_nil entry.child
60
-
61
- entry = bt_parents(:with_bt_child)
62
- assert_equal "with_bt_child", entry.field
63
- assert_equal "1", entry.bt_child.field
64
- assert_nil entry.child
65
-
66
- entry = bt_parents(:with_child)
67
- assert_equal "with_child", entry.field
68
- assert_nil entry.bt_child
69
- assert_equal "2", entry.child.field
70
-
71
- entry = bt_parents(:with_both)
72
- assert_equal "with_both", entry.field
73
- assert_equal "3", entry.bt_child.field
74
- assert_equal "4", entry.child.field
155
+ def test_error_for_belongs_to_with_multiple_associations
156
+ error_test(MultipleChildrenError) do
157
+ setup_fixtures(
158
+ :bt_parents => %Q{
159
+ parent_entry:
160
+ bt_child:
161
+ - child_one:
162
+ field: 1
163
+ - child_two:
164
+ field: 2},
165
+ :bt_children => %Q{})
75
166
  end
76
167
  end
77
- end
168
+ end