Skip to content

Commit

Permalink
Add json support to models (#50)
Browse files Browse the repository at this point in the history
Fix #26
  • Loading branch information
anykeyh authored Nov 12, 2018
1 parent aee8784 commit 8f0695e
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 4 deletions.
12 changes: 12 additions & 0 deletions spec/model/model_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,18 @@ module ModelSpec
end
end

it "can export to json" do
temporary do
reinit
u = User.new({first_name: "Hello", last_name: "World"})
u.to_json.should eq %({"first_name":"Hello","last_name":"World"})

u.to_json(full: true).should eq (
%({"id":null,"first_name":"Hello","last_name":"World","middle_name":null,"active":null,"notification_preferences":"null","updated_at":null,"created_at":null})
)
end
end

it "can paginate with where clause" do
temporary do
reinit
Expand Down
15 changes: 15 additions & 0 deletions spec/model/uuid_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,20 @@ module UUIDSpec
DBObject.query.where { id == "#{first_uuid}" }.count.should eq 1
end
end

it "can save a model with UUID to JSON" do
temporary do
reinit

3.times do |x|
DBObject.create!({name: "obj#{x}"})
end

(
DBObject.query.first!.to_json =~
/"id":"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"/
).should eq 1
end
end
end
end
101 changes: 101 additions & 0 deletions src/clear/extensions/core_ext.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
require "base64"

struct Char
def to_json(json)
json.string("#{self}")
end
end

struct PG::Geo::Box
def to_json(json)
json.object do
json.field("x1") { json.number x1 }
json.field("x2") { json.number x2 }
json.field("y1") { json.number y1 }
json.field("y2") { json.number y2 }
end
end
end

struct PG::Geo::LineSegment
def to_json(json)
json.object do
json.field("x1") { json.number x1 }
json.field("x2") { json.number x2 }
json.field("y1") { json.number y1 }
json.field("y2") { json.number y2 }
end
end
end

struct PG::Geo::Point
def to_json(json)
json.object do
json.field("x") { json.number x }
json.field("y") { json.number y }
end
end
end

struct PG::Geo::Line
def to_json(json)
json.object do
json.field("a") { json.number a }
json.field("b") { json.number b }
json.field("c") { json.number c }
end
end
end

struct PG::Geo::Circle
def to_json(json)
json.object do
json.field("x") { json.number x }
json.field("y") { json.number y }
json.field("radius") { json.number radius }
end
end
end

struct PG::Geo::Path
def to_json(json)
json.object do
json.field("points") do
json.array do
points.each do
points.to_json(json)
end
end
end
json.field("closed") { json.bool(closed?) }
end
end
end

struct PG::Geo::Polygon
def to_json(json)
json.object do
json.array do
points.each do
points.to_json(json)
end
end
end
end
end

struct Slice(T)
def to_json(json)
s = String::Builder.new
to_s(s)
json.string(Base64.strict_encode(s.to_s))
end
end

struct PG::Numeric
def to_json(json)
s = String::Builder.new
to_s(s)
json.string(s.to_s)
end
end
1 change: 1 addition & 0 deletions src/clear/model/model.cr
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ module Clear::Model
include Clear::Model::HasRelations
include Clear::Model::HasScope
include Clear::Model::ClassMethods
include Clear::Model::HasJson
include Clear::Model::IsPolymorphic

getter cache : Clear::Model::QueryCache?
Expand Down
7 changes: 7 additions & 0 deletions src/clear/model/modules/class_methods.cr
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ module Clear::Model::ClassMethods

class_property pkey : String = "id"

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

def self.query
Expand Down
6 changes: 3 additions & 3 deletions src/clear/model/modules/has_columns.cr
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ module Clear::Model::HasColumns
{} of String => ::Clear::SQL::Any
end

def to_h
def to_h(full = false)
{} of String => ::Clear::SQL::Any
end

Expand Down Expand Up @@ -196,11 +196,11 @@ module Clear::Model::HasColumns
end

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

{% for name, settings in COLUMNS %}
if @{{name}}_column.defined?
if full || @{{name}}_column.defined?
out[{{settings[:column_name]}}] = Clear::Model::Converter.to_db({{settings[:converter]}}, @{{name}}_column.value(nil))
end
{% end %}
Expand Down
9 changes: 9 additions & 0 deletions src/clear/model/modules/has_json.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Clear::Model::HasJson
def to_json(full : Bool)
to_h(full).to_json
end

def to_json(json, full = false)
to_h(full).to_json(json)
end
end
2 changes: 1 addition & 1 deletion src/clear/model/modules/has_relations.cr
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ module Clear::Model::HasRelations
end

before(:validate, _bt_save_{{method_name}})
# Adding the eager loading

class Collection
def with_{{method_name}}(fetch_columns = false, &block : {{relation_type}}::Collection -> ) : self
before_query do
Expand Down

0 comments on commit 8f0695e

Please sign in to comment.