mongo_odm 0.2.8 → 0.2.9

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.
@@ -5,17 +5,24 @@ module MongoODM
5
5
 
6
6
  delegate :inspect, :to_xml, :to_yaml, :to_json, :include?, :to => :to_a
7
7
 
8
- def initialize(klass, selector = {}, opts = {})
9
- @klass, @selector, @opts = klass, selector, opts
8
+ def initialize(klass, options = {})
9
+ @klass = klass
10
+ @selector = options[:selector] || {}
11
+ @opts = options[:opts] || {}
12
+ @sort = options[:sort] || []
13
+ @limit = options[:limit] || nil
14
+ @skip = options[:skip] || nil
10
15
  _set_cursor
11
16
  end
12
- attr_reader :selector, :opts, :cursor
13
17
 
14
18
  def ==(other)
15
19
  case other
16
20
  when Criteria
17
- other.instance_variable_get("@selector") == @selector &&
18
- other.instance_variable_get("@opts") == @opts
21
+ other.instance_variable_get(:@selector) == @selector &&
22
+ other.instance_variable_get(:@opts) == @opts &&
23
+ other.instance_variable_get(:@sort) == @sort &&
24
+ other.instance_variable_get(:@limit) == @limit &&
25
+ other.instance_variable_get(:@skip) == @skip
19
26
  else
20
27
  to_a == other.to_a
21
28
  end
@@ -25,13 +32,24 @@ module MongoODM
25
32
  @cursor.to_a
26
33
  end
27
34
 
35
+ def to_cursor
36
+ @cursor
37
+ end
38
+
28
39
  def _set_cursor
29
40
  @cursor = @klass.collection.find(@selector, @opts)
41
+ @cursor = @cursor.sort(@sort) unless @sort.blank?
42
+ @cursor = @cursor.limit(@limit) unless @limit.blank?
43
+ @cursor = @cursor.skip(@skip) unless @skip.blank?
44
+ @cursor
30
45
  end
31
46
 
32
- def _merge_criteria(selector, opts)
33
- @selector.merge!(selector)
34
- @opts.merge!(opts)
47
+ def _merge_criteria(criteria)
48
+ @selector.merge!(criteria.instance_variable_get(:@selector))
49
+ @opts.merge!(criteria.instance_variable_get(:@opts))
50
+ @sort << criteria.instance_variable_get(:@sort) unless criteria.instance_variable_get(:@sort).blank?
51
+ @limit = criteria.instance_variable_get(:@limit) unless criteria.instance_variable_get(:@limit).blank?
52
+ @skip = criteria.instance_variable_get(:@skip) unless criteria.instance_variable_get(:@skip).blank?
35
53
  _set_cursor
36
54
  self
37
55
  end
@@ -39,7 +57,7 @@ module MongoODM
39
57
  def method_missing(method_name, *args, &block)
40
58
  if @klass.respond_to?(method_name)
41
59
  result = @klass.send(method_name, *args, &block)
42
- result.is_a?(Criteria) ? _merge_criteria(result.selector, result.opts) : result
60
+ result.is_a?(Criteria) ? _merge_criteria(result) : result
43
61
  elsif @cursor.respond_to?(method_name)
44
62
  @cursor.send(method_name, *args, &block)
45
63
  elsif [].respond_to?(method_name)
@@ -1,6 +1,8 @@
1
1
  # encoding: utf-8
2
2
  module MongoODM
3
3
 
4
+ delegate :inspect, :to_xml, :to_yaml, :to_json, :include?, :to => :to_a
5
+
4
6
  class Cursor < Mongo::Cursor
5
7
  def next_document
6
8
  doc = super
@@ -88,18 +88,31 @@ module MongoODM
88
88
  end
89
89
  end
90
90
 
91
- def find(*args)
92
- if args.size == 1 && args.first.is_a?(String)
93
- MongoODM::Criteria.new(self, :_id => BSON::ObjectId.from_string(args.first))
94
- elsif args.size == 1 && args.first.is_a?(BSON::ObjectId)
95
- MongoODM::Criteria.new(self, :_id => args.first)
91
+ def find(selector = {}, opts = {})
92
+ if opts.blank? && selector.is_a?(String)
93
+ MongoODM::Criteria.new(self, :selector => {:_id => BSON::ObjectId.from_string(selector)})
94
+ elsif opts.blank? && selector.is_a?(BSON::ObjectId)
95
+ MongoODM::Criteria.new(self, :selector => {:_id => selector})
96
96
  else
97
- MongoODM::Criteria.new(self, *args)
97
+ MongoODM::Criteria.new(self, :selector => selector, :opts => opts)
98
98
  end
99
99
  end
100
100
 
