Class: PgSerializable::Visitors::Json
- Inherits:
-
Base
- Object
- Base
- PgSerializable::Visitors::Json
show all
- Defined in:
- lib/pg_serializable/visitors/json.rb
Instance Method Summary
collapse
-
#visit_association(subject, **kwargs) ⇒ Object
-
#visit_attribute(subject, table_alias: nil) ⇒ Object
-
#visit_belongs_to(subject, table_alias:, **kwargs) ⇒ Object
-
#visit_class(subject, trait: :default, **kwargs) ⇒ Object
-
#visit_enum(subject, table_alias: nil) ⇒ Object
-
#visit_has_and_belongs_to_many(subject, table_alias:, **kwargs) ⇒ Object
-
#visit_has_many(subject, table_alias:, **kwargs) ⇒ Object
-
#visit_has_many_through(subject, table_alias:, **kwargs) ⇒ Object
-
#visit_has_one(subject, table_alias:, **kwargs) ⇒ Object
-
#visit_node(subject, **kwargs) ⇒ Object
-
#visit_record(subject, trait: :default) ⇒ Object
-
#visit_relation(subject, table_alias: nil, trait: :default) ⇒ Object
-
#visit_trait(subject, **kwargs) ⇒ Object
-
#visit_trait_manager(subject, trait: :default, **kwargs) ⇒ Object
Methods inherited from Base
#visit, #visit_method_for, #visit_other, #visit_scope
Instance Method Details
#visit_association(subject, **kwargs) ⇒ Object
65
66
67
|
# File 'lib/pg_serializable/visitors/json.rb', line 65
def visit_association(subject, **kwargs)
send("visit_#{subject.type}", subject, **kwargs)
end
|
#visit_attribute(subject, table_alias: nil) ⇒ Object
46
47
48
49
50
51
52
53
|
# File 'lib/pg_serializable/visitors/json.rb', line 46
def visit_attribute(subject, table_alias: nil)
return visit_enum(subject, table_alias: table_alias) if subject.enum?
table_alias ||= alias_tracker
key = "\'#{subject.label}\'"
column_name = "\"#{table_alias}\".\"#{subject.column_name}\""
val = subject.prc ? subject.prc.call(column_name) : column_name
"#{key}, #{val}"
end
|
#visit_belongs_to(subject, table_alias:, **kwargs) ⇒ Object
69
70
71
72
73
74
75
76
|
# File 'lib/pg_serializable/visitors/json.rb', line 69
def visit_belongs_to(subject, table_alias:, **kwargs)
current_alias = next_alias!
klass = subject.target
select_sql = json_build_object(visit(klass.trait_manager, trait: subject.trait, table_alias: current_alias)).to_sql
query = klass.select(select_sql).from("#{klass.table_name} #{current_alias}")
.where("#{current_alias}.#{subject.primary_key}=#{table_alias}.#{subject.foreign_key}").to_sql
"\'#{subject.label}\', (#{query})"
end
|
#visit_class(subject, trait: :default, **kwargs) ⇒ Object
26
27
28
|
# File 'lib/pg_serializable/visitors/json.rb', line 26
def visit_class(subject, trait: :default, **kwargs)
visit(subject.all, trait: trait, **kwargs)
end
|
#visit_enum(subject, table_alias: nil) ⇒ Object
55
56
57
58
59
60
61
62
63
|
# File 'lib/pg_serializable/visitors/json.rb', line 55
def visit_enum(subject, table_alias: nil)
key = "\'#{subject.label}\'"
enum_hash = subject.klass.defined_enums[subject.column_name.to_s]
val = "CASE \"#{table_alias}\".\"#{subject.column_name}\" " +
enum_hash.map do |val, int|
"WHEN #{int} THEN \'#{subject.prc ? subject.prc.call(val) : val}\'"
end.join(' ') + " ELSE NULL END"
"#{key}, #{val}"
end
|
#visit_has_and_belongs_to_many(subject, table_alias:, **kwargs) ⇒ Object
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
# File 'lib/pg_serializable/visitors/json.rb', line 117
def visit_has_and_belongs_to_many(subject, table_alias:, **kwargs)
current_alias = next_alias!
association = subject.association
join_table = association.join_table
source = association.source_reflection
query = visit(association
.klass
.select("#{source.table_name}.*, #{join_table}.#{source.association_foreign_key}, #{join_table}.#{association.join_primary_key}")
.joins("INNER JOIN #{join_table} ON #{join_table}.#{source.association_foreign_key}=#{source.table_name}.#{source.association_primary_key}"), table_alias: current_alias)
.where("#{current_alias}.#{association.join_primary_key}=#{table_alias}.#{subject.foreign_key}")
.to_sql
"\'#{subject.label}\', (#{query})"
end
|
#visit_has_many(subject, table_alias:, **kwargs) ⇒ Object
78
79
80
81
82
83
84
85
86
87
88
89
|
# File 'lib/pg_serializable/visitors/json.rb', line 78
def visit_has_many(subject, table_alias:, **kwargs)
return visit_has_many_through(subject, table_alias: table_alias, **kwargs) if subject.association.through_reflection?
current_alias = next_alias!
klass = subject.target
select_sql = coalesce(json_agg(json_build_object(visit(klass.trait_manager, trait: subject.trait, table_alias: current_alias)))).to_sql
query = klass.select(select_sql).from("#{klass.table_name} #{current_alias}")
.where("#{current_alias}.#{subject.primary_key}=#{table_alias}.#{subject.foreign_key}").to_sql
"\'#{subject.label}\', (#{query})"
end
|
#visit_has_many_through(subject, table_alias:, **kwargs) ⇒ Object
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
# File 'lib/pg_serializable/visitors/json.rb', line 91
def visit_has_many_through(subject, table_alias:, **kwargs)
current_alias = next_alias!
association = subject.association
through = association.through_reflection
source = association.source_reflection
join_name = source.collection? ? through.plural_name.to_sym : through.name
where_clause = begin
if source.belongs_to?
"#{table_alias}.#{through.join_foreign_key}=#{through.table_name}.#{through.join_primary_key}"
elsif through.belongs_to?
"#{table_alias}.#{through.join_foreign_key}=#{through.table_name}.#{subject.foreign_key}"
else
"#{through.table_name}.#{through.join_foreign_key}=#{table_alias}.#{subject.foreign_key}"
end
end
query = visit(association
.klass
.joins(join_name)
.where(where_clause), table_alias: current_alias)
.to_sql
"\'#{subject.label}\', (#{query})"
end
|
#visit_has_one(subject, table_alias:, **kwargs) ⇒ Object
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
# File 'lib/pg_serializable/visitors/json.rb', line 133
def visit_has_one(subject, table_alias:, **kwargs)
current_alias = next_alias!
subquery_alias = next_alias!
klass = subject.target
select_sql = json_build_object(visit(klass.trait_manager, trait: subject.trait, table_alias: current_alias)).to_sql
from_sql = klass
.select("DISTINCT ON (#{subject.primary_key}) #{subquery_alias}.*")
.from("#{klass.table_name} #{subquery_alias}")
query = klass.select(select_sql).from("#{as(from_sql, current_alias)}")
.where("#{current_alias}.#{subject.primary_key}=#{table_alias}.#{subject.foreign_key}").to_sql
"\'#{subject.label}\', (#{query})"
end
|
#visit_node(subject, **kwargs) ⇒ Object
38
39
40
41
42
43
44
|
# File 'lib/pg_serializable/visitors/json.rb', line 38
def visit_node(subject, **kwargs)
case subject
when attribute? then visit_attribute subject, **kwargs
when association? then visit_association subject, **kwargs
else raise UnknownAttributeError.new
end
end
|
#visit_record(subject, trait: :default) ⇒ Object
4
5
6
7
8
9
10
11
12
13
|
# File 'lib/pg_serializable/visitors/json.rb', line 4
def visit_record(subject, trait: :default)
table_alias = next_alias!
klass = subject.class
base_class = klass.base_class
select_sql = json_build_object(visit(klass.trait_manager, trait: trait, table_alias: table_alias)).to_sql
from_sql = base_class.where(id: subject.id).limit(1).to_sql
base_class.select(select_sql).from("#{as(from_sql, table_alias)}")
end
|
#visit_relation(subject, table_alias: nil, trait: :default) ⇒ Object
15
16
17
18
19
20
21
22
23
24
|
# File 'lib/pg_serializable/visitors/json.rb', line 15
def visit_relation(subject, table_alias: nil, trait: :default)
table_alias ||= next_alias!
klass = subject.klass
base_class = klass.base_class
select_sql = coalesce(json_agg(json_build_object(visit(klass.trait_manager, trait: trait, table_alias: table_alias)))).to_sql
from_sql = subject.to_sql
base_class.select(select_sql).from("#{as(from_sql, table_alias)}")
end
|
#visit_trait(subject, **kwargs) ⇒ Object
34
35
36
|
# File 'lib/pg_serializable/visitors/json.rb', line 34
def visit_trait(subject, **kwargs)
subject.attribute_nodes.map { |attribute| visit attribute, **kwargs }.join(', ')
end
|
#visit_trait_manager(subject, trait: :default, **kwargs) ⇒ Object
30
31
32
|
# File 'lib/pg_serializable/visitors/json.rb', line 30
def visit_trait_manager(subject, trait: :default, **kwargs)
visit subject.get_trait(trait), **kwargs
end
|