Skip to content

Commit 4425e28

Browse files
committed
Flatten class nesting back to separate files
Keep Row, RowDefinition, RowBuilder, Default, DefaultContext as top-level classes under FixtureBot instead of nesting inside Row and Default. Simpler for a library.
1 parent bb848b3 commit 4425e28

8 files changed

Lines changed: 159 additions & 147 deletions

File tree

lib/fixturebot.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
require_relative "fixturebot/schema"
55
require_relative "fixturebot/key"
66
require_relative "fixturebot/default"
7+
require_relative "fixturebot/default_context"
78
require_relative "fixturebot/row"
9+
require_relative "fixturebot/row_definition"
10+
require_relative "fixturebot/row_builder"
811
require_relative "fixturebot/definition"
912
require_relative "fixturebot/fixture_set"
1013
require_relative "fixturebot/yaml_dumper"

lib/fixturebot/default.rb

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,5 @@ def define_column_methods(table)
1717
end
1818
end
1919
end
20-
21-
class Context
22-
def initialize(record_name:, literal_values: {})
23-
define_name_method(record_name, literal_values)
24-
define_literal_value_methods(literal_values)
25-
end
26-
27-
private
28-
29-
def define_name_method(record_name, literal_values)
30-
define_singleton_method(:name) do
31-
literal_values.key?(:name) ? literal_values[:name] : record_name
32-
end
33-
end
34-
35-
def define_literal_value_methods(literal_values)
36-
literal_values.each do |col, val|
37-
next if col == :name
38-
define_singleton_method(col) { val }
39-
end
40-
end
41-
end
4220
end
4321
end

lib/fixturebot/default_context.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# frozen_string_literal: true
2+
3+
module FixtureBot
4+
class DefaultContext
5+
def initialize(record_name:, literal_values: {})
6+
define_name_method(record_name, literal_values)
7+
define_literal_value_methods(literal_values)
8+
end
9+
10+
private
11+
12+
def define_name_method(record_name, literal_values)
13+
define_singleton_method(:name) do
14+
literal_values.key?(:name) ? literal_values[:name] : record_name
15+
end
16+
end
17+
18+
def define_literal_value_methods(literal_values)
19+
literal_values.each do |col, val|
20+
next if col == :name
21+
define_singleton_method(col) { val }
22+
end
23+
end
24+
end
25+
end

lib/fixturebot/definition.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def define_table_method(table)
3030
end
3131

