mongoid-cached-json 1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.md +22 -0
- data/README.md +138 -0
- data/lib/mongoid-cached-json.rb +7 -0
- data/lib/mongoid-cached-json/cached_json.rb +151 -0
- data/lib/mongoid-cached-json/config.rb +94 -0
- data/lib/mongoid-cached-json/version.rb +7 -0
- metadata +146 -0
data/LICENSE.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2011 Art.sy, Aaron Windsor, Daniel Doubrovkine
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
Mongoid::CachedJson [![Build Status](https://secure.travis-ci.org/dblock/mongoid-cached-json.png)](http://travis-ci.org/dblock/mongoid-cached-json)
|
2
|
+
===================
|
3
|
+
|
4
|
+
Typical *as_json* definitions may involve lots of database point queries and method calls. When returning collections of objects, a single call may yield hundreds of database queries that can take seconds. This library mitigates the problem by implementing a module called *CachedJson*.
|
5
|
+
|
6
|
+
CachedJson enables returning multiple JSON formats from a single class and provides some rules for returning embedded or referenced data. It then uses a scheme where fragments of JSON are cached for a particular (class, id) pair containing only the data that doesn't involve references/embedded documents. To get the full JSON for an instance, CachedJson will combine fragments of JSON from the instance with fragments representing the JSON for its references. In the best case, when all of these fragments are cached, this falls through to a few cache lookups followed by a couple Ruby hash merges to create the JSON.
|
7
|
+
|
8
|
+
Using Mongoid::CachedJson we were able to cut our JSON API average response time by about a factor of 10.
|
9
|
+
|
10
|
+
Resources
|
11
|
+
---------
|
12
|
+
|
13
|
+
* [Need Help?](http://groups.google.com/group/mongoid-cached-json)
|
14
|
+
* [Source Code](http://github.com/dblock/mongoid-cached-json)
|
15
|
+
* [Travis CI](https://secure.travis-ci.org/dblock/mongoid-cached-json)
|
16
|
+
|
17
|
+
Quickstart
|
18
|
+
----------
|
19
|
+
|
20
|
+
Add `mongoid-cached-json` to your Gemfile.
|
21
|
+
|
22
|
+
gem "mongoid-cached-json"
|
23
|
+
|
24
|
+
Include `Mongoid::CachedJson` in your models.
|
25
|
+
|
26
|
+
``` ruby
|
27
|
+
class Gadget
|
28
|
+
include Mongoid::CachedJson
|
29
|
+
|
30
|
+
field :name
|
31
|
+
field :extras
|
32
|
+
|
33
|
+
belongs_to :widget
|
34
|
+
|
35
|
+
json_fields \
|
36
|
+
:name => { },
|
37
|
+
:extras => { :properties => :public }
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
class Widget
|
42
|
+
include Mongoid::CachedJson
|
43
|
+
|
44
|
+
field :name
|
45
|
+
has_many :gadgets
|
46
|
+
|
47
|
+
json_fields \
|
48
|
+
:name => { },
|
49
|
+
:gadgets => { :type => :reference, :properties => :public }
|
50
|
+
|
51
|
+
end
|
52
|
+
```
|
53
|
+
|
54
|
+
Invoke `as_json`.
|
55
|
+
|
56
|
+
``` ruby
|
57
|
+
# the `:short` version of the JSON, `gadgets` not included
|
58
|
+
Widget.first.as_json
|
59
|
+
|
60
|
+
# equivalent to the above
|
61
|
+
Widget.first.as_json({ :properties => :short })
|
62
|
+
|
63
|
+
# `:public` version of the JSON, `gadgets` returned with `:short` JSON, no `:extras`
|
64
|
+
Widget.first.as_json({ :properties => :public })
|
65
|
+
|
66
|
+
# `:all` version of the JSON, `gadgets` returned with `:all` JSON, including `:extras`
|
67
|
+
Widget.first.as_json({ :properties => :all })
|
68
|
+
```
|
69
|
+
|
70
|
+
Configuration
|
71
|
+
-------------
|
72
|
+
|
73
|
+
By default `Mongoid::CachedJson` will use an instance of `ActiveSupport::Cache::MemoryStore` in a non-Rails and `Rails.cache` in a Rails environment. You can configure it to use any other cache store.
|
74
|
+
|
75
|
+
``` ruby
|
76
|
+
Mongoid::CachedJson.configure do |config|
|
77
|
+
config.cache = ActiveSupport::Cache::FileStore.new
|
78
|
+
end
|
79
|
+
```
|
80
|
+
|
81
|
+
Definining Fields
|
82
|
+
-----------------
|
83
|
+
|
84
|
+
Mongoid::CachedJson supports the following options.
|
85
|
+
|
86
|
+
* `:hide_as_child_json_when` is an optional function that hides the child JSON from `as_json` parent objects, eg. `cached_json :hide_as_child_json_when => lambda { |instance| ! instance.is_secret? }`
|
87
|
+
|
88
|
+
Mongoid::CachedJson field definitions support the following options.
|
89
|
+
|
90
|
+
* `:definition` can be a symbol or an anonymous function, eg. `:description => { :definition => :name }` or `:description => { :definition => lambda { |instance| instance.name } }`
|
91
|
+
* `:type` can be `:reference`, required for referenced objects
|
92
|
+
* `:properties` can be one of `:short`, `:public`, `:all`, in this order
|
93
|
+
|
94
|
+
Transformations
|
95
|
+
---------------
|
96
|
+
|
97
|
+
You can define global transformations on all JSON values with `Mongoid::CachedJson.config.transform`. Each transformation must return a value. In the following example we extend the JSON definition with an application-specific `:trusted` field and encode any content that is not trusted.
|
98
|
+
|
99
|
+
``` ruby
|
100
|
+
class Widget
|
101
|
+
include Mongoid::CachedJson
|
102
|
+
|
103
|
+
field :name
|
104
|
+
field :description
|
105
|
+
|
106
|
+
json_fields \
|
107
|
+
:name => { :trusted => true },
|
108
|
+
:description => { }
|
109
|
+
end
|
110
|
+
```
|
111
|
+
|
112
|
+
``` ruby
|
113
|
+
Mongoid::CachedJson.config.transform do |field, definition, value|
|
114
|
+
(!! definition[:trusted]) ? value : CGI.escapeHTML(value)
|
115
|
+
end
|
116
|
+
```
|
117
|
+
|
118
|
+
Mixing with Standard as_json
|
119
|
+
----------------------------
|
120
|
+
|
121
|
+
Taking part in the Mongoid::CachedJson `json_fields` scheme is optional: you can still write *as_json* methods where it makes sense.
|
122
|
+
|
123
|
+
Turning Caching Off
|
124
|
+
-------------------
|
125
|
+
|
126
|
+
You can set `Mongoid::CachedJson.config.disable_caching = true`. It may be a good idea to set it to `ENV['DISABLE_JSON_CACHING']`, in case this turns out not to be The Solution To All Of Your Performance Problems (TM).
|
127
|
+
|
128
|
+
Contributing
|
129
|
+
------------
|
130
|
+
|
131
|
+
Fork the project. Make your feature addition or bug fix with tests. Send a pull request. Bonus points for topical branches.
|
132
|
+
|
133
|
+
Copyright and License
|
134
|
+
---------------------
|
135
|
+
|
136
|
+
MIT License, see [LICENSE](LICENSE.md) for details.
|
137
|
+
|
138
|
+
(c) 2012 [Art.sy Inc.](http://artsy.github.com) and [Contributors](HISTORY.md)
|
@@ -0,0 +1,151 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid
|
3
|
+
module CachedJson
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
class_attribute :all_json_properties
|
8
|
+
class_attribute :cached_json_field_defs
|
9
|
+
class_attribute :cached_json_reference_defs
|
10
|
+
class_attribute :hide_as_child_json_when
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
|
15
|
+
# Define JSON fields for a class.
|
16
|
+
#
|
17
|
+
# @param [ hash ] defs JSON field definition.
|
18
|
+
#
|
19
|
+
# @since 1.0.0
|
20
|
+
def json_fields(defs)
|
21
|
+
self.hide_as_child_json_when = defs.delete(:hide_as_child_json_when) || lambda { |a| false }
|
22
|
+
self.all_json_properties = [:short, :public, :all]
|
23
|
+
cached_json_defs = Hash[defs.map { |k,v| [k, { :type => :callable, :properties => :short, :definition => k }.merge(v)] }]
|
24
|
+
self.cached_json_field_defs = {}
|
25
|
+
self.cached_json_reference_defs = {}
|
26
|
+
self.all_json_properties.each_with_index do |property, i|
|
27
|
+
self.cached_json_field_defs[property] = Hash[cached_json_defs.find_all do |field, definition|
|
28
|
+
self.all_json_properties.find_index(definition[:properties]) <= i and definition[:type] == :callable
|
29
|
+
end]
|
30
|
+
self.cached_json_reference_defs[property] = Hash[cached_json_defs.find_all do |field, definition|
|
31
|
+
self.all_json_properties.find_index(definition[:properties]) <= i and definition[:type] == :reference
|
32
|
+
end]
|
33
|
+
# If the field is a reference and is just specified as a symbol, reflect on it to get metadata
|
34
|
+
self.cached_json_reference_defs[property].to_a.each do |field, definition|
|
35
|
+
if definition[:definition].is_a?(Symbol)
|
36
|
+
self.cached_json_reference_defs[property][field][:metadata] = self.reflect_on_association(definition[:definition])
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
before_save :expire_cached_json
|
41
|
+
end
|
42
|
+
|
43
|
+
# Given an object definition in the form of either an object or a class, id pair,
|
44
|
+
# grab the as_json representation from the cache if possible, otherwise create
|
45
|
+
# the as_json representation by loading the object from the database. For any
|
46
|
+
# references in the object's JSON representation, we have to recursively materialize
|
47
|
+
# the JSON by calling resolve_json_reference on each of them (which may, in turn,
|
48
|
+
# call materialize_json)
|
49
|
+
def materialize_json(options, object_def)
|
50
|
+
return nil if !object_def[:object] and !object_def[:id]
|
51
|
+
is_top_level_json = options[:is_top_level_json] || false
|
52
|
+
if object_def[:object]
|
53
|
+
object_reference = object_def[:object]
|
54
|
+
clazz, id = object_def[:object].class, object_def[:object].id
|
55
|
+
else
|
56
|
+
object_reference = nil
|
57
|
+
clazz, id = object_def[:clazz], object_def[:id]
|
58
|
+
end
|
59
|
+
json = Mongoid::CachedJson.config.cache.fetch(self.cached_json_key(options, clazz, id), { :force => !! Mongoid::CachedJson.config.disable_caching }) do
|
60
|
+
object_reference = clazz.where({ :_id => id }).first if !object_reference
|
61
|
+
if !object_reference or (!is_top_level_json and options[:properties] != :all and clazz.hide_as_child_json_when.call(object_reference))
|
62
|
+
nil
|
63
|
+
else
|
64
|
+
Hash[clazz.cached_json_field_defs[options[:properties]].map do |field, definition|
|
65
|
+
json_value = (definition[:definition].is_a?(Symbol) ? object_reference.send(definition[:definition]) : definition[:definition].call(object_reference))
|
66
|
+
Mongoid::CachedJson.config.transform.each do |t|
|
67
|
+
json_value = t.call(field, definition, json_value)
|
68
|
+
end
|
69
|
+
[field, json_value]
|
70
|
+
end]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
reference_defs = clazz.cached_json_reference_defs[options[:properties]]
|
74
|
+
if !reference_defs.empty?
|
75
|
+
object_reference = clazz.where({ :_id => id }).first if !object_reference
|
76
|
+
if object_reference and (is_top_level_json or options[:properties] == :all or !clazz.hide_as_child_json_when.call(object_reference))
|
77
|
+
json = json.merge(Hash[reference_defs.map do |field, definition|
|
78
|
+
json_properties_type = (options[:properties] == :all) ? :all : :short
|
79
|
+
[field, clazz.resolve_json_reference(options.merge({ :properties => json_properties_type, :is_top_level_json => false}), object_reference, field, definition)]
|
80
|
+
end])
|
81
|
+
end
|
82
|
+
end
|
83
|
+
json
|
84
|
+
end
|
85
|
+
|
86
|
+
# Cache key.
|
87
|
+
def cached_json_key(options, cached_class, cached_id)
|
88
|
+
"as_json/#{cached_class}/#{cached_id}/#{options[:properties]}/#{!!options[:is_top_level_json]}"
|
89
|
+
end
|
90
|
+
|
91
|
+
# If the reference is a symbol, we may be lucky and be able to figure out the as_json
|
92
|
+
# representation by the (class, id) pair definition of the reference. That is, we may
|
93
|
+
# be able to load the as_json representation from the cache without even getting the
|
94
|
+
# model from the database and materializing it through Mongoid. We'll try to do this first.
|
95
|
+
def resolve_json_reference(options, object, field, reference_def)
|
96
|
+
reference_json = nil
|
97
|
+
if reference_def[:metadata]
|
98
|
+
clazz = reference_def[:metadata].class_name.constantize
|
99
|
+
key = reference_def[:metadata].key.to_sym
|
100
|
+
if reference_def[:metadata].relation == Mongoid::Relations::Referenced::ManyToMany
|
101
|
+
reference_json = object.send(key).map do |id|
|
102
|
+
materialize_json(options, { :clazz => clazz, :id => id })
|
103
|
+
end.compact
|
104
|
+
elsif reference_def[:metadata].relation == Mongoid::Relations::Referenced::In
|
105
|
+
reference_json = materialize_json(options, { :clazz => clazz, :id => object.send(key) })
|
106
|
+
end
|
107
|
+
end
|
108
|
+
# If we get to this point and reference_json is still nil, there's no chance we can
|
109
|
+
# load the JSON from cache so we go ahead and call as_json on the object.
|
110
|
+
if !reference_json
|
111
|
+
reference = reference_def[:definition].is_a?(Symbol) ? object.send(reference_def[:definition]) : reference_def[:definition].call(object)
|
112
|
+
reference_json = reference.as_json(options) if reference
|
113
|
+
end
|
114
|
+
reference_json
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
def as_json(options = { :properties => :short })
|
120
|
+
raise ArgumentError.new("Missing options[:properties]") if (options.nil? || options[:properties].nil?)
|
121
|
+
raise ArgumentError.new("Unknown properties option: #{options[:properties]}") if !self.all_json_properties.member?(options[:properties])
|
122
|
+
self.class.materialize_json({ :is_top_level_json => true }.merge(options), { :object => self })
|
123
|
+
end
|
124
|
+
|
125
|
+
# Expire all JSON entries for this class.
|
126
|
+
def expire_cached_json
|
127
|
+
self.all_json_properties.each do |properties|
|
128
|
+
[true, false].each do |is_top_level_json|
|
129
|
+
Mongoid::CachedJson.config.cache.delete(self.class.cached_json_key({:properties => properties, :is_top_level_json => is_top_level_json}, self.class, self.id))
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
class << self
|
135
|
+
|
136
|
+
# Set the configuration options. Best used by passing a block.
|
137
|
+
#
|
138
|
+
# @example Set up configuration options.
|
139
|
+
# Mongoid::CachedJson.configure do |config|
|
140
|
+
# config.cache = Rails.cache
|
141
|
+
# end
|
142
|
+
#
|
143
|
+
# @return [ Config ] The configuration obejct.
|
144
|
+
def configure
|
145
|
+
block_given? ? yield(Mongoid::CachedJson::Config) : Mongoid::CachedJson::Config
|
146
|
+
end
|
147
|
+
alias :config :configure
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid
|
3
|
+
module CachedJson #:nodoc
|
4
|
+
module Config
|
5
|
+
extend self
|
6
|
+
include ActiveSupport::Callbacks
|
7
|
+
|
8
|
+
attr_accessor :settings, :defaults
|
9
|
+
@settings = {}
|
10
|
+
@defaults = {}
|
11
|
+
|
12
|
+
# Define a configuration option with a default.
|
13
|
+
#
|
14
|
+
# @example Define the option.
|
15
|
+
# Config.option(:cache, :default => nil)
|
16
|
+
#
|
17
|
+
# @param [ Symbol ] name The name of the configuration option.
|
18
|
+
# @param [ Hash ] options Extras for the option.
|
19
|
+
#
|
20
|
+
# @option options [ Object ] :default The default value.
|
21
|
+
def option(name, options = {})
|
22
|
+
defaults[name] = settings[name] = options[:default]
|
23
|
+
|
24
|
+
class_eval <<-RUBY
|
25
|
+
def #{name}
|
26
|
+
settings[#{name.inspect}]
|
27
|
+
end
|
28
|
+
|
29
|
+
def #{name}=(value)
|
30
|
+
settings[#{name.inspect}] = value
|
31
|
+
end
|
32
|
+
|
33
|
+
def #{name}?
|
34
|
+
#{name}
|
35
|
+
end
|
36
|
+
RUBY
|
37
|
+
end
|
38
|
+
|
39
|
+
option :disable_caching, { :default => false }
|
40
|
+
|
41
|
+
# Returns the default cache store, which is either a Rails logger of stdout logger
|
42
|
+
#
|
43
|
+
# @example Get the default cache store
|
44
|
+
# config.default_cache
|
45
|
+
#
|
46
|
+
# @return [ Cache ] The default Cache instance.
|
47
|
+
def default_cache
|
48
|
+
defined?(Rails) && Rails.respond_to?(:cache) ? Rails.cache : ::ActiveSupport::Cache::MemoryStore.new
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns the cache, or defaults to Rails cache or ActiveSupport::Cache::MemoryStore logger.
|
52
|
+
#
|
53
|
+
# @example Get the cache.
|
54
|
+
# config.cache
|
55
|
+
#
|
56
|
+
# @return [ Cache ] The configured cache or a default cache instance.
|
57
|
+
def cache
|
58
|
+
settings[:cache] = default_cache unless settings.has_key?(:cache)
|
59
|
+
settings[:cache]
|
60
|
+
end
|
61
|
+
|
62
|
+
# Sets the cache to use.
|
63
|
+
#
|
64
|
+
# @example Set the cache.
|
65
|
+
# config.cache = Rails.cache
|
66
|
+
#
|
67
|
+
# @return [ Cache ] The newly set cache.
|
68
|
+
def cache=(cache)
|
69
|
+
settings[:cache] = cache
|
70
|
+
end
|
71
|
+
|
72
|
+
# Reset the configuration options to the defaults.
|
73
|
+
#
|
74
|
+
# @example Reset the configuration options.
|
75
|
+
# config.reset!
|
76
|
+
def reset!
|
77
|
+
settings.replace(defaults)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Define a transformation on JSON data.
|
81
|
+
#
|
82
|
+
# @example Convert every string in materialized JSON to upper-case.
|
83
|
+
# config.transform do |field, value|
|
84
|
+
# value.upcase
|
85
|
+
# end
|
86
|
+
def transform(& block)
|
87
|
+
settings[:transform] = [] unless settings.has_key?(:transform)
|
88
|
+
settings[:transform] << block if block_given?
|
89
|
+
settings[:transform]
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
metadata
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mongoid-cached-json
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '1.0'
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Aaron Windsor
|
9
|
+
- Daniel Doubrovkine
|
10
|
+
- Frank Macreery
|
11
|
+
autorequire:
|
12
|
+
bindir: bin
|
13
|
+
cert_chain: []
|
14
|
+
date: 2012-02-20 00:00:00.000000000Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: activesupport
|
18
|
+
requirement: &70215312132660 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ! '>='
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '0'
|
24
|
+
type: :runtime
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: *70215312132660
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: mongoid
|
29
|
+
requirement: &70215312131960 !ruby/object:Gem::Requirement
|
30
|
+
none: false
|
31
|
+
requirements:
|
32
|
+
- - ! '>='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: *70215312131960
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: bson_ext
|
40
|
+
requirement: &70215312120160 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
type: :runtime
|
47
|
+
prerelease: false
|
48
|
+
version_requirements: *70215312120160
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: hpricot
|
51
|
+
requirement: &70215312118740 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ! '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
type: :runtime
|
58
|
+
prerelease: false
|
59
|
+
version_requirements: *70215312118740
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: rspec
|
62
|
+
requirement: &70215312117220 !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ~>
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '2.5'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: *70215312117220
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: bundler
|
73
|
+
requirement: &70215312116260 !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ~>
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '1.0'
|
79
|
+
type: :development
|
80
|
+
prerelease: false
|
81
|
+
version_requirements: *70215312116260
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: jeweler
|
84
|
+
requirement: &70215312115520 !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.6'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: *70215312115520
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: yard
|
95
|
+
requirement: &70215312114460 !ruby/object:Gem::Requirement
|
96
|
+
none: false
|
97
|
+
requirements:
|
98
|
+
- - ~>
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0.6'
|
101
|
+
type: :development
|
102
|
+
prerelease: false
|
103
|
+
version_requirements: *70215312114460
|
104
|
+
description: Cached-json is a DSL for describing JSON representations of Mongoid models.
|
105
|
+
email: dblock@dblock.org
|
106
|
+
executables: []
|
107
|
+
extensions: []
|
108
|
+
extra_rdoc_files:
|
109
|
+
- LICENSE.md
|
110
|
+
- README.md
|
111
|
+
files:
|
112
|
+
- lib/mongoid-cached-json.rb
|
113
|
+
- lib/mongoid-cached-json/cached_json.rb
|
114
|
+
- lib/mongoid-cached-json/config.rb
|
115
|
+
- lib/mongoid-cached-json/version.rb
|
116
|
+
- LICENSE.md
|
117
|
+
- README.md
|
118
|
+
homepage: http://github.com/dblock/mongoid-cached-json
|
119
|
+
licenses:
|
120
|
+
- MIT
|
121
|
+
post_install_message:
|
122
|
+
rdoc_options: []
|
123
|
+
require_paths:
|
124
|
+
- lib
|
125
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
126
|
+
none: false
|
127
|
+
requirements:
|
128
|
+
- - ! '>='
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
segments:
|
132
|
+
- 0
|
133
|
+
hash: 2087512391400708959
|
134
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
|
+
none: false
|
136
|
+
requirements:
|
137
|
+
- - ! '>='
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
140
|
+
requirements: []
|
141
|
+
rubyforge_project:
|
142
|
+
rubygems_version: 1.8.10
|
143
|
+
signing_key:
|
144
|
+
specification_version: 3
|
145
|
+
summary: Effective model-level JSON caching for the Mongoid ODM.
|
146
|
+
test_files: []
|