Reputation: 43
This is my Model
class Client < Sequel::Model(:clients)
end
When I execute
Client.first.to_json
I get
"\"#<Client:0x2594b824>\""
But when I execute
DB[:clients].first.to_json
I correctly get:
{id: 1, name: "Someone" ... }
What am I doing wrong?... I also tried using Client.dataset.first.json
having the same result.
Also I'm using a MS Access DB but I don't think that's important.
Upvotes: 2
Views: 2220
Reputation: 19948
The json
library (part of the Ruby standard library), and other gems such as ActiveSupport, monkey patch objects with a to_json
method which could be what is getting called, not a the specific to_json
method supplied by Sequel which knows how to convert a Sequel::Model
instance to JSON. This is speculation as I'd be surprised that the JSON library monkey patches anything other than String
, Array
, Hash
etc.
When using DB[:clients].first
you probably get back a Hash
which has a to_json
method, where as Client.first
returns a model instance which isn't handled by the generic to_json
method supplied by the json library.
Try registering the Sequel JSON plugin, this should take precedence over the monkey patched to_json
method:
Sequel::Model.plugin :json_serializer
By the way this is a good indicator of why monkey patching is often a bad idea, particularly monkey patching of classes which are outside a libraries/gems namespace.
Upvotes: 5
Reputation: 160549
You need to use to_hash
:
require 'json'
require 'sequel'
DB = Sequel.sqlite
DB.create_table :items do
primary_key :id
String :name
Float :price
end
items = DB[:items]
items.insert(:name => 'abc', :price => rand * 100)
class Item < Sequel::Model(:items)
end
Item.first
.to_hash # => {:id=>1, :name=>"abc", :price=>51.47074347440235}
.to_json # => "{\"id\":1,\"name\":\"abc\",\"price\":51.47074347440235}"
Upvotes: 4