Skip to content

Commit 8f0695e

Browse files
authored
Add json support to models (#50)
Fix #26
1 parent aee8784 commit 8f0695e

File tree

8 files changed

+149
-4
lines changed

8 files changed

+149
-4
lines changed

spec/model/model_spec.cr

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,18 @@ module ModelSpec
563563
end
564564
end
565565

566+
it "can export to json" do
567+
temporary do
568+
reinit
569+
u = User.new({first_name: "Hello", last_name: "World"})
570+
u.to_json.should eq %({"first_name":"Hello","last_name":"World"})
571+
572+
u.to_json(full: true).should eq (
573+
%({"id":null,"first_name":"Hello","last_name":"World","middle_name":null,"active":null,"notification_preferences":"null","updated_at":null,"created_at":null})
574+
)
575+
end
576+
end
577+
566578
it "can paginate with where clause" do
567579
temporary do
568580
reinit

spec/model/uuid_spec.cr

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,20 @@ module UUIDSpec
4949
DBObject.query.where { id == "#{first_uuid}" }.count.should eq 1
5050
end
5151
end
52+
53+
it "can save a model with UUID to JSON" do
54+
temporary do
55+
reinit
56+
57+
3.times do |x|
58+
DBObject.create!({name: "obj#{x}"})
59+
end
60+
61+
(
62+
DBObject.query.first!.to_json =~
63+
/"id":"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"/
64+
).should eq 1
65+
end
66+
end
5267
end
5368
end

src/clear/extensions/core_ext.cr

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
require "base64"
2+
3+
struct Char
4+
def to_json(json)
5+
json.string("#{self}")
6+
end
7+
end
8+
9+
struct PG::Geo::Box
10+
def to_json(json)
11+
json.object do
12+
json.field("x1") { json.number x1 }
13+
json.field("x2") { json.number x2 }
14+
json.field("y1") { json.number y1 }
15+
json.field("y2") { json.number y2 }
16+
end
17+
end
18+
end
19+
20+
struct PG::Geo::LineSegment
21+
def to_json(json)
22+
json.object do
23+
json.field("x1") { json.number x1 }
24+
json.field("x2") { json.number x2 }
25+
json.field("y1") { json.number y1 }
26+
json.field("y2") { json.number y2 }
27+
end
28+
end
29+
end
30+
31+
struct PG::Geo::Point
32+
def to_json(json)
33+
json.object do
34+
json.field("x") { json.number x }
35+
json.field("y") { json.number y }
36+
end
37+
end
38+
end
39+
40+
struct PG::Geo::Line
41+
def to_json(json)
42+
json.object do
43+
json.field("a") { json.number a }
44+
json.field("b") { json.number b }
45+
json.field("c") { json.number c }
46+
end
47+
end
48+
end
49+
50+
struct PG::Geo::Circle
51+
def to_json(json)
52+
json.object do
53+
json.field("x") { json.number x }
54+
json.field("y") { json.number y }
55+
json.field("radius") { json.number radius }
56+
end
57+
end
58+
end
59+
60+
struct PG::Geo::Path
61+
def to_json(json)
62+
json.object do
63+
json.field("points") do
64+
json.array do
65+
points.each do
66+
points.to_json(json)
67+
end
68+
end
69+
end
70+
json.field("closed") { json.bool(closed?) }
71+
end
72+
end
73+
end
74+
75+
struct PG::Geo::Polygon
76+
def to_json(json)
77+
json.object do
78+
json.array do
79+
points.each do
80+
points.to_json(json)
81+
end
82+
end
83+
end
84+
end
85+
end
86+
87+
struct Slice(T)
88+
def to_json(json)
89+
s = String::Builder.new
90+
to_s(s)
91+
json.string(Base64.strict_encode(s.to_s))
92+
end
93+
end
94+
95+
struct PG::Numeric
96+
def to_json(json)
97+
s = String::Builder.new
98+
to_s(s)
99+
json.string(s.to_s)
100+
end
101+
end

src/clear/model/model.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ module Clear::Model
1717
include Clear::Model::HasRelations
1818
include Clear::Model::HasScope
1919
include Clear::Model::ClassMethods
20+
include Clear::Model::HasJson
2021
include Clear::Model::IsPolymorphic
2122

2223
getter cache : Clear::Model::QueryCache?

src/clear/model/modules/class_methods.cr

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ module Clear::Model::ClassMethods
3131

3232
class_property pkey : String = "id"
3333

34+
# Collection({{@type}})
35+
#
36+
# This is the object managing a `Select` request.
37+
# A new collection is created by calling `{{@type}}.query`
38+
#
39+
# Collection are mutable and refining the SQL will mutate the collection.
40+
# You may want to copy the collection by calling `dup`
3441
class Collection < Clear::Model::CollectionBase(\{{@type}}); end
3542

3643
def self.query

src/clear/model/modules/has_columns.cr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ module Clear::Model::HasColumns
4343
{} of String => ::Clear::SQL::Any
4444
end
4545

46-
def to_h
46+
def to_h(full = false)
4747
{} of String => ::Clear::SQL::Any
4848
end
4949

@@ -196,11 +196,11 @@ module Clear::Model::HasColumns
196196
end
197197

198198
# Return a hash version of the columns of this model.
199-
def to_h : Hash(String, ::Clear::SQL::Any)
199+
def to_h(full = false) : Hash(String, ::Clear::SQL::Any)
200200
out = super
201201

202202
{% for name, settings in COLUMNS %}
203-
if @{{name}}_column.defined?
203+
if full || @{{name}}_column.defined?
204204
out[{{settings[:column_name]}}] = Clear::Model::Converter.to_db({{settings[:converter]}}, @{{name}}_column.value(nil))
205205
end
206206
{% end %}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module Clear::Model::HasJson
2+
def to_json(full : Bool)
3+
to_h(full).to_json
4+
end
5+
6+
def to_json(json, full = false)
7+
to_h(full).to_json(json)
8+
end
9+
end

src/clear/model/modules/has_relations.cr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ module Clear::Model::HasRelations
291291
end
292292

293293
before(:validate, _bt_save_{{method_name}})
294-
# Adding the eager loading
294+
295295
class Collection
296296
def with_{{method_name}}(fetch_columns = false, &block : {{relation_type}}::Collection -> ) : self
297297
before_query do

0 commit comments

Comments
 (0)