cowtech-rails 1.9.7.6 → 2.0.0.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/app/helpers/cowtech/ruby_on_rails/helpers/{crud_helper.rb → ar_crud_helper.rb} +1 -1
- data/app/helpers/cowtech/ruby_on_rails/helpers/browser_helper.rb +26 -23
- data/app/helpers/cowtech/ruby_on_rails/helpers/mongoid_crud_helper.rb +226 -0
- data/app/models/cowtech/ruby_on_rails/models/ar/model_base.rb +97 -0
- data/app/models/cowtech/ruby_on_rails/models/mongoid/cowtech.rb +108 -0
- data/app/models/cowtech/ruby_on_rails/models/mongoid/logging.rb +34 -0
- data/app/models/cowtech/ruby_on_rails/models/mongoid/sequence.rb +59 -0
- data/lib/cowtech/version.rb +4 -4
- metadata +10 -6
- data/app/models/cowtech/ruby_on_rails/models/model_base.rb +0 -95
@@ -9,33 +9,36 @@ module Cowtech
|
|
9
9
|
module Helpers
|
10
10
|
module BrowserHelper
|
11
11
|
def browser_detect
|
12
|
-
rv = {:engine => :unknown, :version => "0", :platform => :unknown, :agent => request.user_agent || request.env['HTTP_USER_AGENT'].downcase || ""}
|
13
|
-
|
12
|
+
rv = {:engine => :unknown, :version => "0", :platform => :unknown, :agent => request.user_agent || request.env['HTTP_USER_AGENT'].try(:downcase) || ""}
|
13
|
+
|
14
|
+
if rv[:agent].present? then
|
15
|
+
agent = rv[:agent].downcase
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
17
|
+
# Identify engine
|
18
|
+
if agent =~ /opera/ then
|
19
|
+
rv[:engine] = :opera
|
20
|
+
elsif agent =~ /webkit/ then
|
21
|
+
rv[:engine] = (agent =~ /chrome|chromium/ ? :chrome : :safari)
|
22
|
+
elsif agent =~ /msie/ || agent =~ /webtv/ then
|
23
|
+
rv[:engine] = :msie
|
24
|
+
elsif agent =~ /mozilla/ && agent !~ /compatible/ then
|
25
|
+
rv[:engine] = :mozilla
|
26
|
+
end
|
25
27
|
|
26
|
-
|
27
|
-
|
28
|
-
|
28
|
+
# Identify version
|
29
|
+
rv[:version] = $1 if agent =~ /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/
|
30
|
+
rv[:version_number] = rv[:version].to_f
|
29
31
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
32
|
+
# Identify platform
|
33
|
+
if agent =~ /linux/
|
34
|
+
rv[:platform] = :linux
|
35
|
+
elsif agent =~ /macintosh|mac os x/ then
|
36
|
+
rv[:platform] = :mac
|
37
|
+
elsif agent =~ /windows|win32|win64/ then
|
38
|
+
rv[:platform] = :windows
|
39
|
+
end
|
37
40
|
end
|
38
|
-
|
41
|
+
|
39
42
|
@browser = rv
|
40
43
|
end
|
41
44
|
|
@@ -0,0 +1,226 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# This file is part of the cowtech-rails gem. Copyright (C) 2011 and above Shogun <shogun_panda@me.com>.
|
4
|
+
# Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
|
5
|
+
#
|
6
|
+
|
7
|
+
module Cowtech
|
8
|
+
module RubyOnRails
|
9
|
+
module Helpers
|
10
|
+
module MongoidCrudHelper
|
11
|
+
attr_accessor :mongo_class
|
12
|
+
attr_accessor :records
|
13
|
+
attr_accessor :mongo_sort_order
|
14
|
+
attr_accessor :mongo_bounds
|
15
|
+
attr_accessor :mongo_query
|
16
|
+
attr_accessor :mongo_records
|
17
|
+
attr_accessor :mongo_pager
|
18
|
+
|
19
|
+
def mongo_setup(args = {})
|
20
|
+
@mongo_class = args[:class] if args[:class]
|
21
|
+
@mongo_class = @mongo_class.constantize if @mongo_class.is_a?(String)
|
22
|
+
@mongo_records = []
|
23
|
+
@mongo_sort_order = [[:_id, :asc]]
|
24
|
+
@mongo_bounds = {:total => 0, :first => 1, :last => 0, :pages => 1, :page => 1, :per_page => 1}
|
25
|
+
@mongo_query = self.mongo_reset_query(:also_deleted => args[:also_deleted]) if @mongo_class
|
26
|
+
end
|
27
|
+
|
28
|
+
def mongo_has_data?(args = {})
|
29
|
+
@mongo_bounds[:total] > 0
|
30
|
+
end
|
31
|
+
|
32
|
+
def mongo_calculate_bounds(args = {})
|
33
|
+
if @mongo_records.present? then
|
34
|
+
@mongo_bounds[:total] = @mongo_records.count
|
35
|
+
@mongo_bounds[:per_page] = (args[:per_page].is_integer? ? args[:per_page] : @mongo_records.first.class.per_page).to_integer
|
36
|
+
@mongo_bounds[:pages] = (@mongo_bounds[:total].to_f / @mongo_bounds[:per_page]).ceil
|
37
|
+
|
38
|
+
if @mongo_bounds[:per_page] > 0 then
|
39
|
+
@mongo_bounds[:page] = self.mongo_get_page_param(:upperbound => @mongo_bounds[:pages])
|
40
|
+
base = ((@mongo_bounds[:page] - 1) * @mongo_bounds[:per_page])
|
41
|
+
@mongo_bounds[:first] = base + 1
|
42
|
+
@mongo_bounds[:last] = [base + @mongo_bounds[:per_page], @mongo_bounds[:total]].min
|
43
|
+
else
|
44
|
+
@mongo_bounds.merge!(:pages => 1, :page => 1, :first => 1, :last => @mongo_bounds[:total], :per_page => @mongo_bounds[:total])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
@mongo_bounds
|
49
|
+
end
|
50
|
+
|
51
|
+
def mongo_fetch_data(args = {})
|
52
|
+
@mongo_records = @mongo_query.order_by(@mongo_sort_order)
|
53
|
+
self.mongo_calculate_bounds(args.reverse_merge(:per_page => (args[:per_page] || params[args[:parameter] || :count])))
|
54
|
+
@records = @mongo_records.skip(@mongo_bounds[:first] - 1).limit(@mongo_bounds[:per_page])
|
55
|
+
@mongo_pager = WillPaginate::Collection.new(@mongo_bounds[:page], @mongo_bounds[:per_page], @mongo_bounds[:total])
|
56
|
+
end
|
57
|
+
|
58
|
+
def mongo_reset_query(args = {})
|
59
|
+
klass = args[:class] || @mongo_class
|
60
|
+
klass ? (args[:also_deleted] ? klass.where : klass.not_deleted) : nil
|
61
|
+
end
|
62
|
+
|
63
|
+
def mongo_dump_query(args = {})
|
64
|
+
raise Exception.new("QUERY:\n#{@mongo_query.inspect}")
|
65
|
+
end
|
66
|
+
|
67
|
+
def mongo_add_query_conditions(args = {})
|
68
|
+
(args[:conditions] || []).ensure_array.each do |condition|
|
69
|
+
@mongo_query = @mongo_query.where(condition) if condition.is_a?(Hash)
|
70
|
+
end
|
71
|
+
|
72
|
+
@mongo_query = yield(@mongo_query) if block_given?
|
73
|
+
@mongo_query
|
74
|
+
end
|
75
|
+
|
76
|
+
def mongo_parse_search(search)
|
77
|
+
if search.present? then
|
78
|
+
# Operate on parenthesis. If unbalanced, no substitution is done
|
79
|
+
if search.gsub(/[^(]/mi, "").strip.length == search.gsub(/[^)]/mi, "").strip.length then
|
80
|
+
# Split token
|
81
|
+
search = search.split(/(\s(AND|OR)\s)|([\(\)])/).select{|t| !t.empty? && t !~ /^(AND|OR)$/}
|
82
|
+
|
83
|
+
# Replace tokens
|
84
|
+
search = search.collect { |token|
|
85
|
+
case token
|
86
|
+
when /[\(\)]/ then # No replace
|
87
|
+
token
|
88
|
+
when /\sAND\s/ then
|
89
|
+
"(.+)"
|
90
|
+
when /\sOR\s/ then
|
91
|
+
"|"
|
92
|
+
when /^\^(.+)/ then
|
93
|
+
"(^(#{Regexp.escape($1)}))"
|
94
|
+
when /(.+)\$$/ then
|
95
|
+
"((#{Regexp.escape($1)})$)"
|
96
|
+
else
|
97
|
+
"(" + Regexp.escape(token) + ")"
|
98
|
+
end
|
99
|
+
}.join("")
|
100
|
+
else
|
101
|
+
search = Regexp.quote(search)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
search
|
106
|
+
end
|
107
|
+
|
108
|
+
def mongo_handle_search(args = {})
|
109
|
+
parameter = args[:parameter] || :search
|
110
|
+
|
111
|
+
# Get the query
|
112
|
+
search_query = params[parameter]
|
113
|
+
if search_query.present? then
|
114
|
+
expr = self.mongo_parse_search(search_query)
|
115
|
+
|
116
|
+
# Build the query
|
117
|
+
(args[:fields] || []).each do |field|
|
118
|
+
@mongo_query = @mongo_query.any_of(field.to_sym => Regexp.new(expr, Regexp::EXTENDED | Regexp::MULTILINE | Regexp::IGNORECASE))
|
119
|
+
end
|
120
|
+
|
121
|
+
# Now add external fields
|
122
|
+
# TODO: Can we enhance this?
|
123
|
+
(args[:external] || []).each do |external|
|
124
|
+
external_query = external[:class].not_deleted
|
125
|
+
(external[:fields] || []).each do |field|
|
126
|
+
external_query = external_query.any_of(field.to_sym => Regexp.new(expr, Regexp::EXTENDED | Regexp::MULTILINE | Regexp::IGNORECASE))
|
127
|
+
end
|
128
|
+
|
129
|
+
ids = external_query.only(:id).all.collect {|r| r.id }
|
130
|
+
@mongo_query = @mongo_query.any_of(:cliente_id.in => ids) if ids.count > 0
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
@mongo_query
|
135
|
+
end
|
136
|
+
|
137
|
+
def mongo_handle_sorting(args = {})
|
138
|
+
order = args[:order] || [:current, [:updated_at, :desc]]
|
139
|
+
|
140
|
+
# Get current request sort order and then replace it into the sort fields
|
141
|
+
current = self.mongo_get_sort_param(:default => args[:default])
|
142
|
+
current_index = order.index(:current)
|
143
|
+
order[current_index] = current if current_index
|
144
|
+
|
145
|
+
# Assign data
|
146
|
+
@mongo_sort_order = order
|
147
|
+
end
|
148
|
+
|
149
|
+
def mongo_form_header(args = {})
|
150
|
+
args[:record].try(:new_record?) ? "Create" : "Edit"
|
151
|
+
end
|
152
|
+
|
153
|
+
def mongo_form_submit_label(args = {})
|
154
|
+
args[:record].try(:new_record?) ? "Create" : "Edit"
|
155
|
+
end
|
156
|
+
|
157
|
+
def mongo_yesno
|
158
|
+
[OpenStruct.new(:value => true, :label => "Sì"), OpenStruct.new(:value => false, :label => "No")]
|
159
|
+
end
|
160
|
+
|
161
|
+
def mongo_get_page_param(args = {})
|
162
|
+
page = [params[args[:parameter] || :page].to_integer, 1].max
|
163
|
+
page = [page, args[:upperbound]].min if args[:upperbound].to_integer > 0
|
164
|
+
page
|
165
|
+
end
|
166
|
+
|
167
|
+
def mongo_get_sort_param(args = {})
|
168
|
+
if /^(?<what>[a-z0-9_]+)-(?<how>asc|desc)$/i.match(params[args[:param] || :sort_by]) && (args[:valids] || []).include?($~["what"]) then
|
169
|
+
[$~["what"].to_sym, $~["how"].downcase.to_sym]
|
170
|
+
else
|
171
|
+
args[:default] || [:created_at, :desc]
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def mongo_delete(args = {})
|
176
|
+
record = (args[:class] || @mongo_class).safe_find(args[:id])
|
177
|
+
|
178
|
+
if record then
|
179
|
+
args[:only_check] ? record.deletable? : record.delete(args[:definitive])
|
180
|
+
else
|
181
|
+
false
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def mongo_exists?(args)
|
186
|
+
args[:class].not_deleted.where(args[:conditions]).count > 0
|
187
|
+
end
|
188
|
+
|
189
|
+
def mongo_is_available?(args = {})
|
190
|
+
rv = self.setup_json_response(:validator)
|
191
|
+
rv["success"] = true
|
192
|
+
rv["valid"] = (self.mongo_exists?(args) == (args[:must_exists] || false))
|
193
|
+
args[:internal] ? rv : self.custom_respond_with(rv.to_json)
|
194
|
+
end
|
195
|
+
|
196
|
+
def mongo_update_params_black_list(args = {})
|
197
|
+
["controller", "action", "id", "subdomain"] + (args[:additional] || [])
|
198
|
+
end
|
199
|
+
|
200
|
+
def mongo_update_params(args = {})
|
201
|
+
blacklist = self.mongo_update_params_black_list(args)
|
202
|
+
session["params-#{self.location_name}"] = (params.delete_if {|k,v| blacklist.include?(k) || params[k].is_a?(Tempfile) || params[k].blank?})
|
203
|
+
end
|
204
|
+
|
205
|
+
def mongo_end_write_action(args = {})
|
206
|
+
redirect_to self.mongo_end_write_action_url(args)
|
207
|
+
end
|
208
|
+
|
209
|
+
def mongo_end_write_action_url(args = {})
|
210
|
+
rp = {}
|
211
|
+
|
212
|
+
if !args[:absolute] then
|
213
|
+
rp = session["params-#{self.location_name(:index)}"] || {}
|
214
|
+
rp[:action] = :index
|
215
|
+
end
|
216
|
+
|
217
|
+
if args[:additional].is_a?(Hash) then
|
218
|
+
args[:additional].each { |k, v| rp[k] = v }
|
219
|
+
end
|
220
|
+
|
221
|
+
url_for(rp)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# This file is part of the cowtech-rails gem. Copyright (C) 2011 and above Shogun <shogun_panda@me.com>.
|
4
|
+
# Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
|
5
|
+
#
|
6
|
+
|
7
|
+
module Cowtech
|
8
|
+
module RubyOnRails
|
9
|
+
module Models
|
10
|
+
module Ar
|
11
|
+
if defined?(ActiveRecord) then
|
12
|
+
class ModelBase < ::ActiveRecord::Base
|
13
|
+
def self.deleted_column
|
14
|
+
"deleted_at"
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.status_column
|
18
|
+
"status_id"
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.deleted_status_id
|
22
|
+
0
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.[](what, only_id = false)
|
26
|
+
self.__finalize(self.__safe_index_find(what), only_id)
|
27
|
+
end
|
28
|
+
|
29
|
+
def safe_id
|
30
|
+
if self.id then self.id else 0 end
|
31
|
+
end
|
32
|
+
|
33
|
+
def editable?(user = nil)
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def deletable?(user = nil)
|
38
|
+
true
|
39
|
+
end
|
40
|
+
|
41
|
+
def delete(definitive = false)
|
42
|
+
if !definitive then
|
43
|
+
if self.deletable? then
|
44
|
+
if self.has_attribute?(self.class.deleted_column) then
|
45
|
+
self.update_attribute(self.class.deleted_column, DateTime.now)
|
46
|
+
true
|
47
|
+
elsif self.has_attribute?(self.class.status_column) then
|
48
|
+
self.update_attribute(self.class.status_column, self.deleted_status)
|
49
|
+
true
|
50
|
+
else
|
51
|
+
super()
|
52
|
+
end
|
53
|
+
else
|
54
|
+
false
|
55
|
+
end
|
56
|
+
else
|
57
|
+
super()
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def is?(other)
|
62
|
+
other ? (self.id == self.class.__safe_index_find(other).id) : false
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
def self.__index_find(what)
|
67
|
+
self.find(what)
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.__finalize(record, only_id = false)
|
71
|
+
if record then
|
72
|
+
only_id ? record.id : record
|
73
|
+
else
|
74
|
+
nil
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.__safe_index_find(what)
|
79
|
+
record = nil
|
80
|
+
|
81
|
+
begin
|
82
|
+
record = self.__index_find(what)
|
83
|
+
rescue ActiveRecord::RecordNotFound
|
84
|
+
record = nil
|
85
|
+
end
|
86
|
+
|
87
|
+
record
|
88
|
+
end
|
89
|
+
end
|
90
|
+
else
|
91
|
+
class ModelBase
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# This file is part of the Gestione Exodus Comics application. Copyright (C) 2010 and above Paolo Insogna <p.insogna@me.com>.
|
4
|
+
# Licensed as stated in the COPYRIGHT file, which can be found in the root of the application.
|
5
|
+
#
|
6
|
+
|
7
|
+
module Cowtech
|
8
|
+
module RubyOnRails
|
9
|
+
module Models
|
10
|
+
module Mongoid
|
11
|
+
module Cowtech
|
12
|
+
extend ActiveSupport::Concern
|
13
|
+
|
14
|
+
# Uncomment for numeric ID
|
15
|
+
# included do
|
16
|
+
# include Mongoid::Sequence
|
17
|
+
# identity :type => Integer
|
18
|
+
# sequence :_id
|
19
|
+
# end
|
20
|
+
|
21
|
+
module ClassMethods
|
22
|
+
def [](what, only_id = false)
|
23
|
+
self.__finalize(self.__safe_index_find(what), only_id)
|
24
|
+
end
|
25
|
+
|
26
|
+
def find_or_create(oid, attributes = nil)
|
27
|
+
self.safe_find(oid) || self.new(attributes)
|
28
|
+
end
|
29
|
+
|
30
|
+
def safe_find(oid)
|
31
|
+
rv = oid.blank? ? nil : self.find(BSON::ObjectId(oid))
|
32
|
+
rescue ::Mongoid::Errors::DocumentNotFound, BSON::InvalidObjectId
|
33
|
+
nil
|
34
|
+
end
|
35
|
+
|
36
|
+
def random
|
37
|
+
c = self.count
|
38
|
+
c != 0 ? self.skip(rand(c)).first : nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def per_page
|
42
|
+
25
|
43
|
+
end
|
44
|
+
|
45
|
+
# Overrides for paranoia module to allow find associations on deleted documents
|
46
|
+
def criteria(*args)
|
47
|
+
rv = super
|
48
|
+
rv.selector = {}
|
49
|
+
rv
|
50
|
+
end
|
51
|
+
|
52
|
+
def not_deleted
|
53
|
+
where(:deleted_at.exists => false)
|
54
|
+
end
|
55
|
+
|
56
|
+
def __index_find(oid)
|
57
|
+
oid.blank? ? nil : self.find(BSON::ObjectId(oid))
|
58
|
+
rescue ::Mongoid::Errors::DocumentNotFound, BSON::InvalidObjectId
|
59
|
+
nil
|
60
|
+
end
|
61
|
+
|
62
|
+
def __finalize(record, only_id = false)
|
63
|
+
record ? (only_id ? record.id : record) : nil
|
64
|
+
end
|
65
|
+
|
66
|
+
def __safe_index_find(what)
|
67
|
+
self.__index_find(what)
|
68
|
+
rescue ::Mongoid::Errors::DocumentNotFound, BSON::InvalidObjectId
|
69
|
+
nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
module InstanceMethods
|
74
|
+
# Decommentare per ID di tipo numerico
|
75
|
+
# def safe_id
|
76
|
+
# self.id ? self.id : 0
|
77
|
+
# end
|
78
|
+
|
79
|
+
def editable?(user = nil)
|
80
|
+
true
|
81
|
+
end
|
82
|
+
|
83
|
+
def deletable?(user = nil)
|
84
|
+
true
|
85
|
+
end
|
86
|
+
|
87
|
+
def delete(definitive = false)
|
88
|
+
if definitive != true then
|
89
|
+
if self.deletable? then
|
90
|
+
super()
|
91
|
+
true
|
92
|
+
else
|
93
|
+
false
|
94
|
+
end
|
95
|
+
else
|
96
|
+
self.delete!
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def is?(other)
|
101
|
+
other ? (self.id == self.class.__safe_index_find(other).id) : false
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# This file is part of the Gestione Exodus Comics application. Copyright (C) 2010 and above Paolo Insogna <p.insogna@me.com>.
|
4
|
+
# Licensed as stated in the COPYRIGHT file, which can be found in the root of the application.
|
5
|
+
#
|
6
|
+
|
7
|
+
module Cowtech
|
8
|
+
module RubyOnRails
|
9
|
+
module Models
|
10
|
+
module Mongoid
|
11
|
+
module Logging
|
12
|
+
extend ActiveSupport::Concern
|
13
|
+
|
14
|
+
included do
|
15
|
+
set_callback(:create, :after) { |d| d.log_activity(:create) }
|
16
|
+
set_callback(:update, :after) { |d| d.log_activity(:update) }
|
17
|
+
end
|
18
|
+
|
19
|
+
module InstanceMethods
|
20
|
+
def delete(options = {})
|
21
|
+
log_activity(:delete)
|
22
|
+
super(options)
|
23
|
+
end
|
24
|
+
|
25
|
+
def restore
|
26
|
+
log_activity(:restore)
|
27
|
+
super
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# This file is part of the Gestione Exodus Comics application. Copyright (C) 2010 and above Paolo Insogna <p.insogna@me.com>.
|
4
|
+
# Licensed as stated in the COPYRIGHT file, which can be found in the root of the application.
|
5
|
+
#
|
6
|
+
|
7
|
+
module Cowtech
|
8
|
+
module RubyOnRails
|
9
|
+
module Models
|
10
|
+
module Mongoid
|
11
|
+
# Include this module to add automatic sequence feature (also works for _id field, so SQL-Like autoincrement primary key can easily be simulated)
|
12
|
+
# usage:
|
13
|
+
# class KlassName
|
14
|
+
# include Mongoid::Document
|
15
|
+
# include Mongoid::Sequence
|
16
|
+
# ...
|
17
|
+
# field :number, :type=>Integer
|
18
|
+
# sequence :number
|
19
|
+
# ...
|
20
|
+
module Sequence
|
21
|
+
extend ActiveSupport::Concern
|
22
|
+
|
23
|
+
module ClassMethods
|
24
|
+
def sequence(_field)
|
25
|
+
# REPLACE FIELD DEFAULT VALUE
|
26
|
+
_field = _field.to_s
|
27
|
+
field(_field, fields[_field].options.merge(:default => lambda{ set_from_sequence(_field)}))
|
28
|
+
end
|
29
|
+
|
30
|
+
def set_from_sequence(_field)
|
31
|
+
sequences = self.db.collection("__sequences")
|
32
|
+
counter_id = "#{self.class.name.underscore}_#{_field}"
|
33
|
+
|
34
|
+
# Increase the sequence value and also avoids conflicts
|
35
|
+
catch(:value) do
|
36
|
+
value = nil
|
37
|
+
begin
|
38
|
+
value = sequences.find_and_modify(
|
39
|
+
:query => {"_id" => counter_id},
|
40
|
+
:update=> {"$inc" => {"value" => 1}},
|
41
|
+
:new => true,
|
42
|
+
:upsert => true
|
43
|
+
).send("[]", "value")
|
44
|
+
end while self.first({:conditions => {_field => value}})
|
45
|
+
throw :value, value
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def reset_sequence(_field)
|
50
|
+
sequences = self.db.collection("__sequences")
|
51
|
+
counter_id = "#{self.class.name.underscore}_#{_field.to_s}"
|
52
|
+
sequences.find_and_modify(:query => {"_id" => counter_id}, :update=> {"$set" => {"value" => 0}}, :new => true, :upsert => true)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/cowtech/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cowtech-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-08-
|
12
|
+
date: 2011-08-31 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: cowtech-extensions
|
16
|
-
requirement: &
|
16
|
+
requirement: &70163803747200 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70163803747200
|
25
25
|
description: A general purpose Rails utility plugin.
|
26
26
|
email: shogun_panda@me.com
|
27
27
|
executables: []
|
@@ -30,12 +30,16 @@ extra_rdoc_files:
|
|
30
30
|
- README
|
31
31
|
files:
|
32
32
|
- app/helpers/cowtech/ruby_on_rails/helpers/application_helper.rb
|
33
|
+
- app/helpers/cowtech/ruby_on_rails/helpers/ar_crud_helper.rb
|
33
34
|
- app/helpers/cowtech/ruby_on_rails/helpers/browser_helper.rb
|
34
|
-
- app/helpers/cowtech/ruby_on_rails/helpers/crud_helper.rb
|
35
35
|
- app/helpers/cowtech/ruby_on_rails/helpers/format_helper.rb
|
36
|
+
- app/helpers/cowtech/ruby_on_rails/helpers/mongoid_crud_helper.rb
|
36
37
|
- app/helpers/cowtech/ruby_on_rails/helpers/validation_helper.rb
|
38
|
+
- app/models/cowtech/ruby_on_rails/models/ar/model_base.rb
|
37
39
|
- app/models/cowtech/ruby_on_rails/models/e_mail.rb
|
38
|
-
- app/models/cowtech/ruby_on_rails/models/
|
40
|
+
- app/models/cowtech/ruby_on_rails/models/mongoid/cowtech.rb
|
41
|
+
- app/models/cowtech/ruby_on_rails/models/mongoid/logging.rb
|
42
|
+
- app/models/cowtech/ruby_on_rails/models/mongoid/sequence.rb
|
39
43
|
- lib/cowtech.rb
|
40
44
|
- lib/cowtech/extensions.rb
|
41
45
|
- lib/cowtech/monkey_patches.rb
|
@@ -1,95 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
#
|
3
|
-
# This file is part of the cowtech-rails gem. Copyright (C) 2011 and above Shogun <shogun_panda@me.com>.
|
4
|
-
# Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
|
5
|
-
#
|
6
|
-
|
7
|
-
module Cowtech
|
8
|
-
module RubyOnRails
|
9
|
-
module Models
|
10
|
-
if defined?(ActiveRecord) then
|
11
|
-
class ModelBase < ::ActiveRecord::Base
|
12
|
-
def self.deleted_column
|
13
|
-
"deleted_at"
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.status_column
|
17
|
-
"status_id"
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.deleted_status_id
|
21
|
-
0
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.[](what, only_id = false)
|
25
|
-
self.__finalize(self.__safe_index_find(what), only_id)
|
26
|
-
end
|
27
|
-
|
28
|
-
def safe_id
|
29
|
-
if self.id then self.id else 0 end
|
30
|
-
end
|
31
|
-
|
32
|
-
def editable?(user = nil)
|
33
|
-
true
|
34
|
-
end
|
35
|
-
|
36
|
-
def deletable?(user = nil)
|
37
|
-
true
|
38
|
-
end
|
39
|
-
|
40
|
-
def delete(definitive = false)
|
41
|
-
if !definitive then
|
42
|
-
if self.deletable? then
|
43
|
-
if self.has_attribute?(self.class.deleted_column) then
|
44
|
-
self.update_attribute(self.class.deleted_column, DateTime.now)
|
45
|
-
true
|
46
|
-
elsif self.has_attribute?(self.class.status_column) then
|
47
|
-
self.update_attribute(self.class.status_column, self.deleted_status)
|
48
|
-
true
|
49
|
-
else
|
50
|
-
super()
|
51
|
-
end
|
52
|
-
else
|
53
|
-
false
|
54
|
-
end
|
55
|
-
else
|
56
|
-
super()
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def is?(other)
|
61
|
-
other ? (self.id == self.class.__safe_index_find(other).id) : false
|
62
|
-
end
|
63
|
-
|
64
|
-
private
|
65
|
-
def self.__index_find(what)
|
66
|
-
self.find(what)
|
67
|
-
end
|
68
|
-
|
69
|
-
def self.__finalize(record, only_id = false)
|
70
|
-
if record then
|
71
|
-
only_id ? record.id : record
|
72
|
-
else
|
73
|
-
nil
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def self.__safe_index_find(what)
|
78
|
-
record = nil
|
79
|
-
|
80
|
-
begin
|
81
|
-
record = self.__index_find(what)
|
82
|
-
rescue ActiveRecord::RecordNotFound
|
83
|
-
record = nil
|
84
|
-
end
|
85
|
-
|
86
|
-
record
|
87
|
-
end
|
88
|
-
end
|
89
|
-
else
|
90
|
-
class ModelBase
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|