Skip to content

Commit 6873df7

Browse files
committed
Group into Row and Default modules
- Row module: Row::Declaration (data), Row::Definition (DSL), Row::Builder (resolves keys and defaults) - Default module: Default::Definition (registers defaults), Default::Context (evaluation scope for default blocks) - Remove separate row_definition.rb, row_builder.rb, default_context.rb
1 parent 4425e28 commit 6873df7

8 files changed

Lines changed: 167 additions & 175 deletions

File tree

lib/fixturebot.rb

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

lib/fixturebot/default.rb

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,43 @@
11
# frozen_string_literal: true
22

33
module FixtureBot
4-
class Default
5-
def initialize(table, defaults)
6-
@defaults = defaults
7-
define_column_methods(table)
4+
module Default
5+
class Definition
6+
def initialize(table, defaults)
7+
@defaults = defaults
8+
define_column_methods(table)
9+
end
10+
11+
private
12+
13+
def define_column_methods(table)
14+
table.columns.each do |col|
15+
define_singleton_method(col) do |&block|
16+
raise ArgumentError, "#{col} requires a block" unless block
17+
@defaults[col] = block
18+
end
19+
end
20+
end
821
end
922

10-
private
23+
class Context
24+
def initialize(record_name:, literal_values: {})
25+
define_name_method(record_name, literal_values)
26+
define_literal_value_methods(literal_values)
27+
end
28+
29+
private
30+
31+
def define_name_method(record_name, literal_values)
32+
define_singleton_method(:name) do
33+
literal_values.key?(:name) ? literal_values[:name] : record_name
34+
end
35+
end
1136

12-
def define_column_methods(table)
13-
table.columns.each do |col|
14-
define_singleton_method(col) do |&block|
15-
raise ArgumentError, "#{col} requires a block" unless block
16-
@defaults[col] = block
37+
def define_literal_value_methods(literal_values)
38+
literal_values.each do |col, val|
39+
next if col == :name
40+
define_singleton_method(col) { val }
1741
end
1842
end
1943
end

lib/fixturebot/default_context.rb

Lines changed: 0 additions & 25 deletions
This file was deleted.

lib/fixturebot/definition.rb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def initialize(schema)
2020
def define_table_method(table)
2121
define_singleton_method(table.singular_name) do |record_name = nil, &block|
2222
if record_name.nil? && block.nil?
23-
Default.new(table, @defaults[table.name])
23+
Default::Definition.new(table, @defaults[table.name])
2424
elsif record_name
2525
add_row(table, record_name, block)
2626
else
@@ -30,14 +30,14 @@ def define_table_method(table)
3030
end
3131

3232
def add_row(table, record_name, block)
33-
row_dsl = RowDefinition.new(table, @schema)
34-
row_dsl.instance_eval(&block) if block
35-
@rows << Row.new(
33+
row_def = Row::Definition.new(table, @schema)
34+
row_def.instance_eval(&block) if block
35+
@rows << Row::Declaration.new(
3636
table: table.name,
3737
name: record_name,
38-
literal_values: row_dsl.literal_values,
39-
association_refs: row_dsl.association_refs,
40-
tag_refs: row_dsl.tag_refs
38+
literal_values: row_def.literal_values,
39+
association_refs: row_def.association_refs,
40+
tag_refs: row_def.tag_refs
4141
)
4242
end
4343
end

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 = RowBuilder.new(
14+
builder = Row::Builder.new(
1515
row: row,
1616
table: schema.tables[row.table],
1717
defaults: definition.defaults[row.table],

lib/fixturebot/row.rb

Lines changed: 125 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,129 @@
11
# frozen_string_literal: true
22

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

lib/fixturebot/row_builder.rb

Lines changed: 0 additions & 79 deletions
This file was deleted.

lib/fixturebot/row_definition.rb

Lines changed: 0 additions & 49 deletions
This file was deleted.

0 commit comments

Comments
 (0)