dooly 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +4 -0
- data/Gemfile.lock +87 -0
- data/MIT-LICENSE +19 -0
- data/README.markdown +164 -0
- data/Rakefile +11 -0
- data/dooly.gemspec +32 -0
- data/lib/dooly/attachment/base.rb +107 -0
- data/lib/dooly/attachment.rb +48 -0
- data/lib/dooly/collection/base.rb +53 -0
- data/lib/dooly/collection.rb +23 -0
- data/lib/dooly/configuration.rb +14 -0
- data/lib/dooly/id_proxy/base.rb +52 -0
- data/lib/dooly/id_proxy.rb +57 -0
- data/lib/dooly/model_regulator.rb +58 -0
- data/lib/dooly/version.rb +3 -0
- data/lib/dooly.rb +20 -0
- data/test/test_attachment.rb +74 -0
- data/test/test_collection.rb +57 -0
- data/test/test_helper.rb +12 -0
- data/test/test_id_proxy.rb +48 -0
- data/test/test_model_regulator.rb +60 -0
- metadata +210 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
dooly (0.0.1)
|
5
|
+
activemodel
|
6
|
+
activesupport
|
7
|
+
rake
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: http://rubygems.org/
|
11
|
+
specs:
|
12
|
+
activemodel (3.2.13)
|
13
|
+
activesupport (= 3.2.13)
|
14
|
+
builder (~> 3.0.0)
|
15
|
+
activesupport (3.2.13)
|
16
|
+
i18n (= 0.6.1)
|
17
|
+
multi_json (~> 1.0)
|
18
|
+
binding_of_caller (0.7.1)
|
19
|
+
debug_inspector (>= 0.0.1)
|
20
|
+
builder (3.0.4)
|
21
|
+
coderay (1.0.8)
|
22
|
+
columnize (0.3.6)
|
23
|
+
debug_inspector (0.0.2)
|
24
|
+
debugger (1.2.4)
|
25
|
+
columnize (>= 0.3.1)
|
26
|
+
debugger-linecache (~> 1.1.1)
|
27
|
+
debugger-ruby_core_source (~> 1.1.7)
|
28
|
+
debugger-linecache (1.1.2)
|
29
|
+
debugger-ruby_core_source (>= 1.1.1)
|
30
|
+
debugger-ruby_core_source (1.1.8)
|
31
|
+
guard (1.6.2)
|
32
|
+
listen (>= 0.6.0)
|
33
|
+
lumberjack (>= 1.0.2)
|
34
|
+
pry (>= 0.9.10)
|
35
|
+
terminal-table (>= 1.4.3)
|
36
|
+
thor (>= 0.14.6)
|
37
|
+
guard-test (0.7.0)
|
38
|
+
guard (>= 1.1)
|
39
|
+
test-unit (~> 2.2)
|
40
|
+
i18n (0.6.1)
|
41
|
+
listen (0.7.2)
|
42
|
+
lumberjack (1.0.2)
|
43
|
+
metaclass (0.0.1)
|
44
|
+
method_source (0.8.1)
|
45
|
+
mocha (0.13.2)
|
46
|
+
metaclass (~> 0.0.1)
|
47
|
+
multi_json (1.7.1)
|
48
|
+
pry (0.9.12)
|
49
|
+
coderay (~> 1.0.5)
|
50
|
+
method_source (~> 0.8)
|
51
|
+
slop (~> 3.4)
|
52
|
+
pry-debugger (0.2.1)
|
53
|
+
debugger (~> 1.2.0)
|
54
|
+
pry (~> 0.9.10)
|
55
|
+
pry-remote (0.1.6)
|
56
|
+
pry (~> 0.9)
|
57
|
+
slop (~> 3.0)
|
58
|
+
pry-stack_explorer (0.4.9)
|
59
|
+
binding_of_caller (>= 0.7)
|
60
|
+
pry (~> 0.9.11)
|
61
|
+
rake (10.0.4)
|
62
|
+
shoulda (3.3.2)
|
63
|
+
shoulda-context (~> 1.0.1)
|
64
|
+
shoulda-matchers (~> 1.4.1)
|
65
|
+
shoulda-context (1.0.2)
|
66
|
+
shoulda-matchers (1.4.1)
|
67
|
+
activesupport (>= 3.0.0)
|
68
|
+
slop (3.4.3)
|
69
|
+
terminal-table (1.4.5)
|
70
|
+
test-unit (2.5.4)
|
71
|
+
thor (0.17.0)
|
72
|
+
|
73
|
+
PLATFORMS
|
74
|
+
ruby
|
75
|
+
|
76
|
+
DEPENDENCIES
|
77
|
+
bundler (~> 1.0)
|
78
|
+
dooly!
|
79
|
+
guard
|
80
|
+
guard-test
|
81
|
+
mocha
|
82
|
+
pry
|
83
|
+
pry-debugger
|
84
|
+
pry-remote
|
85
|
+
pry-stack_explorer
|
86
|
+
shoulda
|
87
|
+
shoulda-context
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2013 Insoo Jung
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
Dooly
|
2
|
+
==========
|
3
|
+
|
4
|
+
_Dooly_ is a character of Korean animation. [둘리](http://ko.wikipedia.org/wiki/%EB%91%98%EB%A6%AC)
|
5
|
+
|
6
|
+
This gem offer an extension for Rails Serialization, and some helpful feature.
|
7
|
+
|
8
|
+
|
9
|
+
Installation
|
10
|
+
============
|
11
|
+
|
12
|
+
$ gem install dooly
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
Usage
|
17
|
+
==========
|
18
|
+
|
19
|
+
|
20
|
+
Attachment
|
21
|
+
----------
|
22
|
+
|
23
|
+
By including Dooly::Attachment in your class, that class can attach some data to the instance
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
require 'dooly'
|
27
|
+
|
28
|
+
class User < ActiveRecord::Base
|
29
|
+
include Dooly::Attachment
|
30
|
+
make_attachable_as_json
|
31
|
+
end
|
32
|
+
|
33
|
+
user = User.first
|
34
|
+
user.attachment.add(:email, 'dooly@kogil.dong')
|
35
|
+
user.attachment.add(:friends) do |u|
|
36
|
+
u.friends
|
37
|
+
end
|
38
|
+
user.attachment.add(:address, {:city=>'seoul'}) do |u, addr_hash|
|
39
|
+
addr_hash.merge(:landlord=>'ko gil dong')
|
40
|
+
end
|
41
|
+
|
42
|
+
user.as_json
|
43
|
+
# {
|
44
|
+
# 'name'=>'dooly', ... ,
|
45
|
+
# 'email'=>'dooly@kogil.dong',
|
46
|
+
# 'friends'=>user.friends.as_json,
|
47
|
+
# 'address'=>{'city'=>'seoul', 'landlord'=>'ko gil dong'}
|
48
|
+
# }
|
49
|
+
```
|
50
|
+
|
51
|
+
Also extended attachment class can be apply
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
class User < ActiveRecord::Base
|
55
|
+
include Dooly::Attachment
|
56
|
+
|
57
|
+
class Attachment < Dooly::Attachment::Base
|
58
|
+
def add_email
|
59
|
+
self[:email] = body.email
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
make_attachable_as_json User::Attachment
|
64
|
+
end
|
65
|
+
|
66
|
+
user = User.first
|
67
|
+
user.attachment.add_email
|
68
|
+
user.as_json #=> {..., 'email'=>'dooly@kogil.dong'}
|
69
|
+
```
|
70
|
+
|
71
|
+
|
72
|
+
IdProxy
|
73
|
+
----------
|
74
|
+
|
75
|
+
IdProxy is a simple idea for class method that need only model id.
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
class User < ActiveRecord::Base
|
79
|
+
def self.friends(id)
|
80
|
+
NoSQL.find_friends_of(id)
|
81
|
+
end
|
82
|
+
|
83
|
+
def friends
|
84
|
+
self.class.friends(self.id)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
```
|
88
|
+
|
89
|
+
using IdProxy...
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
class User < ActiveRecord::Base
|
93
|
+
include Dooly::IdProxy
|
94
|
+
|
95
|
+
class IdProxy < Dooly::IdProxy::Base
|
96
|
+
def friends
|
97
|
+
NoSQL.find_friends_of(id)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
id_proxy_class IdProxy
|
102
|
+
id_proxy_delegate
|
103
|
+
|
104
|
+
def another_instance_method
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
User.id_proxy(1).friends
|
109
|
+
User.first.friends # instance of original class can call method of id_proxy
|
110
|
+
User.id_proxy(1).another_instance_method # id_proxy can call instance method of original class
|
111
|
+
```
|
112
|
+
|
113
|
+
Collection
|
114
|
+
----------
|
115
|
+
|
116
|
+
Fix as_json root option for collection classes. as-is,
|
117
|
+
|
118
|
+
```ruby
|
119
|
+
User.where('id < 10').as_json(:root=>'users')
|
120
|
+
# [
|
121
|
+
# {"users"=>{"name"=>"dooly"}},
|
122
|
+
# {"users"=>{"name"=>"ddochi"}},
|
123
|
+
# ...
|
124
|
+
# ]
|
125
|
+
```
|
126
|
+
|
127
|
+
fix this,
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
Dooly::Collection::Base.new(User.where('id < 10')).as_json(:root=>'users')
|
131
|
+
# {
|
132
|
+
# "users" => [
|
133
|
+
# {"name"=>"dooly"},
|
134
|
+
# {"name"=>"ddochi"}
|
135
|
+
# ]
|
136
|
+
# }
|
137
|
+
```
|
138
|
+
|
139
|
+
|
140
|
+
Model Regulator
|
141
|
+
---------------
|
142
|
+
|
143
|
+
Model Regulator can reduce effort of parameter validation.
|
144
|
+
|
145
|
+
```ruby
|
146
|
+
class User < ActiveRecord::Base
|
147
|
+
include Dooly::ModelRegulator
|
148
|
+
end
|
149
|
+
|
150
|
+
class Friend < ActiveRecord::Base
|
151
|
+
# this methods can accept number id of user,
|
152
|
+
# number id's string of user, user instance, and id_proxy of user
|
153
|
+
|
154
|
+
def self.sample_method(user)
|
155
|
+
u = User.by(user)
|
156
|
+
# u is a user instance
|
157
|
+
end
|
158
|
+
|
159
|
+
def self.example_method(user)
|
160
|
+
uid = User.id(user)
|
161
|
+
# uid is a number id of user
|
162
|
+
end
|
163
|
+
end
|
164
|
+
```
|
data/Rakefile
ADDED
data/dooly.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require 'dooly/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'dooly'
|
6
|
+
s.description = 'Some helpful feature for rails'
|
7
|
+
s.version = Dooly::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.date = '2013-07-23'
|
10
|
+
s.summary = 'Little dinosaur, Dooly'
|
11
|
+
s.homepage = 'http://github.com/insoul/dooly'
|
12
|
+
s.authors = ['Insoo Jung']
|
13
|
+
s.email = 'ensoul@empal.com'
|
14
|
+
|
15
|
+
s.files = Dir['**/*'].select{|f| File.file?(f)}
|
16
|
+
s.require_path = %w{lib}
|
17
|
+
|
18
|
+
s.add_dependency 'rake'
|
19
|
+
s.add_dependency 'activemodel'
|
20
|
+
s.add_dependency 'activesupport'
|
21
|
+
|
22
|
+
s.add_development_dependency 'bundler', '~> 1.0'
|
23
|
+
s.add_development_dependency 'pry'
|
24
|
+
s.add_development_dependency 'pry-remote'
|
25
|
+
s.add_development_dependency 'pry-stack_explorer'
|
26
|
+
s.add_development_dependency 'pry-debugger'
|
27
|
+
s.add_development_dependency 'mocha'
|
28
|
+
s.add_development_dependency 'shoulda'
|
29
|
+
s.add_development_dependency 'shoulda-context'
|
30
|
+
s.add_development_dependency 'guard'
|
31
|
+
s.add_development_dependency 'guard-test'
|
32
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module Dooly
|
2
|
+
module Attachment
|
3
|
+
class Base < HashWithIndifferentAccess
|
4
|
+
attr_accessor :body
|
5
|
+
|
6
|
+
def add(k, value = nil, options = {})
|
7
|
+
if key?(k)
|
8
|
+
warn_duplicated(k); return fetch(k)
|
9
|
+
end
|
10
|
+
|
11
|
+
if value
|
12
|
+
store(k, value)
|
13
|
+
if block_given?
|
14
|
+
self.as_json_procs(k, &Proc.new)
|
15
|
+
end
|
16
|
+
elsif block_given?
|
17
|
+
store(k, Proc.new)
|
18
|
+
else
|
19
|
+
warn_unassigned_value(k)
|
20
|
+
end
|
21
|
+
|
22
|
+
if options[:as_json_options]
|
23
|
+
as_json_options(k, options[:as_json_options])
|
24
|
+
else
|
25
|
+
as_json_options(k, options) unless options.empty?
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def as_json_options(k = nil, options = nil)
|
30
|
+
@as_json_options ||= HashWithIndifferentAccess.new
|
31
|
+
return @as_json_options if k.nil?
|
32
|
+
return @as_json_options[k] if options.nil?
|
33
|
+
|
34
|
+
@as_json_options[k] = options
|
35
|
+
end
|
36
|
+
|
37
|
+
def as_json_procs(k = nil)
|
38
|
+
@as_json_procs ||= HashWithIndifferentAccess.new
|
39
|
+
return @as_json_procs if k.nil?
|
40
|
+
return @as_json_procs[k] unless block_given?
|
41
|
+
|
42
|
+
@as_json_procs[k] = Proc.new
|
43
|
+
end
|
44
|
+
|
45
|
+
def as_json_procs_run(k = nil, value = nil)
|
46
|
+
@as_json_procs_run ||= HashWithIndifferentAccess.new
|
47
|
+
return @as_json_procs_run if k.nil?
|
48
|
+
return @as_json_procs_run[k] if value.nil?
|
49
|
+
|
50
|
+
@as_json_procs_run[k] = value
|
51
|
+
end
|
52
|
+
|
53
|
+
alias :to_hash_with_string :to_hash
|
54
|
+
|
55
|
+
def to_hash
|
56
|
+
to_hash_with_string.symbolize_keys
|
57
|
+
end
|
58
|
+
|
59
|
+
def [](key)
|
60
|
+
value = fetch(key, nil)
|
61
|
+
return nil if value.nil?
|
62
|
+
|
63
|
+
if Proc === value
|
64
|
+
value = value.call(body)
|
65
|
+
store(key, value)
|
66
|
+
end
|
67
|
+
|
68
|
+
fetch(key)
|
69
|
+
end
|
70
|
+
|
71
|
+
def as_json
|
72
|
+
self.each_pair do |k, v|
|
73
|
+
if self.as_json_procs(k) and !as_json_procs_run(k)
|
74
|
+
v = self.as_json_procs(k).call(body, v)
|
75
|
+
self.as_json_procs_run(k, true)
|
76
|
+
end
|
77
|
+
|
78
|
+
if Proc === v
|
79
|
+
self[k] = v.call(body).as_json
|
80
|
+
elsif v.respond_to?(:as_json)
|
81
|
+
if as_json_options(k)
|
82
|
+
self[k] = v.as_json(as_json_options(k)).as_json
|
83
|
+
else
|
84
|
+
self[k] = v.as_json
|
85
|
+
end
|
86
|
+
else
|
87
|
+
self[k] = v.as_json
|
88
|
+
end
|
89
|
+
end
|
90
|
+
self
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
def warn_unassigned_value(key)
|
95
|
+
message = ["Attachment has been tried to add with none value, #{self.class.name}/#{key}"]
|
96
|
+
message += caller if Rails.env.development?
|
97
|
+
Configuration.logger.warn(message.join("\n"))
|
98
|
+
end
|
99
|
+
|
100
|
+
def warn_duplicated(key)
|
101
|
+
message = ["Attachment has been tried to add repeatedly about key, #{self.class.name}/#{key}."]
|
102
|
+
message += caller if Rails.env.development?
|
103
|
+
Configuration.logger.warn(message.join("\n"))
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Dooly
|
2
|
+
module Attachment
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
class_attribute :attachment_klass
|
7
|
+
self.attachment_klass = Dooly::Attachment::Base
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def make_attachable_as_json(klass = nil)
|
12
|
+
klass = Dooly::Attachment::Base if klass.nil?
|
13
|
+
unless klass <= Dooly::Attachment::Base
|
14
|
+
raise "Attachment class must inherit Dooly::Attachment::Base: #{klass}"
|
15
|
+
end
|
16
|
+
self.attachment_klass = klass
|
17
|
+
|
18
|
+
if self.instance_methods.include?(:as_json)
|
19
|
+
self.class_eval do
|
20
|
+
alias :as_json_exclude_attachment :as_json
|
21
|
+
define_method(:as_json) do |options = {}, &block|
|
22
|
+
js = if block
|
23
|
+
as_json_exclude_attachment(options, &block)
|
24
|
+
else
|
25
|
+
as_json_exclude_attachment(options)
|
26
|
+
end
|
27
|
+
|
28
|
+
js.class <= Hash ? js.merge(attachment.as_json) : js
|
29
|
+
end
|
30
|
+
end
|
31
|
+
else
|
32
|
+
self.class_eval do
|
33
|
+
define_method(:as_json) do |options = {}|
|
34
|
+
attachment.as_json
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def attachment
|
42
|
+
return @attachment if @attachment
|
43
|
+
am = self.attachment_klass.new
|
44
|
+
am.body = self
|
45
|
+
@attachment = am
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Dooly
|
2
|
+
module Collection
|
3
|
+
class Base
|
4
|
+
include ActiveModel::Serializers::JSON
|
5
|
+
|
6
|
+
extend Forwardable
|
7
|
+
def_delegators :@collection, *Enumerable.instance_methods
|
8
|
+
def_delegators :@collection, :each
|
9
|
+
|
10
|
+
include Dooly::Attachment
|
11
|
+
|
12
|
+
attr_reader :collection
|
13
|
+
|
14
|
+
class_attribute :include_root_in_json
|
15
|
+
|
16
|
+
def initialize(*args)
|
17
|
+
if args.first.respond_to?(:each)
|
18
|
+
args = args.first
|
19
|
+
end
|
20
|
+
@collection = args
|
21
|
+
end
|
22
|
+
|
23
|
+
def as_json(options = {})
|
24
|
+
root = options.delete(:root) || self.include_root_in_json
|
25
|
+
jsons = block_given? ? self.as_jsons(options, &Proc.new) : self.as_jsons(options)
|
26
|
+
if root
|
27
|
+
if root == true
|
28
|
+
root = begin
|
29
|
+
@collection[0].class.model_name.element.pluralize
|
30
|
+
rescue
|
31
|
+
self.class.name.underscore.split('/')[-2].pluralize rescue 'collection'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
{root => jsons}
|
35
|
+
else
|
36
|
+
jsons
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def as_jsons(options = {})
|
41
|
+
@collection.map do |member|
|
42
|
+
if block_given?
|
43
|
+
member.as_json(options, &Proc.new)
|
44
|
+
else
|
45
|
+
member.as_json(options)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
make_attachable_as_json
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Dooly
|
2
|
+
module Collection
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
class_attribute :collection_klass
|
7
|
+
self.collection_klass = Dooly::Collection::Base
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def collection_class(klass)
|
12
|
+
unless klass <= Dooly::Collection::Base
|
13
|
+
raise "Collection class must inherit Dooly::Colletion::Base: #{klass}"
|
14
|
+
end
|
15
|
+
self.collection_klass = klass
|
16
|
+
end
|
17
|
+
|
18
|
+
def collection(*args)
|
19
|
+
self.collection_klass.new(*args)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Dooly
|
2
|
+
module IdProxy
|
3
|
+
class Base
|
4
|
+
class << self
|
5
|
+
attr_accessor :model
|
6
|
+
attr_reader :finders
|
7
|
+
|
8
|
+
def finders=(*args)
|
9
|
+
if args[0].is_a? Array
|
10
|
+
@finders = args[0]
|
11
|
+
else
|
12
|
+
@finders = args
|
13
|
+
end
|
14
|
+
end
|
15
|
+
alias :finder :finders
|
16
|
+
alias :finder= :finders=
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :id
|
20
|
+
|
21
|
+
def initialize(id)
|
22
|
+
raise 'idea must have id' if id.blank?
|
23
|
+
@id = id
|
24
|
+
end
|
25
|
+
|
26
|
+
def record
|
27
|
+
return @record if @record
|
28
|
+
|
29
|
+
self.class.finders.each do |finder|
|
30
|
+
f = finder.to_sym
|
31
|
+
if self.class.model.respond_to?(f)
|
32
|
+
@record = self.class.model.send(f, self.id)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
unless @record
|
37
|
+
@record = self.class.model.find(self.id)
|
38
|
+
end
|
39
|
+
|
40
|
+
@record
|
41
|
+
end
|
42
|
+
|
43
|
+
def respond_to?(name)
|
44
|
+
self.record.respond_to?(name) || super
|
45
|
+
end
|
46
|
+
|
47
|
+
def method_missing(name, *args, &block)
|
48
|
+
self.record.send(name, *args, &block)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Dooly
|
2
|
+
module IdProxy
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
class_attribute :id_proxy_klass, :id_proxy_options
|
7
|
+
self.id_proxy_klass = Dooly::IdProxy::Base
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def id_proxy_class(klass, options = {})
|
12
|
+
raise "Id Proxy class must inherit Dooly::IdProxyBase: #{klass}" unless klass <= Dooly::IdProxy::Base
|
13
|
+
self.id_proxy_klass = klass
|
14
|
+
self.id_proxy_klass.model = self
|
15
|
+
finders = options[:finders] || options[:finder]
|
16
|
+
self.id_proxy_klass.finders = finders if finders
|
17
|
+
end
|
18
|
+
|
19
|
+
def id_proxy_delegate
|
20
|
+
self.extend Forwardable
|
21
|
+
self.def_delegators 'self.id_proxy', *self.id_proxy_klass.instance_methods(false)
|
22
|
+
end
|
23
|
+
|
24
|
+
def id_proxy(*args)
|
25
|
+
options = args.extract_options!
|
26
|
+
|
27
|
+
if args.length > 1
|
28
|
+
return args.map {|arg| id(arg, options)}
|
29
|
+
end
|
30
|
+
|
31
|
+
value = args[0]
|
32
|
+
begin
|
33
|
+
return value.idx if value.is_a? self
|
34
|
+
return self.id_proxy_klass.new(value) if value.is_a? Integer
|
35
|
+
return self.id_proxy_klass.new(Integer(value)) if value.is_a? String
|
36
|
+
return value if Dooly::IdProxy::Base === value
|
37
|
+
|
38
|
+
if options[:relate]
|
39
|
+
fn = options[:relate] == true ? "#{self.name.underscore}_id".to_sym : options[:relate].to_sym
|
40
|
+
return self.id_proxy_klass.new(value.send(fn)) if value.respond_to?(fn)
|
41
|
+
end
|
42
|
+
rescue => e
|
43
|
+
raise "Cannot make id_proxy from #{self.name} with #{value.to_s}: #{e}"
|
44
|
+
else
|
45
|
+
raise "Cannot make id_proxy from #{self.name} with #{value.to_s}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
alias :idx :id_proxy
|
49
|
+
end
|
50
|
+
|
51
|
+
def id_proxy
|
52
|
+
return nil unless self.id
|
53
|
+
@id_proxy ||= self.id_proxy_klass.new(self.id)
|
54
|
+
end
|
55
|
+
alias :idx :id_proxy
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Dooly
|
2
|
+
module ModelRegulator
|
3
|
+
def model_regulator_finder(finder = nil)
|
4
|
+
return (@model_regulator_finder || :find) if finder.nil?
|
5
|
+
@model_regulator_finder = finder.to_sym
|
6
|
+
end
|
7
|
+
|
8
|
+
def by(*args)
|
9
|
+
options = args.extract_options!
|
10
|
+
|
11
|
+
if args.length > 1
|
12
|
+
return args.map {|arg| by(arg, options)}
|
13
|
+
end
|
14
|
+
|
15
|
+
value = args[0]
|
16
|
+
begin
|
17
|
+
return value if value.is_a? self
|
18
|
+
return self.send(model_regulator_finder, value) if value.is_a? Integer
|
19
|
+
return self.send(model_regulator_finder, Integer(value)) if value.is_a? String
|
20
|
+
return value.record if Dooly::IdProxy::Base === value
|
21
|
+
|
22
|
+
if options[:relate]
|
23
|
+
fn = options[:relate] == true ? "#{self.name.underscore}_id".to_sym : options[:relate].to_sym
|
24
|
+
return self.send(model_regulator_finder, value.send(fn)) if value.respond_to?(fn)
|
25
|
+
end
|
26
|
+
rescue => e
|
27
|
+
raise "Cannot find record from #{self.name} with #{value.to_s}: #{e}"
|
28
|
+
else
|
29
|
+
raise "Cannot find record from #{self.name} with #{value.to_s}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def id(*args)
|
34
|
+
options = args.extract_options!
|
35
|
+
|
36
|
+
if args.length > 1
|
37
|
+
return args.map {|arg| id(arg, options)}
|
38
|
+
end
|
39
|
+
|
40
|
+
value = args[0]
|
41
|
+
begin
|
42
|
+
return value.id if value.is_a? self
|
43
|
+
return value if value.is_a? Integer
|
44
|
+
return Integer(value) if value.is_a? String
|
45
|
+
return value.id if Dooly::IdProxy::Base === value
|
46
|
+
|
47
|
+
if options[:relate]
|
48
|
+
fn = options[:relate] == true ? "#{self.name.underscore}_id".to_sym : options[:relate].to_sym
|
49
|
+
return value.send(fn) if value.respond_to?(fn)
|
50
|
+
end
|
51
|
+
rescue => e
|
52
|
+
raise "Cannot find id from #{self.name} with #{value.to_s}: #{e}"
|
53
|
+
else
|
54
|
+
raise "Cannot find id from #{self.name} with #{value.to_s}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/dooly.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'active_support'
|
3
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
4
|
+
require 'active_support/core_ext/class/attribute'
|
5
|
+
require 'active_support/concern'
|
6
|
+
require 'active_support/hash_with_indifferent_access'
|
7
|
+
require 'active_model/serialization'
|
8
|
+
require 'active_model/naming'
|
9
|
+
require 'active_model/serializers/json'
|
10
|
+
require 'dooly/version'
|
11
|
+
require 'dooly/attachment'
|
12
|
+
require 'dooly/attachment/base'
|
13
|
+
require 'dooly/collection'
|
14
|
+
require 'dooly/collection/base'
|
15
|
+
require 'dooly/id_proxy'
|
16
|
+
require 'dooly/id_proxy/base'
|
17
|
+
require 'dooly/model_regulator'
|
18
|
+
|
19
|
+
module Dooly
|
20
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Dooly
|
4
|
+
class TestAttachment < Test::Unit::TestCase
|
5
|
+
|
6
|
+
class ModelSample
|
7
|
+
include ActiveModel::Serializers::JSON
|
8
|
+
self.include_root_in_json = false
|
9
|
+
include Dooly::Attachment
|
10
|
+
|
11
|
+
attr_accessor :name
|
12
|
+
|
13
|
+
def attributes
|
14
|
+
{'name' => name}
|
15
|
+
end
|
16
|
+
|
17
|
+
make_attachable_as_json
|
18
|
+
end
|
19
|
+
|
20
|
+
class ValueSample
|
21
|
+
attr_accessor :value
|
22
|
+
end
|
23
|
+
|
24
|
+
class DefaultSample
|
25
|
+
include Dooly::Attachment
|
26
|
+
end
|
27
|
+
|
28
|
+
def setup
|
29
|
+
super
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'attachment' do
|
33
|
+
setup do
|
34
|
+
@model = ModelSample.new
|
35
|
+
@model.name = 'ddochi'
|
36
|
+
end
|
37
|
+
|
38
|
+
should 'simply' do
|
39
|
+
assert_equal({'name'=>'ddochi'}, @model.as_json)
|
40
|
+
end
|
41
|
+
|
42
|
+
should 'defalut attachment class' do
|
43
|
+
assert_equal(Dooly::Attachment::Base, DefaultSample.new.attachment.class)
|
44
|
+
end
|
45
|
+
|
46
|
+
should 'attach key-value' do
|
47
|
+
@model.attachment.add(:friend, 'donor')
|
48
|
+
assert_equal({'name'=>'ddochi', 'friend'=>'donor'}, @model.as_json)
|
49
|
+
end
|
50
|
+
|
51
|
+
should 'attach key-block' do
|
52
|
+
@model.attachment.add(:friend) do |body|
|
53
|
+
body.name + " and donor"
|
54
|
+
end
|
55
|
+
assert_equal({'name'=>'ddochi', 'friend'=>'ddochi and donor'}, @model.as_json)
|
56
|
+
|
57
|
+
# block must be called only once
|
58
|
+
assert_equal({'name'=>'ddochi', 'friend'=>'ddochi and donor'}, @model.as_json)
|
59
|
+
end
|
60
|
+
|
61
|
+
should 'attach key-value with block' do
|
62
|
+
v = ValueSample.new
|
63
|
+
v.value = 'donor'
|
64
|
+
@model.attachment.add(:friend, v) do |body, value|
|
65
|
+
"#{body.name} #{value.value}"
|
66
|
+
end
|
67
|
+
assert_equal({'name'=>'ddochi', 'friend'=>'ddochi donor'}, @model.as_json)
|
68
|
+
|
69
|
+
# block must be called only once
|
70
|
+
assert_equal({'name'=>'ddochi', 'friend'=>'ddochi donor'}, @model.as_json)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Dooly
|
2
|
+
class TestCollection < Test::Unit::TestCase
|
3
|
+
class ModelSample
|
4
|
+
attr_accessor :name
|
5
|
+
include Dooly::Collection
|
6
|
+
include ActiveModel::Serializers::JSON
|
7
|
+
self.include_root_in_json = false
|
8
|
+
include Dooly::Attachment
|
9
|
+
|
10
|
+
def initialize(name)
|
11
|
+
@name = name
|
12
|
+
end
|
13
|
+
|
14
|
+
def attributes
|
15
|
+
{'name' => name}
|
16
|
+
end
|
17
|
+
|
18
|
+
def as_json(options = {})
|
19
|
+
js = super
|
20
|
+
js = yield(js) if block_given?
|
21
|
+
js
|
22
|
+
end
|
23
|
+
make_attachable_as_json
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'collection' do
|
27
|
+
setup do
|
28
|
+
@ddochi = ModelSample.new('ddochi')
|
29
|
+
@donor = ModelSample.new('donor')
|
30
|
+
@friends = ModelSample.collection(@ddochi, @donor)
|
31
|
+
@friends.attachment.add(:total, 2)
|
32
|
+
end
|
33
|
+
|
34
|
+
should 'simply' do
|
35
|
+
assert_equal([{"name"=>"ddochi"}, {"name"=>"donor"}], @friends.as_json)
|
36
|
+
assert_equal({
|
37
|
+
'friends' => [{"name"=>"ddochi"}, {"name"=>"donor"}],
|
38
|
+
'total' => 2
|
39
|
+
}, @friends.as_json(:root => 'friends'))
|
40
|
+
assert_equal('ddochi', @friends.to_a[0].name)
|
41
|
+
end
|
42
|
+
|
43
|
+
should 'block call by member' do
|
44
|
+
assert_equal([
|
45
|
+
{'name'=>'ddochi', 'friend_of'=>'dooly'},
|
46
|
+
{'name'=>'donor', 'friend_of'=>'dooly'}
|
47
|
+
],@friends.as_json {|f| f.merge('friend_of' => 'dooly')})
|
48
|
+
end
|
49
|
+
|
50
|
+
should 'just using base class' do
|
51
|
+
assert_equal({
|
52
|
+
'friends' => [{"name"=>"ddochi"}, {"name"=>"donor"}]
|
53
|
+
}, Dooly::Collection::Base.new([@ddochi, @donor]).as_json(:root=>'friends'))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
module Dooly
|
2
|
+
class TestIdProxy < Test::Unit::TestCase
|
3
|
+
class ModelSample
|
4
|
+
attr_accessor :id
|
5
|
+
|
6
|
+
class IdProxyClass < Dooly::IdProxy::Base
|
7
|
+
def proxy_method_sample(arg)
|
8
|
+
['class', arg, self.id.to_s].join(' ')
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
include Dooly::IdProxy
|
13
|
+
id_proxy_class IdProxyClass, :finder => :get_cache
|
14
|
+
id_proxy_delegate
|
15
|
+
|
16
|
+
def instance_method_sample(arg)
|
17
|
+
['instance', arg, @id.to_s].join(' ')
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.get_cache(id)
|
21
|
+
instance = self.new
|
22
|
+
instance.id = id
|
23
|
+
instance
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class DefaultSample
|
28
|
+
attr_accessor :id
|
29
|
+
include Dooly::IdProxy
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'id_proxy' do
|
33
|
+
setup do
|
34
|
+
@model = ModelSample.new
|
35
|
+
@model.id = 11
|
36
|
+
end
|
37
|
+
|
38
|
+
should 'simply' do
|
39
|
+
assert_equal('class simply 11', @model.proxy_method_sample('simply'))
|
40
|
+
assert_equal('instance simply 11', ModelSample.id_proxy(11).instance_method_sample('simply'))
|
41
|
+
end
|
42
|
+
|
43
|
+
should 'default id proxy class' do
|
44
|
+
assert_equal(Dooly::IdProxy::Base, DefaultSample.idx(11).class)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Dooly
|
4
|
+
class TestModelRegulator < Test::Unit::TestCase
|
5
|
+
class ModelSample
|
6
|
+
attr_accessor :id
|
7
|
+
extend Dooly::ModelRegulator
|
8
|
+
|
9
|
+
def self.find(id)
|
10
|
+
instance = self.new
|
11
|
+
instance.id = id
|
12
|
+
instance
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class CacheSample
|
17
|
+
attr_accessor :id
|
18
|
+
extend Dooly::ModelRegulator
|
19
|
+
model_regulator_finder :get_cache
|
20
|
+
|
21
|
+
def self.get_cache(id)
|
22
|
+
instance = self.new
|
23
|
+
instance.id = id
|
24
|
+
instance
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def setup
|
29
|
+
super
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'model_regulator' do
|
33
|
+
setup do
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
should 'simply' do
|
38
|
+
instance = ModelSample.new
|
39
|
+
instance.id = 11
|
40
|
+
assert_equal(11, ModelSample.by(instance).id)
|
41
|
+
assert_equal(11, ModelSample.id(instance))
|
42
|
+
assert_equal(11, ModelSample.by(11).id)
|
43
|
+
assert_equal(11, ModelSample.id(11))
|
44
|
+
assert_equal(11, ModelSample.by('11').id)
|
45
|
+
assert_equal(11, ModelSample.id('11'))
|
46
|
+
end
|
47
|
+
|
48
|
+
should 'simple cache' do
|
49
|
+
instance = CacheSample.new
|
50
|
+
instance.id = 11
|
51
|
+
assert_equal(11, CacheSample.by(instance).id)
|
52
|
+
assert_equal(11, CacheSample.id(instance))
|
53
|
+
assert_equal(11, CacheSample.by(11).id)
|
54
|
+
assert_equal(11, CacheSample.id(11))
|
55
|
+
assert_equal(11, CacheSample.by('11').id)
|
56
|
+
assert_equal(11, CacheSample.id('11'))
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
metadata
ADDED
@@ -0,0 +1,210 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dooly
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Insoo Jung
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-07-23 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: &70342471631920 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70342471631920
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: activemodel
|
27
|
+
requirement: &70342471631080 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70342471631080
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: activesupport
|
38
|
+
requirement: &70342471629800 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70342471629800
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: bundler
|
49
|
+
requirement: &70342471629000 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70342471629000
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: pry
|
60
|
+
requirement: &70342471628260 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70342471628260
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry-remote
|
71
|
+
requirement: &70342471626760 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70342471626760
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: pry-stack_explorer
|
82
|
+
requirement: &70342471626100 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *70342471626100
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: pry-debugger
|
93
|
+
requirement: &70342471625040 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
type: :development
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *70342471625040
|
102
|
+
- !ruby/object:Gem::Dependency
|
103
|
+
name: mocha
|
104
|
+
requirement: &70342471623840 !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: *70342471623840
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: shoulda
|
115
|
+
requirement: &70342471623320 !ruby/object:Gem::Requirement
|
116
|
+
none: false
|
117
|
+
requirements:
|
118
|
+
- - ! '>='
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
type: :development
|
122
|
+
prerelease: false
|
123
|
+
version_requirements: *70342471623320
|
124
|
+
- !ruby/object:Gem::Dependency
|
125
|
+
name: shoulda-context
|
126
|
+
requirement: &70342471622660 !ruby/object:Gem::Requirement
|
127
|
+
none: false
|
128
|
+
requirements:
|
129
|
+
- - ! '>='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: *70342471622660
|
135
|
+
- !ruby/object:Gem::Dependency
|
136
|
+
name: guard
|
137
|
+
requirement: &70342471621900 !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
139
|
+
requirements:
|
140
|
+
- - ! '>='
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
type: :development
|
144
|
+
prerelease: false
|
145
|
+
version_requirements: *70342471621900
|
146
|
+
- !ruby/object:Gem::Dependency
|
147
|
+
name: guard-test
|
148
|
+
requirement: &70342471658400 !ruby/object:Gem::Requirement
|
149
|
+
none: false
|
150
|
+
requirements:
|
151
|
+
- - ! '>='
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
type: :development
|
155
|
+
prerelease: false
|
156
|
+
version_requirements: *70342471658400
|
157
|
+
description: Some helpful feature for rails
|
158
|
+
email: ensoul@empal.com
|
159
|
+
executables: []
|
160
|
+
extensions: []
|
161
|
+
extra_rdoc_files: []
|
162
|
+
files:
|
163
|
+
- dooly-0.1.0.gem
|
164
|
+
- dooly.gemspec
|
165
|
+
- Gemfile
|
166
|
+
- Gemfile.lock
|
167
|
+
- lib/dooly/attachment/base.rb
|
168
|
+
- lib/dooly/attachment.rb
|
169
|
+
- lib/dooly/collection/base.rb
|
170
|
+
- lib/dooly/collection.rb
|
171
|
+
- lib/dooly/configuration.rb
|
172
|
+
- lib/dooly/id_proxy/base.rb
|
173
|
+
- lib/dooly/id_proxy.rb
|
174
|
+
- lib/dooly/model_regulator.rb
|
175
|
+
- lib/dooly/version.rb
|
176
|
+
- lib/dooly.rb
|
177
|
+
- MIT-LICENSE
|
178
|
+
- Rakefile
|
179
|
+
- README.markdown
|
180
|
+
- test/test_attachment.rb
|
181
|
+
- test/test_collection.rb
|
182
|
+
- test/test_helper.rb
|
183
|
+
- test/test_id_proxy.rb
|
184
|
+
- test/test_model_regulator.rb
|
185
|
+
homepage: http://github.com/insoul/dooly
|
186
|
+
licenses: []
|
187
|
+
post_install_message:
|
188
|
+
rdoc_options: []
|
189
|
+
require_paths:
|
190
|
+
- - lib
|
191
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
192
|
+
none: false
|
193
|
+
requirements:
|
194
|
+
- - ! '>='
|
195
|
+
- !ruby/object:Gem::Version
|
196
|
+
version: '0'
|
197
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
198
|
+
none: false
|
199
|
+
requirements:
|
200
|
+
- - ! '>='
|
201
|
+
- !ruby/object:Gem::Version
|
202
|
+
version: '0'
|
203
|
+
requirements: []
|
204
|
+
rubyforge_project:
|
205
|
+
rubygems_version: 1.8.17
|
206
|
+
signing_key:
|
207
|
+
specification_version: 3
|
208
|
+
summary: Little dinosaur, Dooly
|
209
|
+
test_files: []
|
210
|
+
has_rdoc:
|