joinfix 0.1.1 → 1.0.0
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/README +157 -85
- data/Rakefile +38 -0
- data/TEST_README +45 -44
- data/lib/joinfix/error.rb +220 -0
- data/lib/joinfix/fixture.rb +3 -4
- data/lib/joinfix/fixtures.rb +107 -145
- data/lib/joinfix/fixtures_class.rb +51 -97
- data/lib/joinfix.rb +118 -84
- data/rails/app/models/group.rb +3 -3
- data/rails/db/migrate/004_create_users.rb +1 -1
- data/rails/db/schema.rb +1 -1
- data/rails/log/development.log +409 -57
- data/rails/log/test.log +350 -23
- data/rails/test/fixtures/groups.yml +2 -1
- data/rails/test/fixtures/users.yml +27 -19
- data/rails/test/unit/user_test.rb +25 -4
- data/test/has_many_test.rb +16 -0
- data/test/joinfix_test.rb +6 -69
- data/test/joinfix_test_suite.rb +1 -1
- metadata +9 -5
- data/test/todo +0 -15
data/lib/joinfix/fixtures.rb
CHANGED
@@ -1,27 +1,67 @@
|
|
1
|
+
# Fixtures objects are essentially nested hashes:
|
2
|
+
#
|
3
|
+
# # A Fixtures is a hash of entry name keys and Fixture values
|
4
|
+
# entry_name:
|
5
|
+
# # A Fixture is a hash of entry fields and values
|
6
|
+
# field: value
|
7
|
+
#
|
8
|
+
# Fixtures also tracks data required for loading entries into the database,
|
9
|
+
# such as table_name and the connection to use. See 'active_record/fixtures.rb'
|
10
|
+
# for more details.
|
11
|
+
#
|
12
|
+
# JoinFix extends Fixtures to track additional information like the ActiveRecord
|
13
|
+
# class modeling the entry data. Using reflection, Fixtures can figure out which fields
|
14
|
+
# in an entry correspond to an association. Entries with association fields are
|
15
|
+
# extracted and turned into join entries. Consider and ActiveRecord class User, with
|
16
|
+
# 'name' as an attribute and a 'groups' association...
|
17
|
+
#
|
18
|
+
# [users.yml]
|
19
|
+
# # This entry will not be extracted as a template because it defines no 'groups'
|
20
|
+
# john:
|
21
|
+
# name: John
|
22
|
+
#
|
23
|
+
# # This entry will be extracted because it defines the 'groups' association
|
24
|
+
# jane:
|
25
|
+
# name: Jane
|
26
|
+
# groups:
|
27
|
+
# - admin_group
|
28
|
+
# - workers
|
29
|
+
#
|
30
|
+
# If you loaded users.yml into a Fixtures...
|
31
|
+
# users = Fixtures.new( ...arguments to load users.yml...)
|
32
|
+
# users.to_hash # => {'john' => ..., 'jane' => ...}
|
33
|
+
# users.templates # => nil
|
34
|
+
#
|
35
|
+
# users.extract_templates
|
36
|
+
# users.to_hash # => {'john' => ...}
|
37
|
+
# users.templates # => {'jane' => ...}
|
38
|
+
#
|
39
|
+
# The entry templates are extended with JoinFix and used to create the join entries.
|
1
40
|
class Fixtures
|
2
|
-
attr_reader :klass, :
|
41
|
+
attr_reader :klass, :association_names, :templates, :fixture_path
|
3
42
|
|
4
43
|
alias join_fix_original_initialize initialize
|
5
|
-
def initialize(*args)
|
44
|
+
def initialize(*args) # :nodoc:
|
6
45
|
join_fix_original_initialize(*args)
|
7
46
|
@klass = Object.const_get(@class_name)
|
8
|
-
|
9
|
-
# default attributes, constructed from reflecting on the active record table
|
10
|
-
@attributes = {}
|
11
|
-
@klass.columns.each do |column|
|
12
|
-
@attributes[column.name] = column.default
|
13
|
-
end
|
14
|
-
|
47
|
+
@association_names = klass.reflect_on_all_associations.collect {|assoc| assoc.name.to_s}
|
15
48
|
@join_configs = {}
|
16
49
|
end
|
17
50
|
|
18
51
|
alias join_fix_original_insert_fixtures insert_fixtures
|
52
|
+
|
53
|
+
# Extends the default method to provide a hook for making join fixtures.
|
54
|
+
# Now insert_fixtures calls Fixtures.make_join_fixtures before calling
|
55
|
+
# the original insert_fixtures method.
|
19
56
|
def insert_fixtures
|
20
|
-
Fixtures.
|
57
|
+
Fixtures.make_join_fixtures if templates.nil?
|
21
58
|
join_fix_original_insert_fixtures
|
22
59
|
end
|
23
60
|
|
24
|
-
|
61
|
+
# Extracts the child entry templates then makes the entries specified
|
62
|
+
# by each template. Does not execute if templates have already been
|
63
|
+
# extracted.
|
64
|
+
def make_child_entries
|
25
65
|
return unless templates.nil?
|
26
66
|
|
27
67
|
extract_templates
|
@@ -30,83 +70,88 @@ class Fixtures
|
|
30
70
|
end
|
31
71
|
end
|
32
72
|
|
33
|
-
|
34
|
-
0
|
35
|
-
# FUTURE!: is this even needed? I don't think so given that all rows are
|
36
|
-
# deleted by delete_existing_fixtures... not sure.
|
37
|
-
# @connection. QUERY FOR NEXT ID
|
38
|
-
end
|
39
|
-
|
73
|
+
# Returns the join configuration (as per JoinFix.configure) for the given association.
|
40
74
|
def join_config(assoc_name)
|
41
75
|
@join_configs[assoc_name] ||= JoinFix.send("configure", klass, assoc_name)
|
42
76
|
end
|
43
77
|
|
44
|
-
|
78
|
+
# Iterates through each entry
|
79
|
+
def each_pair(&block)
|
45
80
|
map { |entry_name, fixture| yield(entry_name, fixture) }
|
46
81
|
end
|
47
82
|
|
83
|
+
# Returns all entries as a hash of {entry_name => entry} pairs
|
48
84
|
def to_hash
|
49
85
|
hash = {}
|
50
|
-
each_pair do |
|
51
|
-
hash[
|
86
|
+
each_pair do |entry_name, entry|
|
87
|
+
hash[entry_name] = entry.to_hash
|
52
88
|
end
|
53
89
|
hash
|
54
90
|
end
|
91
|
+
|
92
|
+
# The initial offset for indexing (ie 0 so that indexing starts at 1).
|
93
|
+
# This method is provided as a hook for overrides if necessary.
|
94
|
+
def primary_key_offset
|
95
|
+
0
|
96
|
+
end
|
55
97
|
|
56
98
|
protected
|
57
99
|
|
58
|
-
|
59
|
-
|
100
|
+
# Extracts template entries. Entries are Fixture objects, essentially a hash of {attribute => value} pairs.
|
101
|
+
# An entry is considered a template if it contains an association attribute. If this is true, then the entry
|
102
|
+
# is removed from self and stored as a template.
|
103
|
+
def extract_templates # :nodoc:
|
60
104
|
@templates = {}
|
61
|
-
|
62
|
-
|
105
|
+
|
106
|
+
# iterate over all entries looking for templates
|
107
|
+
each do |entry_name, fixture|
|
63
108
|
entry = fixture.to_hash
|
64
|
-
|
109
|
+
|
110
|
+
# fixture is a template if it contains an association
|
111
|
+
next if (entry.keys & association_names).empty?
|
65
112
|
@templates[entry_name] = entry
|
66
113
|
end
|
114
|
+
|
115
|
+
# remove template entries
|
67
116
|
delete_if do |entry_name, fixture|
|
68
117
|
@templates.has_key?(entry_name)
|
69
118
|
end
|
70
119
|
end
|
71
120
|
|
72
|
-
|
73
|
-
|
121
|
+
# Makes the specified entry and adds the entry to self if add_entry_on_complete is true.
|
122
|
+
def make_entry(entry_name, entry, add_entry_on_complete) # :nodoc:
|
123
|
+
|
124
|
+
# If the entry is not a hash, then no entry name was specified in the fixture file
|
125
|
+
unless entry.kind_of?(Hash)
|
126
|
+
raise NoEntryNameError.new(self, entry_name, entry)
|
127
|
+
end
|
74
128
|
|
75
|
-
entry = attributes.merge(entry_template)
|
76
129
|
entry.extend JoinFix
|
77
130
|
entry.entry_name = entry_name
|
78
131
|
|
79
|
-
# extract
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
key == "id" || key.kind_of?(Array)
|
85
|
-
end
|
86
|
-
|
87
|
-
# also extract templates for entries that have an array value. These entries indicate a set of
|
88
|
-
# associated entries that should each be joined to the current entry
|
89
|
-
assoc_entries.merge( entry.extract_if { |key, value| value.kind_of?(Array) } )
|
90
|
-
assoc_entries.each_pair do |assoc_name, assoc_array|
|
91
|
-
# ensure that assoc_array is an array of template
|
92
|
-
assoc_array = [assoc_array] unless assoc_array.kind_of?(Array)
|
132
|
+
# extract and construct associated entries
|
133
|
+
associated_entries = entry.extract_if(association_names)
|
134
|
+
associated_entries.each_pair do |assoc_name, associations|
|
135
|
+
# ensure that associations is an array
|
136
|
+
associations = [associations] unless associations.kind_of?(Array)
|
93
137
|
|
94
|
-
#
|
138
|
+
# get the join configuration for the association
|
95
139
|
join_config = join_config(assoc_name)
|
96
140
|
join_table = join_config[:join_table]
|
97
141
|
macro = join_config[:macro]
|
98
142
|
|
99
|
-
# pull the polymorphic
|
100
|
-
# beforehand what table they will join to
|
143
|
+
# pull the polymorphic join information out of the entry -- polymorphic joins cannot determine
|
144
|
+
# beforehand what table they will join to; the associable_type MUST be specified in the entry.
|
101
145
|
if join_config[:polymorphic] == true
|
102
|
-
|
146
|
+
# be sure to preserve the base configuration...
|
147
|
+
join_config = join_config.dup
|
103
148
|
|
104
149
|
associable_type = join_config[:associable_type]
|
105
150
|
associable_class = entry[associable_type]
|
106
151
|
|
107
152
|
unless associable_class
|
108
|
-
raise MissingPolymorphicTypeError.new(self, entry_name,
|
109
|
-
|
153
|
+
raise MissingPolymorphicTypeError.new(self, entry_name, entry.merge(associated_entries),
|
154
|
+
"No <#{associable_type}> was specified.")
|
110
155
|
end
|
111
156
|
|
112
157
|
join_config[:child_class] = associable_class
|
@@ -114,16 +159,16 @@ class Fixtures
|
|
114
159
|
end
|
115
160
|
|
116
161
|
# raise an error if the macro doesn't allow for multiple joins, but multiple associated entries are specified
|
117
|
-
unless
|
118
|
-
raise MultipleChildrenError.new(self, entry_name,
|
162
|
+
unless associations.length == 1 || JoinFix.macro_allows_multiple(macro)
|
163
|
+
raise MultipleChildrenError.new(self, entry_name, entry.merge(associated_entries),
|
119
164
|
"Multiple joined entries specified for the single-join macro '#{macro}'.")
|
120
165
|
end
|
121
166
|
|
122
|
-
|
123
|
-
#
|
167
|
+
associations.each do |template|
|
168
|
+
# String templates are references to another entry. Make a dummy template with a dummy JoinFix.
|
124
169
|
template = {template => JoinFix.new(template)} if template.kind_of?(String)
|
125
170
|
|
126
|
-
#
|
171
|
+
# Make the entries specified in the template
|
127
172
|
template.each_pair do |child_name, child|
|
128
173
|
# generate the child entry
|
129
174
|
child_fixture = Fixtures.fixture(join_config[:child_table])
|
@@ -131,12 +176,10 @@ class Fixtures
|
|
131
176
|
|
132
177
|
# generate the join entry
|
133
178
|
join = entry.send("join_#{macro}", child, join_config)
|
134
|
-
|
135
|
-
|
136
|
-
#
|
137
|
-
# join entry will be processed according to the wizard modules specified for the join table.
|
179
|
+
Fixtures.fixture(join_table).make_entry(join.entry_name, join, true) if join
|
180
|
+
|
181
|
+
# add the child entry
|
138
182
|
child_fixture.add_entry(child_name, child)
|
139
|
-
Fixtures.fixture(join_table).make_entry(join.entry_name, join, true) if join
|
140
183
|
end
|
141
184
|
end
|
142
185
|
end
|
@@ -145,17 +188,11 @@ class Fixtures
|
|
145
188
|
add_entry(entry_name, entry) if add_entry_on_complete
|
146
189
|
entry
|
147
190
|
end
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
# remove any attributes that are equal to their default
|
154
|
-
entry.delete_if do |attribute, value|
|
155
|
-
default = attributes[attribute]
|
156
|
-
value == default
|
157
|
-
end
|
158
|
-
|
191
|
+
|
192
|
+
# Adds the specified entry to self, or merges entry attributes into the
|
193
|
+
# existing entry. Raises an error in the case of an entry attribute collision
|
194
|
+
# (ie an existing attribute does not equal the new attribute).
|
195
|
+
def add_entry(entry_name, entry) # :nodoc:
|
159
196
|
# create a new fixture if one by the entry_name doesn't exist
|
160
197
|
existing = self[entry_name] ||= Fixture.new({}, klass.class_name)
|
161
198
|
|
@@ -169,78 +206,3 @@ class Fixtures
|
|
169
206
|
end
|
170
207
|
end
|
171
208
|
end
|
172
|
-
|
173
|
-
class MakeEntryError < RuntimeError # :nodoc:
|
174
|
-
attr_reader :fixtures, :entry_name, :entry, :msg
|
175
|
-
attr_accessor :advice
|
176
|
-
|
177
|
-
def initialize(fixtures, entry_name, entry, msg=nil)
|
178
|
-
@fixtures = fixtures
|
179
|
-
@entry_name = entry_name
|
180
|
-
@entry = entry
|
181
|
-
@msg =msg
|
182
|
-
end
|
183
|
-
|
184
|
-
def message
|
185
|
-
"Error making <#{fixtures.klass.table_name}(:#{entry_name})> in <#{fixtures.fixture_path}>.\n" +
|
186
|
-
{entry_name => entry}.to_yaml +
|
187
|
-
(msg.nil? ? '' : "\n#{msg}\n") +
|
188
|
-
(advice.nil? ? '' : "#{advice}\n")
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
class EntryCollisionError < MakeEntryError # :nodoc:
|
193
|
-
end
|
194
|
-
|
195
|
-
class NoEntryNameError < MakeEntryError # :nodoc:
|
196
|
-
def advice
|
197
|
-
%Q{
|
198
|
-
This error occurs when an entry is not named as in:
|
199
|
-
---
|
200
|
-
dog:
|
201
|
-
title: Dog
|
202
|
-
author:
|
203
|
-
# <an entry name like 'ferlinghetti' is missing here>
|
204
|
-
full_name: Lawrence Ferlinghetti
|
205
|
-
...}
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
|
-
class MultipleChildrenError < MakeEntryError # :nodoc:
|
210
|
-
def advice
|
211
|
-
%Q{
|
212
|
-
Single entry joins should specify a single entry, not an array of entries.
|
213
|
-
Use a different association if you need multiple joined entries.
|
214
|
-
---
|
215
|
-
poem:
|
216
|
-
title: Slave's Dream
|
217
|
-
author:
|
218
|
-
longfellow:
|
219
|
-
full_name: Henry Wadsworth Longfellow}
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
class MissingPolymorphicTypeError < MakeEntryError # :nodoc:
|
224
|
-
def advice
|
225
|
-
%Q{
|
226
|
-
When specifying a belongs_to :polymorphic join, the type
|
227
|
-
of the joined entry must be specified because it cannot be
|
228
|
-
inferred from association itself. Use something like:
|
229
|
-
--
|
230
|
-
book_I_read:
|
231
|
-
opinion: Great!
|
232
|
-
readable_type: Book
|
233
|
-
readable:
|
234
|
-
the_jungle_books:
|
235
|
-
author: Rudyard Kipling
|
236
|
-
title: The Jungle Books
|
237
|
-
|
238
|
-
poem_I_read:
|
239
|
-
opinion: Essential!
|
240
|
-
readable_type: Poem
|
241
|
-
readable:
|
242
|
-
sea_fever:
|
243
|
-
poet: John Masefield
|
244
|
-
title: Sea-Fever}
|
245
|
-
end
|
246
|
-
end
|
@@ -1,26 +1,45 @@
|
|
1
1
|
class Fixtures
|
2
|
-
# Class methods to tie fixture joining into the standard process for generating fixtures.
|
3
2
|
class << self
|
4
3
|
|
5
|
-
#
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
# Makes join fixtures for all loaded fixtures. Called just prior to inserting
|
5
|
+
# fixtures, after all fixtures have been loaded.
|
6
|
+
#
|
7
|
+
# After make_join_fixtures completes, entries for tables matching ENV['joinfix_dump']
|
8
|
+
# are printed to STDOUT. You can print entries for each loaded fixture by setting
|
9
|
+
# ENV['joinfix_dump'] = 'true'. By default, no entries are printed.
|
10
|
+
#
|
11
|
+
# Note: printing does not affect the creation or loading of fixtures.
|
12
|
+
def make_join_fixtures
|
10
13
|
all_loaded_fixtures.each_pair do |table_name, fixtures|
|
11
|
-
fixtures.
|
14
|
+
fixtures.make_child_entries
|
12
15
|
end
|
16
|
+
|
13
17
|
# note indexing and reference resolution must execute after all
|
14
18
|
# fixtures have been templated because you never know which fixture(s)
|
15
19
|
# will recieve new entries. Additionally, indexing and resolution must
|
16
|
-
# run separately, because reference resolution requires the
|
17
|
-
|
20
|
+
# run separately, because reference resolution requires the primary key
|
21
|
+
# be set for the referenced entry.
|
18
22
|
all_loaded_fixtures.values.each {|fixtures| index_fixtures(fixtures) }
|
19
23
|
all_loaded_fixtures.values.each {|fixtures| resolve_references(fixtures)}
|
24
|
+
|
25
|
+
# Print entries to STDOUT for review, if applicable
|
26
|
+
joinfix_dump = ENV['joinfix_dump']
|
27
|
+
if joinfix_dump
|
28
|
+
print_all = (joinfix_dump.to_s =~ /^true$/i)
|
29
|
+
regexp = Regexp.new(joinfix_dump.to_s)
|
30
|
+
|
31
|
+
all_loaded_fixtures.values.each do |fixtures|
|
32
|
+
table_name = fixtures.klass.table_name
|
33
|
+
next unless print_all || table_name =~ regexp
|
34
|
+
|
35
|
+
puts "------- #{fixtures.klass.table_name} --------"
|
36
|
+
puts fixtures.to_hash.to_yaml.gsub(/^---/, '') + "\n"
|
37
|
+
end
|
38
|
+
end
|
20
39
|
end
|
21
40
|
|
22
|
-
# Retreives the
|
23
|
-
# not yet been loaded.
|
41
|
+
# Retreives the Fixtures for the given table name. Raises an error if this Fixtures
|
42
|
+
# has not yet been loaded.
|
24
43
|
def fixture(table_name)
|
25
44
|
fixture = all_loaded_fixtures[table_name.to_s]
|
26
45
|
raise MissingFixtureError.new(table_name) unless fixture
|
@@ -29,26 +48,25 @@ class Fixtures
|
|
29
48
|
|
30
49
|
protected
|
31
50
|
|
32
|
-
# Sets the primary key in each of the input
|
33
|
-
|
34
|
-
|
51
|
+
# Sets the primary key for entries in each of the input Fixtures, beginning
|
52
|
+
# one past the Fixtures primary key offset (ie 1). Skips entries that already
|
53
|
+
# have a primary key assigned.
|
54
|
+
def index_fixtures(fixtures) # :nodoc:
|
35
55
|
id = fixtures.klass.primary_key
|
36
56
|
|
37
|
-
#
|
57
|
+
# find entries with the primary key and record these so that they will be skipped
|
38
58
|
skip_indicies = []
|
39
59
|
fixtures.each_pair do |name, fixture|
|
40
60
|
skip_indicies << fixture[id].to_i if fixture.has_key?(id)
|
41
61
|
end
|
42
62
|
|
43
|
-
#
|
44
|
-
index = fixtures.
|
63
|
+
# find and index entries that do not have a primary key defined
|
64
|
+
index = fixtures.primary_key_offset
|
45
65
|
fixtures.each_pair do |name, fixture|
|
46
|
-
# skip entries that already have an id defined
|
47
66
|
next if fixture.has_key?(id)
|
48
67
|
|
49
|
-
# find the next available index
|
50
|
-
|
51
|
-
# in case index 1 is marked for skipping
|
68
|
+
# find the next available index. Note this must happen before
|
69
|
+
# the assignment, in case '1' is marked for skipping
|
52
70
|
while true
|
53
71
|
index += 1
|
54
72
|
break unless skip_indicies.include?(index)
|
@@ -58,24 +76,17 @@ class Fixtures
|
|
58
76
|
end
|
59
77
|
end
|
60
78
|
|
61
|
-
# Resolves
|
62
|
-
def resolve_references(fixtures)
|
63
|
-
fixtures.each_pair do |entry_name,
|
64
|
-
|
65
|
-
fixture.each_pair do |join_ref, join_name|
|
79
|
+
# Resolves join references in the input Fixtures.
|
80
|
+
def resolve_references(fixtures) # :nodoc:
|
81
|
+
fixtures.each_pair do |entry_name, entry|
|
82
|
+
entry.each_pair do |join_ref, join_name|
|
66
83
|
# next if the key isn't a join reference
|
67
84
|
next unless join_ref.kind_of?(Array)
|
68
85
|
|
69
86
|
foreign_key = join_ref.first
|
70
87
|
join_table_name = join_ref.last
|
71
|
-
|
72
|
-
|
73
|
-
unless Fixtures.all_loaded_fixtures.has_key?(join_table_name)
|
74
|
-
raise ResolveJoinReferenceError.new(fixtures, entry_name, join_table_name, join_name,
|
75
|
-
"The join table '#{join_table_name}' has not been loaded.")
|
76
|
-
end
|
77
|
-
|
78
|
-
join_fixtures = Fixtures.all_loaded_fixtures[join_table_name]
|
88
|
+
|
89
|
+
join_fixtures = Fixtures.fixture(join_table_name)
|
79
90
|
id = join_fixtures.klass.primary_key
|
80
91
|
|
81
92
|
# raise an error if the join entry isn't in the join table; the reference cannot be resolved
|
@@ -86,82 +97,25 @@ class Fixtures
|
|
86
97
|
|
87
98
|
join_entry = join_fixtures[join_name]
|
88
99
|
|
89
|
-
# raise an exception if
|
100
|
+
# raise an exception if the primary key for the join entry is not set
|
90
101
|
unless join_entry.has_key?(id)
|
91
102
|
raise ResolveJoinReferenceError.new(fixtures, entry_name, join_table_name, join_name,
|
92
103
|
"No #{id} present in join entry '#{join_name}'.")
|
93
104
|
end
|
94
105
|
|
95
106
|
# raise an exception if the foreign key is already set
|
96
|
-
unless
|
107
|
+
unless entry[foreign_key].nil?
|
97
108
|
raise ForeignKeySetError.new(fixtures, entry_name, join_table_name, join_name,
|
98
109
|
"Foreign key <#{foreign_key}> is already set!")
|
99
110
|
end
|
100
111
|
|
101
|
-
# set the
|
102
|
-
|
112
|
+
# set the foreign key to the joined entry primary key
|
113
|
+
entry[foreign_key] = join_entry[id]
|
103
114
|
end
|
104
115
|
|
105
116
|
# delete the join references
|
106
|
-
|
117
|
+
entry.delete_if {|key,value| key.kind_of?(Array) }
|
107
118
|
end
|
108
119
|
end
|
109
120
|
end
|
110
|
-
end
|
111
|
-
|
112
|
-
class MissingFixtureError < RuntimeError # :nodoc:
|
113
|
-
attr_reader :table_name
|
114
|
-
def initialize(table_name)
|
115
|
-
@table_name = table_name
|
116
|
-
end
|
117
|
-
|
118
|
-
def message
|
119
|
-
"No fixture loaded for <#{table_name}>\n" +
|
120
|
-
(advice.nil? ? '' : "#{advice}\n")
|
121
|
-
end
|
122
|
-
|
123
|
-
def advice
|
124
|
-
%Q{}
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
class ResolveJoinReferenceError < RuntimeError # :nodoc:
|
129
|
-
attr_reader :fixtures, :entry_name, :join_table_name, :join_name, :msg
|
130
|
-
attr_accessor :advice
|
131
|
-
|
132
|
-
def initialize(fixtures, entry_name, join_table_name, join_name, msg=nil)
|
133
|
-
@fixtures = fixtures
|
134
|
-
@entry_name = entry_name
|
135
|
-
@join_table_name = join_table_name
|
136
|
-
@join_name = join_name
|
137
|
-
@msg =msg
|
138
|
-
end
|
139
|
-
|
140
|
-
def message
|
141
|
-
"Cannot resolve reference to <#{join_table_name}(:#{join_name})> " +
|
142
|
-
"for <#{fixtures.klass.table_name}(:#{entry_name})> " +
|
143
|
-
"in <#{fixtures.fixture_path}>.\n" +
|
144
|
-
(msg.nil? ? '' : "\n#{msg}\n") +
|
145
|
-
(advice.nil? ? '' : "#{advice}\n")
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
class ForeignKeySetError < ResolveJoinReferenceError # :nodoc:
|
150
|
-
def advice
|
151
|
-
%Q{
|
152
|
-
This error occurs when you specifiy the foreign key, as well as a join entry.
|
153
|
-
---
|
154
|
-
poem:
|
155
|
-
title: Poetry of Departures
|
156
|
-
author_id: 8
|
157
|
-
author: larkin
|
158
|
-
|
159
|
-
If you need to specify the foreign key, do so within the entry.
|
160
|
-
---
|
161
|
-
poem:
|
162
|
-
title: Poetry of Departures
|
163
|
-
author:
|
164
|
-
larkin:
|
165
|
-
id: 8}
|
166
|
-
end
|
167
|
-
end
|
121
|
+
end
|