101
+ def sort(key_or_list, direction = nil)
102
+ order = key_or_list.is_a?(Array) ? key_or_list : direction.nil? ? [key_or_list, :asc] : [key_or_list, direction]
103
+ MongoODM::Criteria.new(self, :sort => order)
104
+ end
105
+
106
+ def skip(number_to_skip = nil)
107
+ MongoODM::Criteria.new(self, :skip => number_to_skip)
108
+ end
109
+
110
+ def limit(number_to_return = nil)
111
+ MongoODM::Criteria.new(self, :limit => number_to_return)
112
+ end
113
+
101
114
  def cursor
102
- @cursor ||= find.cursor
115
+ @cursor ||= find.to_cursor
103
116
  end
104
117
 
105
118
  def destroy_all(*args)
@@ -0,0 +1,64 @@
1
+ # encoding: utf-8
2
+ require 'active_support/core_ext/module/aliasing'
3
+
4
+ module MongoODM
5
+ module Document
6
+ module Validations
7
+ # Validates whether or not a field is unique against the documents in the
8
+ # database.
9
+ #
10
+ # @example Define the uniqueness validator.
11
+ #
12
+ # class Person
13
+ # include MongoODM::Document
14
+ # field :title
15
+ #
16
+ # validates_uniqueness_of :title
17
+ # end
18
+ class UniquenessValidator < ActiveModel::EachValidator
19
+
20
+ # Unfortunately, we have to tie Uniqueness validators to a class.
21
+ def setup(klass)
22
+ @klass = klass
23
+ end
24
+
25
+ # Validate the document for uniqueness violations.
26
+ #
27
+ # @example Validate the document.
28
+ # validate_each(person, :title, "Sir")
29
+ #
30
+ # @param [ Document ] document The document to validate.
31
+ # @param [ Symbol ] attribute The field to validate on.
32
+ # @param [ Object ] value The value of the field.
33
+ def validate_each(document, attribute, value)
34
+ criteria = @klass.find(attribute => unique_search_value(value))
35
+ unless document.new_record?
36
+ criteria = criteria.find(:_id => {'$ne' => document._id})
37
+ end
38
+
39
+ Array.wrap(options[:scope]).each do |item|
40
+ criteria = criteria.find(item => document.attributes[item])
41
+ end
42
+ if criteria.first
43
+ document.errors.add(
44
+ attribute,
45
+ :taken,
46
+ options.except(:case_sensitive, :scope).merge(:value => value)
47
+ )
48
+ end
49
+ end
50
+
51
+ protected
52
+
53
+ # ensure :case_sensitive is true by default
54
+ def unique_search_value(value)
55
+ if options[:case_sensitive]
56
+ value
57
+ else
58
+ value ? Regexp.new("^#{Regexp.escape(value.to_s)}$", Regexp::IGNORECASE) : nil
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -6,6 +6,9 @@ module MongoODM
6
6
  module Validations
7
7
 
8
8
  extend ActiveSupport::Concern
9
+ extend ActiveSupport::Autoload
10
+
11
+ autoload :UniquenessValidator
9
12
 
10
13
  included do
11
14
  include ActiveModel::Validations
@@ -38,6 +41,25 @@ module MongoODM
38
41
  errors.empty?
39
42
  end
40
43
  end
44
+
45
+ module ClassMethods
46
+ # Validates whether or not a field is unique against the documents in the
47
+ # database.
48
+ #
49
+ # @example
50
+ #
51
+ # class Person
52
+ # include MongoODM::Document
53
+ # field :title
54
+ #
55
+ # validates_uniqueness_of :title
56
+ # end
57
+ #
58
+ # @param [ Array ] *args The arguments to pass to the validator.
59
+ def validates_uniqueness_of(*args)
60
+ validates_with(UniquenessValidator, _merge_attributes(args))
61
+ end
62
+ end
41
63
 
42
64
  end
43
65
  end
@@ -2,6 +2,6 @@
2
2
  module MongoODM
3
3
  VERSION_MAJOR = "0"
4
4
  VERSION_MINOR = "2"
5
- VERSION_BUILD = "8"
5
+ VERSION_BUILD = "9"
6
6
  VERSION = "#{VERSION_MAJOR}.#{VERSION_MINOR}.#{VERSION_BUILD}"
7
7
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: mongo_odm
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.2.8
5
+ version: 0.2.9
6
6
  platform: ruby
7
7
  authors:
8
8
  - Carlos Paramio
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-02-20 00:00:00 +01:00
13
+ date: 2011-03-14 00:00:00 +01:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -270,6 +270,7 @@ files:
270
270
  - lib/mongo_odm/document/persistence.rb
271
271
  - lib/mongo_odm/document/timestamps.rb
272
272
  - lib/mongo_odm/document/validations.rb
273
+ - lib/mongo_odm/document/validations/uniqueness_validator.rb
273
274
  - lib/mongo_odm/errors.rb
274
275
  - lib/mongo_odm/railtie.rb
275
276
  - lib/mongo_odm/version.rb