3232
def add_row(table, record_name, block)
33-
row_dsl = Row::Definition.new(table, @schema)
33+
row_dsl = RowDefinition.new(table, @schema)
3434
row_dsl.instance_eval(&block) if block
3535
@rows << Row.new(
3636
table: table.name,

lib/fixturebot/fixture_set.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def initialize(schema, definition)
1111
schema.join_tables.each_key { |name| @tables[name] = {} }
1212

1313
definition.rows.each do |row|
14-
builder = Row::Builder.new(
14+
builder = RowBuilder.new(
1515
row: row,
1616
table: schema.tables[row.table],
1717
defaults: definition.defaults[row.table],

lib/fixturebot/row.rb

Lines changed: 1 addition & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -1,127 +1,5 @@
11
# frozen_string_literal: true
22

33
module FixtureBot
4-
class Row < Data.define(:table, :name, :literal_values, :association_refs, :tag_refs)
5-
class Definition
6-
attr_reader :literal_values, :association_refs, :tag_refs
7-
8-
def initialize(table, schema)
9-
@literal_values = {}
10-
@association_refs = {}
11-
@tag_refs = {}
12-
13-
define_column_methods(table)
14-
define_association_methods(table)
15-
define_join_table_methods(table, schema)
16-
end
17-
18-
private
19-
20-
def define_column_methods(table)
21-
table.columns.each do |col|
22-
define_singleton_method(col) do |value|
23-
@literal_values[col] = value
24-
end
25-
end
26-
end
27-
28-
def define_association_methods(table)
29-
table.belongs_to_associations.each do |assoc|
30-
define_singleton_method(assoc.name) do |ref|
31-
@association_refs[assoc.name] = ref
32-
end
33-
end
34-
end
35-
36-
def define_join_table_methods(table, schema)
37-
schema.join_tables.each_value do |jt|
38-
if jt.left_table == table.name
39-
define_singleton_method(jt.right_table) do |*refs|
40-
@tag_refs[jt.name] = { table: jt.right_table, refs: refs }
41-
end
42-
elsif jt.right_table == table.name
43-
define_singleton_method(jt.left_table) do |*refs|
44-
@tag_refs[jt.name] = { table: jt.left_table, refs: refs }
45-
end
46-
end
47-
end
48-
end
49-
end
50-
51-
class Builder
52-
def initialize(row:, table:, defaults:, join_tables:)
53-
@row = row
54-
@table = table
55-
@defaults = defaults
56-
@join_tables = join_tables
57-
end
58-
59-
def id
60-
@id ||= Key.generate(@row.table, @row.name)
61-
end
62-
63-
def record
64-
result = { id: id }
65-
@table.columns.each do |col|
66-
if @row.literal_values.key?(col)
67-
result[col] = @row.literal_values[col]
68-
elsif foreign_key_values.key?(col)
69-
result[col] = foreign_key_values[col]
70-
elsif defaulted_values.key?(col)
71-
result[col] = defaulted_values[col]
72-
end
73-
end
74-
result
75-
end
76-
77-
def join_rows
78-
@row.tag_refs.flat_map do |join_table_name, tag_info|
79-
jt = @join_tables[join_table_name]
80-
tag_info[:refs].map do |tag_ref|
81-
build_join_row(jt, tag_info[:table], tag_ref)
82-
end
83-
end
84-
end
85-
86-
private
87-
88-
def build_join_row(jt, other_table, tag_ref)
89-
other_id = Key.generate(other_table, tag_ref)
90-
91-
if jt.left_table == @row.table
92-
{
93-
key: :"#{@row.name}_#{tag_ref}",
94-
join_table: jt.name,
95-
row: { jt.left_foreign_key => id, jt.right_foreign_key => other_id }
96-
}
97-
else
98-
{
99-
key: :"#{tag_ref}_#{@row.name}",
100-
join_table: jt.name,
101-
row: { jt.left_foreign_key => other_id, jt.right_foreign_key => id }
102-
}
103-
end
104-
end
105-
106-
def foreign_key_values
107-
@foreign_key_values ||= @row.association_refs.each_with_object({}) do |(assoc_name, ref), hash|
108-
assoc = @table.belongs_to_associations.find { |a| a.name == assoc_name }
109-
hash[assoc.foreign_key] = Key.generate(assoc.table, ref)
110-
end
111-
end
112-
113-
def defaulted_values
114-
@defaulted_values ||= @defaults.each_with_object({}) do |(col, block), result|
115-
next if @row.literal_values.key?(col)
116-
next if foreign_key_values.key?(col)
117-
118-
context = Default::Context.new(
119-
record_name: @row.name,
120-
literal_values: @row.literal_values
121-
)
122-
result[col] = context.instance_eval(&block)
123-
end
124-
end
125-
end
126-
end
4+
Row = Data.define(:table, :name, :literal_values, :association_refs, :tag_refs)
1275
end

lib/fixturebot/row_builder.rb

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# frozen_string_literal: true
2+
3+
module FixtureBot
4+
class RowBuilder
5+
def initialize(row:, table:, defaults:, join_tables:)
6+
@row = row
7+
@table = table
8+
@defaults = defaults
9+
@join_tables = join_tables
10+
end
11+
12+
def id
13+
@id ||= Key.generate(@row.table, @row.name)
14+
end
15+
16+
def record
17+
result = { id: id }
18+
@table.columns.each do |col|
19+
if @row.literal_values.key?(col)
20+
result[col] = @row.literal_values[col]
21+
elsif foreign_key_values.key?(col)
22+
result[col] = foreign_key_values[col]
23+
elsif defaulted_values.key?(col)
24+
result[col] = defaulted_values[col]
25+
end
26+
end
27+
result
28+
end
29+
30+
def join_rows
31+
@row.tag_refs.flat_map do |join_table_name, tag_info|
32+
jt = @join_tables[join_table_name]
33+
tag_info[:refs].map do |tag_ref|
34+
build_join_row(jt, tag_info[:table], tag_ref)
35+
end
36+
end
37+
end
38+
39+
private
40+
41+
def build_join_row(jt, other_table, tag_ref)
42+
other_id = Key.generate(other_table, tag_ref)
43+
44+
if jt.left_table == @row.table
45+
{
46+
key: :"#{@row.name}_#{tag_ref}",
47+
join_table: jt.name,
48+
row: { jt.left_foreign_key => id, jt.right_foreign_key => other_id }
49+
}
50+
else
51+
{
52+
key: :"#{tag_ref}_#{@row.name}",
53+
join_table: jt.name,
54+
row: { jt.left_foreign_key => other_id, jt.right_foreign_key => id }
55+
}
56+
end
57+
end
58+
59+
def foreign_key_values
60+
@foreign_key_values ||= @row.association_refs.each_with_object({}) do |(assoc_name, ref), hash|
61+
assoc = @table.belongs_to_associations.find { |a| a.name == assoc_name }
62+
hash[assoc.foreign_key] = Key.generate(assoc.table, ref)
63+
end
64+
end
65+
66+
def defaulted_values
67+
@defaulted_values ||= @defaults.each_with_object({}) do |(col, block), result|
68+
next if @row.literal_values.key?(col)
69+
next if foreign_key_values.key?(col)
70+
71+
context = DefaultContext.new(
72+
record_name: @row.name,
73+
literal_values: @row.literal_values
74+
)
75+
result[col] = context.instance_eval(&block)
76+
end
77+
end
78+
end
79+
end

lib/fixturebot/row_definition.rb

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# frozen_string_literal: true
2+
3+
module FixtureBot
4+
class RowDefinition
5+
attr_reader :literal_values, :association_refs, :tag_refs
6+
7+
def initialize(table, schema)
8+
@literal_values = {}
9+
@association_refs = {}
10+
@tag_refs = {}
11+
12+
define_column_methods(table)
13+
define_association_methods(table)
14+
define_join_table_methods(table, schema)
15+
end
16+
17+
private
18+
19+
def define_column_methods(table)
20+
table.columns.each do |col|
21+
define_singleton_method(col) do |value|
22+
@literal_values[col] = value
23+
end
24+
end
25+
end
26+
27+
def define_association_methods(table)
28+
table.belongs_to_associations.each do |assoc|
29+
define_singleton_method(assoc.name) do |ref|
30+
@association_refs[assoc.name] = ref
31+
end
32+
end
33+
end
34+
35+
def define_join_table_methods(table, schema)
36+
schema.join_tables.each_value do |jt|
37+
if jt.left_table == table.name
38+
define_singleton_method(jt.right_table) do |*refs|
39+
@tag_refs[jt.name] = { table: jt.right_table, refs: refs }
40+
end
41+
elsif jt.right_table == table.name
42+
define_singleton_method(jt.left_table) do |*refs|
43+
@tag_refs[jt.name] = { table: jt.left_table, refs: refs }
44+
end
45+
end
46+
end
47+
end
48+
end
49+
end

0 commit comments

Comments
 (0)