mongo_mapper_ext 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +5 -5
- data/lib/mongo_db_ext/micelaneous.rb +12 -0
- data/lib/mongo_mapper_ext/gems.rb +17 -2
- data/lib/mongo_mapper_ext/hacks/active_model.rb +16 -0
- data/lib/mongo_mapper_ext/hacks/fixes.rb +37 -0
- data/lib/mongo_mapper_ext/{micelaneous.rb → logging.rb} +30 -8
- data/lib/mongo_mapper_ext/migration.rb +1 -1
- data/lib/mongo_mapper_ext/mongo_mapper.rb +0 -25
- data/lib/mongo_mapper_ext/plugins/{attributes_cache.rb → attribute_cache.rb} +2 -1
- data/lib/mongo_mapper_ext/plugins/attribute_convertors.rb +79 -0
- data/lib/mongo_mapper_ext/plugins/belongs_to_with_counter_cache.rb +45 -0
- data/lib/mongo_mapper_ext/plugins/carrierwave.rb +60 -0
- data/lib/mongo_mapper_ext/plugins/{default_scope.rb → custom_scope.rb} +3 -2
- data/lib/mongo_mapper_ext/plugins/db_config.rb +84 -46
- data/lib/mongo_mapper_ext/plugins/micelaneous.rb +24 -68
- data/lib/mongo_mapper_ext/rad/file_uploader.rb +28 -0
- data/lib/mongo_mapper_ext/rad.rb +2 -0
- data/lib/mongo_mapper_ext/spec.rb +103 -0
- data/lib/mongo_mapper_ext/{migrate.rake → tasks.rb} +3 -15
- data/lib/mongo_mapper_ext.rb +41 -24
- data/readme.md +74 -2
- data/spec/attribute_convertors_spec.rb +71 -0
- data/spec/carrierwave_spec/plane.jpg +0 -0
- data/spec/carrierwave_spec.rb +42 -0
- data/spec/{scope_spec.rb → custom_scope_spec.rb} +26 -32
- data/spec/micelaneous_plugin_spec.rb +34 -20
- data/spec/micelaneous_spec.rb +105 -24
- data/spec/migration_spec.rb +8 -17
- data/spec/{mm_spec.rb → mongo_mapper_spec.rb} +0 -0
- data/spec/spec_helper.rb +2 -5
- data/spec/uploading_spec/ship.jpg +0 -0
- data/spec/uploading_spec//321/204/320/260/320/270/314/206/320/273 /321/201 /320/277/321/200/320/276/320/261/320/265/320/273/320/260/320/274/320/270.txt" +1 -0
- data/spec/uploading_spec.rb +49 -0
- metadata +164 -72
- data/lib/mongo_mapper_ext/db_config.rb +0 -67
- data/lib/mongo_mapper_ext/hacks/time_measuring.rb +0 -44
- data/lib/mongo_mapper_ext/spec/helper.rb +0 -61
data/Rakefile
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'rake_ext'
|
2
2
|
|
3
3
|
project(
|
4
|
-
:
|
5
|
-
:
|
6
|
-
:
|
4
|
+
name: "mongo_mapper_ext",
|
5
|
+
version: "0.2.3",
|
6
|
+
summary: "Extensions for MongoMapper",
|
7
7
|
|
8
|
-
:
|
9
|
-
:
|
8
|
+
author: "Alexey Petrushin",
|
9
|
+
homepage: "http://github.com/alexeypetrushin/mongo_mapper"
|
10
10
|
)
|
@@ -1,2 +1,17 @@
|
|
1
|
-
|
2
|
-
gem '
|
1
|
+
# core gems
|
2
|
+
gem 'mongo_mapper', '0.9.0'
|
3
|
+
|
4
|
+
gem 'carrierwave', '0.5.3'
|
5
|
+
|
6
|
+
# dependencies for core gems
|
7
|
+
gem 'i18n', '0.5.0'
|
8
|
+
gem 'activesupport', '3.0.7'
|
9
|
+
gem 'activemodel', '3.0.7'
|
10
|
+
gem 'bson', '1.3.0'
|
11
|
+
gem 'bson_ext', '1.3.0'
|
12
|
+
gem 'mongo', '1.3.0'
|
13
|
+
gem 'plucky', '0.3.6'
|
14
|
+
gem 'jnunemaker-validatable', '1.8.4'
|
15
|
+
|
16
|
+
gem 'mini_magick', '3.2.1'
|
17
|
+
gem 'subexec', '0.0.4'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
ActiveModel::Name.class_eval do
|
2
|
+
def initialize klass, name = nil
|
3
|
+
name ||= klass.name
|
4
|
+
|
5
|
+
super name
|
6
|
+
|
7
|
+
@klass = klass
|
8
|
+
@singular = ActiveSupport::Inflector.underscore(self).tr('/', '_').freeze
|
9
|
+
@plural = ActiveSupport::Inflector.pluralize(@singular).freeze
|
10
|
+
@element = ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(self)).freeze
|
11
|
+
@human = ActiveSupport::Inflector.humanize(@element).freeze
|
12
|
+
@collection = ActiveSupport::Inflector.tableize(self).freeze
|
13
|
+
@partial_path = "#{@collection}/#{@element}".freeze
|
14
|
+
@i18n_key = ActiveSupport::Inflector.underscore(self).tr('/', '.').to_sym
|
15
|
+
end
|
16
|
+
end
|
@@ -18,3 +18,40 @@ MongoMapper::Plugins::Associations::InArrayProxy.class_eval do
|
|
18
18
|
reset
|
19
19
|
end
|
20
20
|
end
|
21
|
+
|
22
|
+
#
|
23
|
+
# Problem after destroying model the :to_param method returns :nill,
|
24
|
+
# and we can't use :to_param in view (for example in ajax to remove element with id from the screen).
|
25
|
+
#
|
26
|
+
module MongoMapper
|
27
|
+
module Plugins
|
28
|
+
module Rails
|
29
|
+
module InstanceMethods
|
30
|
+
# def to_param
|
31
|
+
# id.to_s if persisted? # old realization
|
32
|
+
# end
|
33
|
+
def to_param
|
34
|
+
id.to_s
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
#
|
43
|
+
# Use class alias instead of class name, because it causes foreign keys like 'models_account_id' instead of 'account_id' if
|
44
|
+
# for models like Models::Account
|
45
|
+
#
|
46
|
+
module MongoMapper
|
47
|
+
module Plugins
|
48
|
+
module Associations
|
49
|
+
class ManyDocumentsProxy
|
50
|
+
def foreign_key
|
51
|
+
# options[:foreign_key] || proxy_owner.class.name.to_s.underscore.gsub("/", "_") + "_id"
|
52
|
+
options[:foreign_key] || proxy_owner.class.alias.to_s.underscore.gsub("/", "_") + "_id"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -1,13 +1,28 @@
|
|
1
|
-
#
|
2
|
-
# upsert
|
3
1
|
#
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
2
|
+
# Custom Logger
|
3
|
+
#
|
4
|
+
MongoMapper.class_eval do
|
5
|
+
class << self
|
6
|
+
|
7
|
+
def logger
|
8
|
+
unless @logger
|
9
|
+
@logger = if "irb" == $0
|
10
|
+
Logger.new(STDOUT)
|
11
|
+
else
|
12
|
+
if defined?(Rails)
|
13
|
+
Rails.test? ? Logger.new(nil) : Rails.logger
|
14
|
+
else
|
15
|
+
Logger.new(STDOUT)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
@logger
|
20
|
+
end
|
21
|
+
|
22
|
+
def logger= logger
|
23
|
+
@logger = logger
|
24
|
+
end
|
9
25
|
|
10
|
-
update({:_id => id}, opt, {:upsert => true, :safe => true})
|
11
26
|
end
|
12
27
|
end
|
13
28
|
|
@@ -36,6 +51,13 @@ MongoMapper.class_eval do
|
|
36
51
|
end
|
37
52
|
end
|
38
53
|
end
|
54
|
+
|
55
|
+
def self.use_database database_alias
|
56
|
+
database_alias = database_alias.to_s
|
57
|
+
MongoMapper.db_config.must.include database_alias
|
58
|
+
MongoMapper.connection = MongoMapper.connections['default']
|
59
|
+
MongoMapper.database = MongoMapper.db_config['default']['name']
|
60
|
+
end
|
39
61
|
end
|
40
62
|
|
41
63
|
|
@@ -1,25 +0,0 @@
|
|
1
|
-
MongoMapper.class_eval do
|
2
|
-
class << self
|
3
|
-
|
4
|
-
def logger
|
5
|
-
# return @logger ||= Logger.new(nil) if defined?(Spec)
|
6
|
-
unless @logger
|
7
|
-
@logger = if "irb" == $0
|
8
|
-
Logger.new(STDOUT)
|
9
|
-
else
|
10
|
-
if defined?(Rails)
|
11
|
-
Rails.test? ? Logger.new(nil) : Rails.logger
|
12
|
-
else
|
13
|
-
Logger.new(STDOUT)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
@logger
|
18
|
-
end
|
19
|
-
|
20
|
-
def logger= logger
|
21
|
-
@logger = logger
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module MongoMapper
|
2
|
+
module Plugins
|
3
|
+
module AttributeConvertors
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
ATTRIBUTE_CONVERTORS = {
|
8
|
+
line: {
|
9
|
+
from_string: -> s {(s || "").split(',').collect{|s| s.strip}},
|
10
|
+
to_string: -> v {v.join(', ')}
|
11
|
+
},
|
12
|
+
column: {
|
13
|
+
from_string: -> s {(s || "").split("\n").collect{|s| s.strip}},
|
14
|
+
to_string: -> v {v.join("\n")}
|
15
|
+
},
|
16
|
+
yaml: {
|
17
|
+
from_string: -> s {YAML.load s rescue {}},
|
18
|
+
to_string: -> v {
|
19
|
+
# MongoMapper uses it's internal Hash that doesn't support to_yaml
|
20
|
+
hash = {}; v.each{|k, v| hash[k] = v}
|
21
|
+
hash.to_yaml.strip
|
22
|
+
}
|
23
|
+
},
|
24
|
+
json: {
|
25
|
+
from_string: -> s {JSON.parse s rescue {}},
|
26
|
+
to_string: -> v {
|
27
|
+
# MongoMapper uses it's internal Hash that doesn't support to_yaml
|
28
|
+
hash = {}; v.each{|k, v| hash[k] = v}
|
29
|
+
hash.to_json.strip
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
|
35
|
+
#
|
36
|
+
# supporf for :as_string option
|
37
|
+
#
|
38
|
+
def key(*args)
|
39
|
+
key = super
|
40
|
+
if converter_name = key.options[:as_string]
|
41
|
+
key_name = key.name.to_sym
|
42
|
+
available_as_string key_name, converter_name
|
43
|
+
attr_protected "#{key_name}_as_string".to_sym if key.options[:protected]
|
44
|
+
end
|
45
|
+
key
|
46
|
+
end
|
47
|
+
|
48
|
+
def available_as_string key_name, converter_name
|
49
|
+
converter = ATTRIBUTE_CONVERTORS[converter_name]
|
50
|
+
raise "unknown converter name :#{converter_name} for :#{key_name} key!" unless converter
|
51
|
+
|
52
|
+
from_string, to_string = converter[:from_string], converter[:to_string]
|
53
|
+
key_name_as_string = "#{key_name}_as_string".to_sym
|
54
|
+
define_method key_name_as_string do
|
55
|
+
cache[key_name_as_string] ||= to_string.call(self.send(key_name))
|
56
|
+
end
|
57
|
+
define_method "#{key_name_as_string}=" do |value|
|
58
|
+
cache.delete key_name_as_string
|
59
|
+
self.send "#{key_name}=", from_string.call(value)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def available_as_yaml key_name
|
64
|
+
raise "delimiter not specified for :#{key_name} key!" unless delimiter
|
65
|
+
method = "#{key_name}_as_string"
|
66
|
+
define_method method do
|
67
|
+
self.send(key_name).join(delimiter)
|
68
|
+
end
|
69
|
+
define_method "#{method}=" do |value|
|
70
|
+
value = (value || "").split(delimiter.strip).collect{|s| s.strip}
|
71
|
+
self.send "#{key_name}=", value
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module MongoMapper
|
2
|
+
module Plugins
|
3
|
+
module BelongsToWithCounterCache
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
#
|
8
|
+
# CounterCache
|
9
|
+
# belongs_to :item, counter_cashe: true
|
10
|
+
#
|
11
|
+
def belongs_to association_id, options={}, &extension
|
12
|
+
options.must_not.include :counter_cashe
|
13
|
+
if options.delete(:counter_cache) || options.delete('counter_cache')
|
14
|
+
association_id = association_id.to_s
|
15
|
+
association_key = "#{association_id}_id"
|
16
|
+
cache_attribute = "#{self.alias.pluralize.underscore}_count"
|
17
|
+
cache_class = if class_name = options[:class_name]
|
18
|
+
class_name.constantize
|
19
|
+
else
|
20
|
+
association_id.classify.constantize
|
21
|
+
end
|
22
|
+
cache_class.keys.must.include cache_attribute
|
23
|
+
increase_method_name = "increase_#{cache_class.alias.underscore}_#{self.alias.pluralize.underscore}_counter"
|
24
|
+
decrease_method_name = "decrease_#{cache_class.alias.underscore}_#{self.alias.pluralize.underscore}_counter"
|
25
|
+
|
26
|
+
define_method increase_method_name do
|
27
|
+
cache_class.upsert!({id: self.send(association_key)}, :$inc => {cache_attribute => 1})
|
28
|
+
end
|
29
|
+
protected increase_method_name
|
30
|
+
|
31
|
+
define_method decrease_method_name do
|
32
|
+
cache_class.upsert!({id: self.send(association_key)}, :$inc => {cache_attribute => -1})
|
33
|
+
end
|
34
|
+
protected decrease_method_name
|
35
|
+
|
36
|
+
after_create increase_method_name
|
37
|
+
after_destroy decrease_method_name
|
38
|
+
end
|
39
|
+
super association_id, options, &extension
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'carrierwave/validations/active_model'
|
2
|
+
|
3
|
+
#
|
4
|
+
# Hacks
|
5
|
+
#
|
6
|
+
CarrierWave::SanitizedFile.class_eval do
|
7
|
+
def sanitize_regexp
|
8
|
+
/[^[:word:]\.\-\+\s_]/i
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
CarrierWave::Uploader::Cache.class_eval do
|
13
|
+
def original_filename=(filename)
|
14
|
+
raise CarrierWave::InvalidParameter, "invalid filename" unless filename =~ /\A[[:word:]\.\-\+\s_]+\z/i
|
15
|
+
@original_filename = filename
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
#
|
21
|
+
# mount_uploader
|
22
|
+
#
|
23
|
+
module MongoMapper
|
24
|
+
module Plugins
|
25
|
+
module CarrierWave
|
26
|
+
extend ActiveSupport::Concern
|
27
|
+
|
28
|
+
module ClassMethods
|
29
|
+
include ::CarrierWave::Mount
|
30
|
+
##
|
31
|
+
# See +CarrierWave::Mount#mount_uploader+ for documentation
|
32
|
+
#
|
33
|
+
def mount_uploader(column, uploader, options={}, &block)
|
34
|
+
define_key column, uploader, options
|
35
|
+
|
36
|
+
super
|
37
|
+
|
38
|
+
alias_method :read_uploader, :read_attribute
|
39
|
+
alias_method :write_uploader, :write_attribute
|
40
|
+
|
41
|
+
include ::CarrierWave::Validations::ActiveModel
|
42
|
+
|
43
|
+
validates_integrity_of column if uploader_option(column.to_sym, :validate_integrity)
|
44
|
+
validates_processing_of column if uploader_option(column.to_sym, :validate_processing)
|
45
|
+
|
46
|
+
after_save "store_#{column}!".to_sym
|
47
|
+
before_save "write_#{column}_identifier".to_sym
|
48
|
+
after_destroy "remove_#{column}!".to_sym
|
49
|
+
end
|
50
|
+
|
51
|
+
protected
|
52
|
+
def define_key column, uploader, options
|
53
|
+
options[:mount_on] ||= "#{column}_filename"
|
54
|
+
name = options[:mount_on]
|
55
|
+
key name
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module MongoMapper
|
2
2
|
module Plugins
|
3
|
-
module
|
3
|
+
module CustomScope
|
4
|
+
extend ActiveSupport::Concern
|
4
5
|
|
5
6
|
module ClassMethods
|
6
7
|
def query options = {}
|
@@ -46,7 +47,7 @@ module MongoMapper
|
|
46
47
|
|
47
48
|
protected
|
48
49
|
def default_scope options = nil, &block
|
49
|
-
options.must_be.a
|
50
|
+
options.must_be.a NilClass, Hash
|
50
51
|
self.write_inheritable_attribute(:default_scope, (options || block))
|
51
52
|
end
|
52
53
|
|
@@ -1,47 +1,85 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
#
|
4
|
-
#
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
1
|
+
module MongoMapper
|
2
|
+
#
|
3
|
+
# Connection Pool
|
4
|
+
#
|
5
|
+
class ConnectionsPool < Hash
|
6
|
+
def [](database_alias)
|
7
|
+
database_alias = database_alias.to_s
|
8
|
+
unless connection = super(database_alias)
|
9
|
+
MongoMapper.db_config.must.include database_alias
|
10
|
+
db_options = MongoMapper.db_config[database_alias]
|
11
|
+
connection = Mongo::Connection.new(db_options['host'], db_options['port'], logger: MongoMapper.logger)
|
12
|
+
|
13
|
+
if defined?(PhusionPassenger)
|
14
|
+
PhusionPassenger.on_event(:starting_worker_process) do |forked|
|
15
|
+
connection.connect_to_master if forked
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
self[database_alias] = connection
|
20
|
+
end
|
21
|
+
return connection
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
#
|
27
|
+
# Databases Pool
|
28
|
+
#
|
29
|
+
class DatabasesPool < Hash
|
30
|
+
def [](database_alias)
|
31
|
+
database_alias = database_alias.to_s
|
32
|
+
unless db = super(database_alias)
|
33
|
+
MongoMapper.db_config.must.include database_alias
|
34
|
+
db_options = MongoMapper.db_config[database_alias]
|
35
|
+
db = MongoMapper.connections[database_alias].db db_options['name'].must_be.a(String)
|
36
|
+
self[database_alias] = db
|
37
|
+
end
|
38
|
+
return db
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class << self
|
43
|
+
attr_accessor :db_config
|
44
|
+
|
45
|
+
def db_config
|
46
|
+
@db_config ||= {}
|
47
|
+
end
|
48
|
+
|
49
|
+
def connections
|
50
|
+
@connections ||= ConnectionsPool.new
|
51
|
+
end
|
52
|
+
|
53
|
+
def databases
|
54
|
+
@databases ||= DatabasesPool.new
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
|
22
60
|
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
|
35
|
-
#
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
#
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
61
|
+
# Plugin
|
62
|
+
#
|
63
|
+
module MongoMapper
|
64
|
+
module Plugins
|
65
|
+
module DbConfig
|
66
|
+
extend ActiveSupport::Concern
|
67
|
+
|
68
|
+
module ClassMethods
|
69
|
+
#
|
70
|
+
# Connect to database_alias specified in config
|
71
|
+
#
|
72
|
+
def use_database database_alias
|
73
|
+
# defer do
|
74
|
+
database_alias = database_alias.to_s
|
75
|
+
MongoMapper.db_config.must.include database_alias
|
76
|
+
|
77
|
+
self.connection MongoMapper.connections[database_alias]
|
78
|
+
set_database_name MongoMapper.db_config[database_alias]['name']
|
79
|
+
# end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -1,95 +1,51 @@
|
|
1
1
|
module MongoMapper
|
2
|
-
# def self.deferred; @deferred ||= [] end
|
3
|
-
# def self.call_deferred
|
4
|
-
# deferred.every.call
|
5
|
-
# deferred.clear
|
6
|
-
# end
|
7
|
-
|
8
2
|
module Plugins
|
9
3
|
module Micelaneous
|
4
|
+
extend ActiveSupport::Concern
|
10
5
|
|
11
6
|
module InstanceMethods
|
12
|
-
def upsert *args
|
13
|
-
self.class.upsert id, *args
|
7
|
+
def upsert! *args
|
8
|
+
self.class.upsert!({id: id}, *args)
|
9
|
+
end
|
10
|
+
|
11
|
+
def exist?
|
12
|
+
self.class.find(id) != nil
|
14
13
|
end
|
15
14
|
end
|
16
15
|
|
17
|
-
module ClassMethods
|
16
|
+
module ClassMethods
|
17
|
+
#
|
18
|
+
# model_name
|
19
|
+
#
|
20
|
+
def model_name *args
|
21
|
+
if args.empty?
|
22
|
+
@model_name ||= ::ActiveModel::Name.new self, self.alias
|
23
|
+
else
|
24
|
+
@model_name = ::ActiveModel::Name.new self, args.first
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
18
29
|
#
|
19
30
|
# Sequentiall :all for big collection
|
20
31
|
#
|
21
32
|
def all_sequentially &block
|
22
33
|
page, per_page = 1, 5
|
23
34
|
begin
|
24
|
-
results = paginate(:
|
35
|
+
results = paginate(page: page, per_page: per_page, order: '_id asc')
|
25
36
|
results.each{|o| block.call o}
|
26
37
|
page += 1
|
27
38
|
end until results.blank? or results.size < per_page
|
28
39
|
end
|
29
40
|
|
30
41
|
|
31
|
-
#
|
32
|
-
# Deferred execution
|
33
|
-
#
|
34
|
-
# def defer &block
|
35
|
-
# MongoMapper.deferred << block
|
36
|
-
# end
|
37
|
-
|
38
|
-
|
39
|
-
#
|
40
|
-
# Connect to database_alias specified in config
|
41
|
-
#
|
42
|
-
def use_database database_alias
|
43
|
-
# defer do
|
44
|
-
database_alias = database_alias.to_s
|
45
|
-
MongoMapper.db_config.must.include database_alias
|
46
|
-
|
47
|
-
self.connection MongoMapper.connections[database_alias]
|
48
|
-
set_database_name MongoMapper.db_config[database_alias]['name']
|
49
|
-
# end
|
50
|
-
end
|
51
|
-
|
52
|
-
|
53
42
|
#
|
54
43
|
# shortcut for upsert
|
55
44
|
#
|
56
|
-
def upsert *args
|
57
|
-
|
45
|
+
def upsert! query, *args
|
46
|
+
query[:_id] = query.delete :id if query.include? :id
|
47
|
+
collection.upsert! query, *args
|
58
48
|
end
|
59
|
-
|
60
|
-
|
61
|
-
#
|
62
|
-
# CounterCache
|
63
|
-
# belongs_to :item, :counter_cashe => true
|
64
|
-
#
|
65
|
-
def belongs_to association_id, options={}, &extension
|
66
|
-
options.must_not.include :counter_cashe
|
67
|
-
if options.delete(:counter_cache) || options.delete('counter_cache')
|
68
|
-
association_id = association_id.to_s
|
69
|
-
association_key = "#{association_id}_id"
|
70
|
-
cache_attribute = "#{name.pluralize.underscore}_count"
|
71
|
-
cache_class = association_id.classify.constantize
|
72
|
-
cache_class.keys.must.include cache_attribute
|
73
|
-
increase_method_name = "increase_#{cache_class.name.underscore}_#{name.pluralize.underscore}_counter"
|
74
|
-
decrease_method_name = "decrease_#{cache_class.name.underscore}_#{name.pluralize.underscore}_counter"
|
75
|
-
|
76
|
-
define_method increase_method_name do
|
77
|
-
cache_class.upsert self.send(association_key), :$inc => {cache_attribute => 1}
|
78
|
-
end
|
79
|
-
protected increase_method_name
|
80
|
-
|
81
|
-
define_method decrease_method_name do
|
82
|
-
cache_class.upsert self.send(association_key), :$inc => {cache_attribute => -1}
|
83
|
-
end
|
84
|
-
protected decrease_method_name
|
85
|
-
|
86
|
-
after_create increase_method_name
|
87
|
-
after_destroy decrease_method_name
|
88
|
-
end
|
89
|
-
|
90
|
-
super association_id, options, &extension
|
91
|
-
end
|
92
|
-
|
93
49
|
end
|
94
50
|
|
95
51
|
end
|