pinkman 0.9.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.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/Rakefile +28 -0
- data/app/assets/javascripts/pinkman.js +10 -0
- data/app/assets/javascripts/pinkman_base/ajax.coffee +90 -0
- data/app/assets/javascripts/pinkman_base/collection.coffee +387 -0
- data/app/assets/javascripts/pinkman_base/common.coffee +56 -0
- data/app/assets/javascripts/pinkman_base/controller.coffee +164 -0
- data/app/assets/javascripts/pinkman_base/glue.coffee +15 -0
- data/app/assets/javascripts/pinkman_base/handlebars.js +4608 -0
- data/app/assets/javascripts/pinkman_base/hogan.js +576 -0
- data/app/assets/javascripts/pinkman_base/markup.js +483 -0
- data/app/assets/javascripts/pinkman_base/mixins.coffee +37 -0
- data/app/assets/javascripts/pinkman_base/object.js.coffee.erb +195 -0
- data/app/assets/javascripts/pinkman_base/pinkman.coffee +131 -0
- data/app/assets/javascripts/pinkman_base/render.coffee.erb +80 -0
- data/app/assets/javascripts/pinkman_base/tools.coffee +4 -0
- data/app/helpers/pinkman_helper.rb +48 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/generators/pinkman/USAGE +16 -0
- data/lib/generators/pinkman/api_generator.rb +60 -0
- data/lib/generators/pinkman/install_generator.rb +25 -0
- data/lib/generators/pinkman/model_generator.rb +41 -0
- data/lib/generators/pinkman/resource_generator.rb +15 -0
- data/lib/generators/pinkman/serializer_generator.rb +33 -0
- data/lib/generators/pinkman/templates/api.rb.erb +87 -0
- data/lib/generators/pinkman/templates/api_controller.rb +2 -0
- data/lib/generators/pinkman/templates/collection.js.erb +5 -0
- data/lib/generators/pinkman/templates/object.js.erb +3 -0
- data/lib/generators/pinkman/templates/serializer.rb.erb +15 -0
- data/lib/pinkman.rb +57 -0
- data/lib/pinkman/serializer.rb +6 -0
- data/lib/pinkman/serializer/base.rb +42 -0
- data/lib/pinkman/serializer/scope.rb +48 -0
- data/lib/pinkman/version.rb +3 -0
- data/pinkman.gemspec +46 -0
- data/public/javascripts/pinkman.min.js +1 -0
- data/public/jquery.pinkman.min.js +0 -0
- data/public/pinkman.min.js +29 -0
- metadata +242 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c608ca91577bd19a8d7014ddd49c49d58f9ef12a
|
4
|
+
data.tar.gz: 14851ec0f71e7a62df16622c525ad42efdb32114
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2f0636432c7af59425a2f87d803798b837eb745de32200f71cd05d58bef06aff4bb8369c2c6955de367db62b75e3b8da5927c6810650566d1444543f5e5d2fe8
|
7
|
+
data.tar.gz: c957e9f96a1c2d4c1fd41ebb3463059075cf182d2011444643be516931ec9f339222184eaff8a99164662389c9d13b271d4b4b1b86ef72a53d41a903e27edda4
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 Agilso Oliveira
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# Pinkman
|
2
|
+
|
3
|
+
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/pinkman`. To experiment with that code, run `bin/console` for an interactive prompt.
|
4
|
+
|
5
|
+
TODO: Delete this and the text above, and describe your gem
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'pinkman'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install pinkman
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
TODO: Write usage instructions here
|
26
|
+
|
27
|
+
## Development
|
28
|
+
|
29
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
30
|
+
|
31
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
32
|
+
|
33
|
+
## Contributing
|
34
|
+
|
35
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/pinkman.
|
36
|
+
|
37
|
+
|
38
|
+
## License
|
39
|
+
|
40
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
41
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
require 'pinkman'
|
4
|
+
require Pinkman.root.join('spec/support/sprockets')
|
5
|
+
|
6
|
+
task :default => :spec
|
7
|
+
require 'jasmine'
|
8
|
+
load 'jasmine/tasks/jasmine.rake'
|
9
|
+
RSpec::Core::RakeTask.new(:spec)
|
10
|
+
|
11
|
+
namespace :pinkman do
|
12
|
+
desc 'Precompile pinkman.js'
|
13
|
+
task :precompile do
|
14
|
+
f = File.open(Pinkman.root.join('public','pinkman.min.js'),'w+') {|f| f.write Assets.app_environment['pinkman'].to_s }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
namespace :spec do
|
19
|
+
|
20
|
+
desc 'Compile spec.js and coffeescripts specs to js'
|
21
|
+
task precompile: ['pinkman:precompile'] do
|
22
|
+
f = File.open(Pinkman.root.join('spec','javascripts','spec.js'),'w+') {|f| f.write Assets.spec_environment['support/spec_helper'].to_s }
|
23
|
+
end
|
24
|
+
|
25
|
+
desc 'Run JS (Jasmine) Specs'
|
26
|
+
task :js => ['spec:precompile', 'jasmine']
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
//= require pinkman_base/handlebars
|
2
|
+
//= require pinkman_base/tools
|
3
|
+
//= require pinkman_base/pinkman
|
4
|
+
//= require pinkman_base/mixins
|
5
|
+
//= require pinkman_base/common
|
6
|
+
//= require pinkman_base/object
|
7
|
+
//= require pinkman_base/collection
|
8
|
+
//= require pinkman_base/render
|
9
|
+
//= require pinkman_base/controller
|
10
|
+
//= require pinkman_base/ajax
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# @ajax:
|
2
|
+
# get: (options) ->
|
3
|
+
# if options.url?
|
4
|
+
# ajax = jQuery.ajax options.url,
|
5
|
+
# type: "GET"
|
6
|
+
# dataType: 'json'
|
7
|
+
# ajax.done (response) =>
|
8
|
+
# if response.errors?
|
9
|
+
# options.error(response) if options.error? and typeof options.error == 'function'
|
10
|
+
# return false
|
11
|
+
# else
|
12
|
+
# options.success(response) if options.success? and typeof options.success == 'function'
|
13
|
+
# options.complete(response) if options.complete? and typeof options.complete == 'function'
|
14
|
+
# return this
|
15
|
+
# else
|
16
|
+
# return false
|
17
|
+
|
18
|
+
# post: (options) ->
|
19
|
+
# if options.url?
|
20
|
+
# ajax = jQuery.ajax options.url,
|
21
|
+
# beforeSend: (xhr) ->
|
22
|
+
# xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
|
23
|
+
# type: "POST"
|
24
|
+
# dataType: 'json'
|
25
|
+
# data: options.data
|
26
|
+
# ajax.done (response) =>
|
27
|
+
# if response.errors?
|
28
|
+
# options.error(this) if options.error? and typeof options.error == 'function'
|
29
|
+
# return false
|
30
|
+
# else
|
31
|
+
# options.success(response) if options.success? and typeof options.success == 'function'
|
32
|
+
# options.complete(response) if options.complete? and typeof options.complete == 'function'
|
33
|
+
# return this
|
34
|
+
# else
|
35
|
+
# return false
|
36
|
+
|
37
|
+
# put: (options) ->
|
38
|
+
# if options.url?
|
39
|
+
# ajax = jQuery.ajax options.url,
|
40
|
+
# beforeSend: (xhr) ->
|
41
|
+
# xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
|
42
|
+
# type: "PUT"
|
43
|
+
# dataType: 'json'
|
44
|
+
# data: options.data
|
45
|
+
# ajax.done (response) =>
|
46
|
+
# if response.errors?
|
47
|
+
# options.error(this) if options.error? and typeof options.error == 'function'
|
48
|
+
# return false
|
49
|
+
# else
|
50
|
+
# options.success(response) if options.success? and typeof options.success == 'function'
|
51
|
+
# options.complete(response) if options.complete? and typeof options.complete == 'function'
|
52
|
+
# return this
|
53
|
+
# else
|
54
|
+
# return false
|
55
|
+
|
56
|
+
|
57
|
+
# file: (options) ->
|
58
|
+
# if options.url?
|
59
|
+
# ajax = jQuery.ajax options.url,
|
60
|
+
# beforeSend: (xhr) ->
|
61
|
+
# xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
|
62
|
+
# xhr: ->
|
63
|
+
# myXhr = $.ajaxSettings.xhr()
|
64
|
+
# myXhr.upload.addEventListener 'progress', (e) ->
|
65
|
+
# if e.lengthComputable
|
66
|
+
# options.progress e.loaded/e.total if options.progress?
|
67
|
+
# , false
|
68
|
+
# myXhr.addEventListener 'progress', (e) ->
|
69
|
+
# if e.lengthComputable
|
70
|
+
# options.progress e.loaded/e.total if options.progress?
|
71
|
+
# , false
|
72
|
+
# return myXhr
|
73
|
+
# type: "POST"
|
74
|
+
# dataType: 'json'
|
75
|
+
# data: options.data
|
76
|
+
# processData: false
|
77
|
+
# contentType: false
|
78
|
+
# ajax.done (response) =>
|
79
|
+
# if response? and response.errors?
|
80
|
+
# options.error(this) if options.error? and typeof options.error == 'function'
|
81
|
+
# return false
|
82
|
+
# else
|
83
|
+
# options.success(response) if options.success? and typeof options.success == 'function'
|
84
|
+
# options.complete(response) if options.complete? and typeof options.complete == 'function'
|
85
|
+
# return this
|
86
|
+
# else
|
87
|
+
# return false
|
88
|
+
|
89
|
+
# upload: (options...) ->
|
90
|
+
# @file(options...)
|
@@ -0,0 +1,387 @@
|
|
1
|
+
class window.PinkmanCollection extends window.PinkmanCommon
|
2
|
+
|
3
|
+
@pinkmanType = 'collection'
|
4
|
+
|
5
|
+
config:
|
6
|
+
memberClass: PinkmanObject
|
7
|
+
|
8
|
+
constructor: () ->
|
9
|
+
|
10
|
+
@isPink = true
|
11
|
+
@isCollection = true
|
12
|
+
@pinkmanType = 'collection'
|
13
|
+
|
14
|
+
@collection = []
|
15
|
+
@pinkey = Pinkman.all.length
|
16
|
+
|
17
|
+
Pinkman.collections.push(this)
|
18
|
+
Pinkman.all.push(this)
|
19
|
+
|
20
|
+
# Desc: return an array of all members
|
21
|
+
# this behaviour makes life easier... trust me
|
22
|
+
attributes: ->
|
23
|
+
return @collection
|
24
|
+
|
25
|
+
# Desc: collection size
|
26
|
+
count: (criteria='') ->
|
27
|
+
if criteria? and typeof criteria == 'function'
|
28
|
+
count = 0
|
29
|
+
(count++ if criteria(object)) for object in @collection
|
30
|
+
count
|
31
|
+
else
|
32
|
+
@collection.length
|
33
|
+
|
34
|
+
# Desc: Alias for count
|
35
|
+
size: (criteria='') ->
|
36
|
+
@count(criteria)
|
37
|
+
|
38
|
+
# Desc: Alias for count
|
39
|
+
length: (criteria='') ->
|
40
|
+
@count(criteria)
|
41
|
+
|
42
|
+
# rails/ruby equivalent: each
|
43
|
+
# Desc: receive a function and apply it to all members
|
44
|
+
# tip: you can chain functions. Example: collection.each(transform).first()
|
45
|
+
each: (transformation='') ->
|
46
|
+
if transformation? and typeof transformation=='function'
|
47
|
+
transformation(o) for o in @collection
|
48
|
+
return this
|
49
|
+
|
50
|
+
# rails/ruby equivalent: where/select
|
51
|
+
# Desc: returns a new collection of all members that satisfies a criteria (criteria(obj) returns true)
|
52
|
+
# new version: accepts a object to match against the object attributes
|
53
|
+
select: (criteria,callback='') ->
|
54
|
+
selection = new @constructor
|
55
|
+
# function version
|
56
|
+
if typeof criteria == 'function'
|
57
|
+
@each (object) ->
|
58
|
+
selection.push(object) if criteria(object)
|
59
|
+
|
60
|
+
# object version
|
61
|
+
else if typeof criteria == 'object'
|
62
|
+
@each (object) ->
|
63
|
+
value = true
|
64
|
+
(value = false if object[k] != v) for k,v of criteria
|
65
|
+
selection.push(object) if value
|
66
|
+
|
67
|
+
callback(selection) if typeof callback == 'function'
|
68
|
+
return(selection)
|
69
|
+
|
70
|
+
# Desc: insert in last position
|
71
|
+
push: (arg) ->
|
72
|
+
if Pinkman.isArray(arg)
|
73
|
+
@pushIndividually(item) for item in arg
|
74
|
+
return(@include(arg))
|
75
|
+
else
|
76
|
+
@pushIndividually(arg)
|
77
|
+
|
78
|
+
# Desc: insert in first position
|
79
|
+
unshift: (object) ->
|
80
|
+
if Pinkman.isArray(object)
|
81
|
+
@unshiftIndividually(item) for item in object
|
82
|
+
return(@include(object))
|
83
|
+
else
|
84
|
+
@unshiftIndividually(object)
|
85
|
+
|
86
|
+
pushIndividually: (object) ->
|
87
|
+
if object? and typeof object == 'object' and not @include(object)
|
88
|
+
@beforeInsertionPrep object, (object) =>
|
89
|
+
@collection.push(object)
|
90
|
+
object.collections.push(this) if object.isObject and object.collections?
|
91
|
+
return true
|
92
|
+
else
|
93
|
+
return false
|
94
|
+
|
95
|
+
directPush: (object) ->
|
96
|
+
@collection.push(object) unless @include(object)
|
97
|
+
|
98
|
+
forcePush: (object) ->
|
99
|
+
@collection.push(object)
|
100
|
+
|
101
|
+
unshiftIndividually: (object) ->
|
102
|
+
if object? and typeof object == 'object' and not @include(object)
|
103
|
+
@beforeInsertionPrep object, (object) =>
|
104
|
+
@collection.unshift(object)
|
105
|
+
object.collections.push(this) if object.isObject and object.collections?
|
106
|
+
return true
|
107
|
+
else
|
108
|
+
return false
|
109
|
+
|
110
|
+
beforeInsertionPrep: (object,callback='') ->
|
111
|
+
unless object.isPink
|
112
|
+
pinkObject = @new()
|
113
|
+
pinkObject.assign(object)
|
114
|
+
object = pinkObject
|
115
|
+
callback(object) if typeof callback == 'function'
|
116
|
+
return(object)
|
117
|
+
|
118
|
+
# Desc: removes from last position and returns it
|
119
|
+
pop: ->
|
120
|
+
@remove(@last())
|
121
|
+
|
122
|
+
# Desc: removes from first position and returns it
|
123
|
+
shift: ->
|
124
|
+
@remove(@first())
|
125
|
+
|
126
|
+
# Desc: remove a object from the collection
|
127
|
+
remove: (object) ->
|
128
|
+
if object?
|
129
|
+
i = @collection.indexOf object
|
130
|
+
@collection.splice(i,1)
|
131
|
+
return object
|
132
|
+
|
133
|
+
# Desc: remove the first object that matches
|
134
|
+
removeBy: (attribute,value) ->
|
135
|
+
if attribute? and value?
|
136
|
+
@remove(@getBy(attribute,value))
|
137
|
+
|
138
|
+
# Desc: remove everyone from this collection
|
139
|
+
removeAll: ->
|
140
|
+
if @any()
|
141
|
+
@remove(@first())
|
142
|
+
@removeAll()
|
143
|
+
else
|
144
|
+
return(true)
|
145
|
+
|
146
|
+
# Desc: return true if object is in this collection and false if anything else.
|
147
|
+
# Also accepts an array as argument. Return true if
|
148
|
+
include: (args) ->
|
149
|
+
if args? and Pinkman.isArray(args)
|
150
|
+
value = true
|
151
|
+
for item in args
|
152
|
+
value=false unless @include(item)
|
153
|
+
return(value)
|
154
|
+
else if args? and typeof args == 'object'
|
155
|
+
if args.id?
|
156
|
+
@any (o) ->
|
157
|
+
args.id == o.id
|
158
|
+
else
|
159
|
+
@collection.indexOf(args) isnt -1
|
160
|
+
else
|
161
|
+
false
|
162
|
+
|
163
|
+
first: (n=1) ->
|
164
|
+
if n==1
|
165
|
+
return @collection[0]
|
166
|
+
else
|
167
|
+
return @collection[0..(n-1)]
|
168
|
+
|
169
|
+
last: (n=1) ->
|
170
|
+
if n==1
|
171
|
+
return @collection[@collection.length - 1]
|
172
|
+
else
|
173
|
+
return @collection[(@collection.length - n - 1)..]
|
174
|
+
|
175
|
+
# Desc: return trues if has at least one member. If a criteria is specificied, returns true if at least one member satisfies it.
|
176
|
+
any: (criteria='') ->
|
177
|
+
if criteria? and typeof criteria == 'function'
|
178
|
+
@select(criteria).count() > 0
|
179
|
+
else
|
180
|
+
@count() > 0
|
181
|
+
|
182
|
+
# Desc: return the first object that matches
|
183
|
+
getBy: (attribute, value) ->
|
184
|
+
if attribute? and value?
|
185
|
+
object = new Object
|
186
|
+
object[attribute] = value
|
187
|
+
return(@getByAttributes(object))
|
188
|
+
|
189
|
+
# Desc: return the first that matches
|
190
|
+
getByAttributes: (object) ->
|
191
|
+
if object? and typeof object == 'object' and @any()
|
192
|
+
for member in @collection
|
193
|
+
match = true
|
194
|
+
for key,value of object
|
195
|
+
match = false if member[key]!=value
|
196
|
+
return(member) if match
|
197
|
+
else
|
198
|
+
return null
|
199
|
+
|
200
|
+
# Desc: get by pinkey
|
201
|
+
getByPinkey: (pinkey) ->
|
202
|
+
@getBy('pinkey',pinkey)
|
203
|
+
|
204
|
+
# Desc: sinthetize getByPinkey, getBy, and getByAttributes in one method
|
205
|
+
get: (args...) ->
|
206
|
+
if args.length > 0
|
207
|
+
if Pinkman.isNumber(args[0])
|
208
|
+
@getByPinkey(args[0])
|
209
|
+
else if args.length == 2
|
210
|
+
@getBy(args...)
|
211
|
+
else if typeof args[0] == 'object'
|
212
|
+
@getByAttributes(args[0])
|
213
|
+
|
214
|
+
# Desc: find by id
|
215
|
+
find: (id) ->
|
216
|
+
if id?
|
217
|
+
object = @getBy('id',id)
|
218
|
+
return(object)
|
219
|
+
|
220
|
+
# Desc: return the next (after) object
|
221
|
+
next: (object) ->
|
222
|
+
i = @collection.indexOf object
|
223
|
+
@collection[i+1]
|
224
|
+
|
225
|
+
# Desc: return the previous (before) object
|
226
|
+
prev: (object) ->
|
227
|
+
i = @collection.indexOf object
|
228
|
+
@collection[i-1]
|
229
|
+
|
230
|
+
# Desc: log every member pinkey in the console
|
231
|
+
logPinkeys: () ->
|
232
|
+
@each (object) ->
|
233
|
+
console.log object.pinkey
|
234
|
+
|
235
|
+
# Desc: removes duplicated records (same id or same pinkey)
|
236
|
+
uniq: (callback='') ->
|
237
|
+
duplicated = []
|
238
|
+
@each (object) =>
|
239
|
+
@each (matching) ->
|
240
|
+
duplicated.push(matching) if object.pinkey? and (object.pinkey == matching.pinkey) and (object isnt matching)
|
241
|
+
duplicated.push(matching) if object.id? and (object.id == matching.id) and (object isnt matching)
|
242
|
+
for d in duplicated
|
243
|
+
@remove(d)
|
244
|
+
return(this)
|
245
|
+
|
246
|
+
# Desc: fetch from array ... T_T
|
247
|
+
fetchFromArray: (array) ->
|
248
|
+
for a in array
|
249
|
+
object = @beforeInsertionPrep(a)
|
250
|
+
# if object already is in this collection, overwrite its values
|
251
|
+
if object? and @find(object.id)?
|
252
|
+
@find(object.id).assign(object.attributes())
|
253
|
+
# else, inserts it
|
254
|
+
else
|
255
|
+
@push(object)
|
256
|
+
return(this)
|
257
|
+
|
258
|
+
# Desc: merges this collection with another
|
259
|
+
merge: (collection) ->
|
260
|
+
if Pinkman.isArray(collection)
|
261
|
+
@fetchFromArray(collection)
|
262
|
+
else if typeof collection == 'object' and collection.isPink and collection.isCollection
|
263
|
+
@fetchFromArray(collection.collection)
|
264
|
+
|
265
|
+
# Desc: returns a new object associated with this collection
|
266
|
+
new: (attributes) ->
|
267
|
+
object = new (@config.memberClass)
|
268
|
+
object.initialize(attributes)
|
269
|
+
object
|
270
|
+
|
271
|
+
# Desc: reload every object in this collection
|
272
|
+
reload: (callback='') ->
|
273
|
+
if @any()
|
274
|
+
@each (object) =>
|
275
|
+
if object.id?
|
276
|
+
object.reload (object) =>
|
277
|
+
if object.pinkey == @last().pinkey and callback == 'function'
|
278
|
+
callback(this)
|
279
|
+
|
280
|
+
# Desc: create a index for objects
|
281
|
+
makeIndex: ->
|
282
|
+
if @any()
|
283
|
+
i = 1
|
284
|
+
for object in @collection
|
285
|
+
object.set("index",i)
|
286
|
+
i++
|
287
|
+
return true
|
288
|
+
else
|
289
|
+
return false
|
290
|
+
|
291
|
+
# Desc: exactly what it suggests
|
292
|
+
shuffle: () ->
|
293
|
+
if @any?
|
294
|
+
currentIndex = @collection.length
|
295
|
+
|
296
|
+
# // While there remain elements to shuffle...
|
297
|
+
while (0 != currentIndex)
|
298
|
+
# // Pick a remaining element...
|
299
|
+
randomIndex = Math.floor(Math.random() * currentIndex)
|
300
|
+
currentIndex = currentIndex - 1
|
301
|
+
|
302
|
+
# // And swap it with the current element.
|
303
|
+
temporaryValue = @collection[currentIndex]
|
304
|
+
@collection[currentIndex] = @collection[randomIndex]
|
305
|
+
@collection[randomIndex] = temporaryValue
|
306
|
+
|
307
|
+
# Desc: filters collection whose attribute matches the query
|
308
|
+
filter: (attribute,query,callback) ->
|
309
|
+
if attribute? and query? and query!="" and (typeof(attribute) == "string")
|
310
|
+
if @any()
|
311
|
+
filter = new @constructor
|
312
|
+
for obj in @collection
|
313
|
+
if obj[attribute] == query
|
314
|
+
filter.push obj
|
315
|
+
else if obj[attribute]? and (typeof obj[attribute] == "string") and (obj[attribute]!="") and (typeof query == "string") and (query!="") and (obj[field].toLowerCase().indexOf(query.toLowerCase()) > -1)
|
316
|
+
filter.push obj
|
317
|
+
callback(filter) if callback? and typeof callback == 'function'
|
318
|
+
return filter
|
319
|
+
else
|
320
|
+
return false
|
321
|
+
|
322
|
+
|
323
|
+
# --- Ajax related --- #
|
324
|
+
|
325
|
+
# Desc: Fetch records from API_URL
|
326
|
+
# request: get /api/API_URL/
|
327
|
+
# in rails: api::controller#index
|
328
|
+
fetch: (callback = '') ->
|
329
|
+
@fetchFromUrl url: @api(), callback: callback
|
330
|
+
|
331
|
+
# Desc: Fetch records from another action of this model api
|
332
|
+
# request: get /api/API_URL/:action/#id
|
333
|
+
# in rails: api::controller#action
|
334
|
+
|
335
|
+
# Example: fetching all orders of a user
|
336
|
+
# coffee: orders.fetchFrom 'user', user.id
|
337
|
+
# api::controler#order: render json: User.find(params[:id]).orders.to_json
|
338
|
+
fetchFrom: (action,id,callback = '') ->
|
339
|
+
if action? and id?
|
340
|
+
@fetchFromUrl(@api() + "#{action}/#{id}", callback)
|
341
|
+
else
|
342
|
+
return false
|
343
|
+
|
344
|
+
|
345
|
+
# Desc: Fetch records from URL
|
346
|
+
# request: get /api/API_URL/
|
347
|
+
fetchFromUrl: (options) ->
|
348
|
+
if options? and typeof options == 'object' and options.url?
|
349
|
+
limit = if options.limit? then options.limit else 1000
|
350
|
+
offset = if options.offset? then options.offset else 0
|
351
|
+
@fetchingFrom = options.url
|
352
|
+
Pinkman.ajax.get
|
353
|
+
url: options.url + "?limit=#{limit}&offset=#{offset}"
|
354
|
+
complete: (response) =>
|
355
|
+
if response.errors? or response.error?
|
356
|
+
[@errors, @error] = [response.errors, response.error]
|
357
|
+
if response.errors? then (throw new Error('Oh no... I could not fetch your records, bitch. (jk... about the "bitch" part)')) else (throw new Error(response.error))
|
358
|
+
return false
|
359
|
+
else
|
360
|
+
@fetchFromArray(response).emptyResponse = response.length == 0
|
361
|
+
options.callback(this) if options.callback? and typeof options.callback == 'function'
|
362
|
+
return(this)
|
363
|
+
|
364
|
+
# Desc: Fetch next records from last fetched URL or main API_URl
|
365
|
+
# request: get /api/API_URL/?offset="COLLECTION_SIZE"&limit=n
|
366
|
+
# in rails: api::controller#index
|
367
|
+
fetchMore: (n=10,callback='') ->
|
368
|
+
if @fetchingFrom?
|
369
|
+
@fetchFromUrl url: @fetchingFrom, limit: n, offset: @count(), callback: callback
|
370
|
+
else
|
371
|
+
@fetchFromUrl url: @api(), limit: n, offset: @count(), callback: callback
|
372
|
+
|
373
|
+
# Desc: Fetch next n records from a action
|
374
|
+
# request: get /api/API_URL/:action/?offset="COLLECTION_SIZE"&limit=n
|
375
|
+
# in rails: api::controller#action
|
376
|
+
fetchMoreFrom: (n,action,id,callback='') ->
|
377
|
+
@fetchFromUrl {url: @api() + "#{action}/#{id}", limit: n, offset: @count(), callback: callback}
|
378
|
+
|
379
|
+
# Desc: Connect to api to search in this model a query
|
380
|
+
# request: get /api/API_URL/search?query=YOUR_QUERY
|
381
|
+
# in rails: api::controller#search
|
382
|
+
# assume models to have a Model.search("YOUR_QUERY") method.
|
383
|
+
search: (query,callback='') ->
|
384
|
+
@removeAll()
|
385
|
+
@fetchFromUrl { url: @api() + "search?query=#{query}", callback: callback }
|
386
|
+
|
387
|
+
window.Pinkman.collection = window.PinkmanCollection
|