dedupe 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,11 @@
1
+ # .document is used by rdoc and yard to know how to generate documentation
2
+ # for example, it can be used to control how rdoc gets built when you do `gem install foo`
3
+
4
+ README.rdoc
5
+ lib/**/*.rb
6
+ bin/*
7
+
8
+ # Files below this - are treated as 'extra files', and aren't parsed for ruby code
9
+ -
10
+ features/**/*.feature
11
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ # rcov generated
2
+ coverage
3
+
4
+ # rdoc generated
5
+ rdoc
6
+
7
+ # yard generated
8
+ doc
9
+ .yardoc
10
+
11
+ # bundler
12
+ .bundle
13
+
14
+ # jeweler generated
15
+ pkg
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format nested
data/.rvmrc ADDED
@@ -0,0 +1,5 @@
1
+ # default gemset
2
+ rvm 1.9.2@dedupe
3
+
4
+ # return to system ruby on leaving directory
5
+ rvm_project_rvmrc_default=1
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem "activesupport", "~> 3.0.0"
4
+ gem "activemodel", "~> 3.0.0"
5
+
6
+ group :development do
7
+ gem "rspec", ">= 2.0.0.beta.19"
8
+ gem "bundler", "~> 1.0.0"
9
+ gem "jeweler", "~> 1.5.0.pre3"
10
+ gem "rcov", ">= 0"
11
+ gem "mongoid", "2.0.0.beta.19"
12
+ gem "bson_ext", "1.0.9"
13
+ gem "activerecord", "~> 3.0.0"
14
+ gem "sqlite3-ruby", "~> 1.3.1"
15
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,62 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activemodel (3.0.0)
5
+ activesupport (= 3.0.0)
6
+ builder (~> 2.1.2)
7
+ i18n (~> 0.4.1)
8
+ activerecord (3.0.0)
9
+ activemodel (= 3.0.0)
10
+ activesupport (= 3.0.0)
11
+ arel (~> 1.0.0)
12
+ tzinfo (~> 0.3.23)
13
+ activesupport (3.0.0)
14
+ arel (1.0.1)
15
+ activesupport (~> 3.0.0)
16
+ bson (1.0.9)
17
+ bson_ext (1.0.9)
18
+ builder (2.1.2)
19
+ diff-lcs (1.1.2)
20
+ git (1.2.5)
21
+ i18n (0.4.1)
22
+ jeweler (1.5.0.pre3)
23
+ bundler (~> 1.0.0)
24
+ git (>= 1.2.5)
25
+ rake
26
+ mongo (1.0.9)
27
+ bson (>= 1.0.5)
28
+ mongoid (2.0.0.beta.19)
29
+ activemodel (~> 3.0)
30
+ mongo (= 1.0.9)
31
+ tzinfo (~> 0.3.22)
32
+ will_paginate (~> 3.0.pre)
33
+ rake (0.8.7)
34
+ rcov (0.9.9)
35
+ rspec (2.0.0.beta.22)
36
+ rspec-core (= 2.0.0.beta.22)
37
+ rspec-expectations (= 2.0.0.beta.22)
38
+ rspec-mocks (= 2.0.0.beta.22)
39
+ rspec-core (2.0.0.beta.22)
40
+ rspec-expectations (2.0.0.beta.22)
41
+ diff-lcs (>= 1.1.2)
42
+ rspec-mocks (2.0.0.beta.22)
43
+ rspec-core (= 2.0.0.beta.22)
44
+ rspec-expectations (= 2.0.0.beta.22)
45
+ sqlite3-ruby (1.3.1)
46
+ tzinfo (0.3.23)
47
+ will_paginate (3.0.pre2)
48
+
49
+ PLATFORMS
50
+ ruby
51
+
52
+ DEPENDENCIES
53
+ activemodel (~> 3.0.0)
54
+ activerecord (~> 3.0.0)
55
+ activesupport (~> 3.0.0)
56
+ bson_ext (= 1.0.9)
57
+ bundler (~> 1.0.0)
58
+ jeweler (~> 1.5.0.pre3)
59
+ mongoid (= 2.0.0.beta.19)
60
+ rcov
61
+ rspec (>= 2.0.0.beta.19)
62
+ sqlite3-ruby (~> 1.3.1)
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Brent Hargrave
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,85 @@
1
+ = dedupe
2
+
3
+
4
+ == Description
5
+
6
+ Dedupe provides Mongoid and ActiveRecord 3 with a uniqueness validation that protects your datastore from duplicate records, defined by your domain.
7
+
8
+ The following model defines a uniqueness constraint:
9
+
10
+ class Model
11
+ include Mongoid::Document
12
+
13
+ field :foo
14
+ field :bar
15
+ field :baz
16
+
17
+ validates_uniqueness :using => :with_matching_foo_and_bar
18
+ scope :with_matching_foo_and_bar, lambda { |instance|
19
+ where :foo => instance.foo, :bar => instance.bar
20
+ # our hypothetical domain requires that we disregard :baz
21
+ }
22
+
23
+ end
24
+
25
+ Any attempt to save a record with the same "foo" and "bar" values will fail.
26
+
27
+ > existing = Model.create! :foo => "a", :bar => "b", :baz => "c"
28
+ => #<Model _id: 123abc, foo: "a", bar: "b", baz: "c">
29
+
30
+ > duplicate = Model.new :foo => "a", :bar => "b", :baz => "z"
31
+ => #<Model _id: 456def, foo: "a", bar: "b", baz: "z">
32
+
33
+ > duplicate.valid?
34
+ => false
35
+
36
+ > duplicate.errors.full_messages
37
+ => ["Duplicates existing record"]
38
+
39
+ > duplicate.save!
40
+ Mongoid::Errors::Validations: Validation failed...
41
+
42
+ The gem also provides a few other methods, possibly useful for cleaning up datastores already corrupted with duplicate records.
43
+
44
+ > duplicate.duplicate?
45
+ => true
46
+
47
+ > duplicate.duplicates.to_a
48
+ => [#<Model _id: 123abc, foo: "a", bar: "b", baz: "c">]
49
+
50
+ > existing.duplicates.to_a
51
+ => []
52
+
53
+
54
+ == Installation & Usage
55
+
56
+ Add the gem to your Gemfile:
57
+ gem 'dedupe'
58
+
59
+ Add a scope or "finder" method to your model that a) accepts an instance of your model and b) returns a relation/criterion that would select all duplicate instances in your datastore. In the above example, this method is:
60
+ scope :with_matching_foo_and_bar, lambda { |instance|
61
+ where :foo => instance.foo, :baz => instance.baz
62
+ }
63
+
64
+ But you could also define:
65
+ def with_matching_foo_and_bar(instance)
66
+ where :foo => instance.foo, :baz => instance.baz
67
+ end
68
+
69
+ Then, mix the Dedupe module into your model using the "validates_uniqueness" macro, passing it the name of your scope/finder:
70
+ validates_uniqueness :using => :with_matching_foo_and_bar
71
+
72
+
73
+ == Note on Patches/Pull Requests
74
+
75
+ * Fork the project.
76
+ * Make your feature addition or bug fix.
77
+ * Add tests for it. This is important so I don't break it in a
78
+ future version unintentionally.
79
+ * Commit, do not mess with rakefile, version, or history.
80
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
81
+ * Send me a pull request. Bonus points for topic branches.
82
+
83
+ == Copyright
84
+
85
+ Copyright (c) 2010 Brent Hargrave. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,45 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'rake'
11
+
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |gem|
14
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15
+ gem.name = "dedupe"
16
+ gem.summary = %Q{ActiveModel validation against duplicating records.}
17
+ gem.description = %Q{ActiveModel validation against duplicating records.}
18
+ gem.email = "brent.hargrave@gmail.com"
19
+ gem.homepage = "http://github.com/jamescallmebrent/dedupe"
20
+ gem.authors = ["Brent Hargrave"]
21
+ end
22
+ Jeweler::RubygemsDotOrgTasks.new
23
+
24
+ require 'rspec/core'
25
+ require 'rspec/core/rake_task'
26
+ RSpec::Core::RakeTask.new(:spec) do |spec|
27
+ spec.pattern = FileList['spec/**/*_spec.rb']
28
+ end
29
+
30
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
31
+ spec.pattern = 'spec/**/*_spec.rb'
32
+ spec.rcov = true
33
+ end
34
+
35
+ task :default => :spec
36
+
37
+ require 'rake/rdoctask'
38
+ Rake::RDocTask.new do |rdoc|
39
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
40
+
41
+ rdoc.rdoc_dir = 'rdoc'
42
+ rdoc.title = "dedupe #{version}"
43
+ rdoc.rdoc_files.include('README*')
44
+ rdoc.rdoc_files.include('lib/**/*.rb')
45
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.0
data/lib/dedupe.rb ADDED
@@ -0,0 +1,30 @@
1
+ require 'dedupe/errors'
2
+ require 'dedupe/validations'
3
+ require 'dedupe/orm/mongoid'
4
+ require 'dedupe/orm/active_record'
5
+
6
+ module Dedupe
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ cattr_accessor :dedupe_scope_name
11
+ end
12
+
13
+ module ClassMethods
14
+
15
+ def validates_uniqueness(options={})
16
+ self.dedupe_scope_name = options.delete :using
17
+ if defined?(Mongoid::Document) && self.new.is_a?(Mongoid::Document)
18
+ self.send :include, Orm::Mongoid
19
+ elsif defined?(ActiveRecord::Base) && self.new.is_a?(ActiveRecord::Base)
20
+ self.send :include, Orm::ActiveRecord
21
+ end
22
+ self.send :include, Validations
23
+ end
24
+
25
+ end
26
+
27
+ end
28
+
29
+ Mongoid::Document.send :include, Dedupe if defined? Mongoid::Document
30
+ ActiveRecord::Base.send :include, Dedupe if defined? ActiveRecord::Base
@@ -0,0 +1,6 @@
1
+ module Dedupe
2
+ module Errors
3
+ class MissingScope < StandardError; end
4
+ class InvalidScope < StandardError; end
5
+ end
6
+ end
@@ -0,0 +1,31 @@
1
+ module Dedupe
2
+ module Orm
3
+ module ActiveRecord
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ scope :excluding, lambda { |instance|
8
+ where('id <> ?', instance.id.to_i)
9
+ }
10
+ end
11
+
12
+ module InstanceMethods
13
+ include Errors
14
+
15
+ def duplicates
16
+ klass, scope_name = self.class, self.class.dedupe_scope_name
17
+ raise MissingScope unless klass.respond_to? scope_name
18
+ result_set = klass.send scope_name, self
19
+ raise InvalidScope unless result_set.is_a? ::ActiveRecord::Relation
20
+ result_set.excluding self
21
+ end
22
+
23
+ def duplicate?
24
+ self.duplicates.present?
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ module Dedupe
2
+ module Orm
3
+ module Mongoid
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ scope :excluding, lambda { |instance|
8
+ excludes(:id => instance.id)
9
+ }
10
+ end
11
+
12
+ module InstanceMethods
13
+ include Errors
14
+
15
+ def duplicates
16
+ klass, scope_name = self.class, self.class.dedupe_scope_name
17
+ raise MissingScope unless klass.respond_to? scope_name
18
+ result_set = klass.send scope_name, self
19
+ raise InvalidScope unless result_set.is_a? ::Mongoid::Criteria
20
+ result_set.excluding self
21
+ end
22
+
23
+ def duplicate?
24
+ self.duplicates.present?
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,18 @@
1
+ module Dedupe
2
+ module Validations
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ validates_with RecordUniquenessValidator
7
+ end
8
+
9
+ class RecordUniquenessValidator < ActiveModel::Validator
10
+ def validate(record)
11
+ if record.duplicate?
12
+ record.errors.add :base, "Duplicates existing record"
13
+ end
14
+ end
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,148 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ shared_examples_for "any Dedupe helper method" do
4
+ it "should raise error if validates_uniqueness omitted" do
5
+ instance ||= @macroless_model.new
6
+ lambda do
7
+ instance.send(@method_name)
8
+ end.should raise_error(NoMethodError)
9
+ end
10
+ end
11
+ shared_examples_for "any Dedupe instance method" do
12
+ it "should raise error if scope omitted" do
13
+ instance = @scopeless_model.new
14
+ lambda do
15
+ instance.send(@method_name)
16
+ end.should raise_error(Dedupe::Errors::MissingScope)
17
+ end
18
+ it "should raise error if scope returns a non-criterion" do
19
+ instance = @invalid_scope_model.new
20
+ lambda do
21
+ instance.send(@method_name)
22
+ end.should raise_error(Dedupe::Errors::InvalidScope)
23
+ end
24
+ end
25
+
26
+ shared_examples_for "any supported ORM" do
27
+ context "finding" do
28
+ context "all but a provided instance (excluding)" do
29
+ before do
30
+ @existing = @model.create!(:foo => 'a', :bar => 'b')
31
+ @others = []
32
+ @others << @model.create!(:foo => 'd', :bar => 'e')
33
+ @others << @model.create!(:foo => 'g', :bar => 'g')
34
+ @found = @model.excluding(@existing).to_a
35
+ end
36
+ it "should not include that instance" do
37
+ @found.should_not include(@existing)
38
+ end
39
+ it "should include all other instances" do
40
+ @others.all? { |instance| @found.include?(instance) }.should be_true
41
+ end
42
+ it "should raise error if validates_uniqueness omitted" do
43
+ lambda do
44
+ @macroless_model.excluding
45
+ end.should raise_error(NoMethodError)
46
+ end
47
+ end
48
+ context 'duplicates of a provided instance (dev-defined scope/finder)' do
49
+ before do
50
+ @existing = @model.create! :foo => 'foo', :bar => 'bar'
51
+ @unique_bar = @model.create! :foo => 'foo', :bar => 'unique'
52
+ @unique_foo = @model.create! :foo => 'unique', :bar => 'bar'
53
+ @duplicate = @model.new :foo => 'foo', :bar => 'bar'
54
+ @found = @model.with_attributes_of(@duplicate).to_a
55
+ end
56
+ it 'should exclude instances with only *some* duplicate attributes' do
57
+ @found.should_not include(@unique_foo)
58
+ @found.should_not include(@unique_bar)
59
+ end
60
+ it 'should include instances with duplicate attributes' do
61
+ @found.should include(@existing)
62
+ end
63
+ end
64
+ end
65
+ context "instance" do
66
+ context "duplicates" do
67
+ before do
68
+ @method_name = "duplicates"
69
+ @existing = @model.create! :foo => 'a', :bar => 'b'
70
+ @other = @model.create! :foo => 'c', :bar => 'd'
71
+ @proposed = @model.new :foo => 'a', :bar => 'b'
72
+ end
73
+ it "should include its duplicate" do
74
+ @proposed.duplicates.should include(@existing)
75
+ end
76
+ it "should exclude non-duplicates" do
77
+ @proposed.duplicates.should_not include(@other)
78
+ end
79
+ it "should exclude itself" do
80
+ @existing.duplicates.should_not include(@existing)
81
+ end
82
+ it_should_behave_like "any Dedupe helper method"
83
+ it_should_behave_like "any Dedupe instance method"
84
+ end
85
+ context "duplicate?" do
86
+ before do
87
+ @method_name = "duplicate?"
88
+ @existing = @model.create! :foo => 'a', :bar => 'b'
89
+ @duplicate = @model.new :foo => 'a', :bar => 'b'
90
+ @non_duplicate = @model.new :foo => 'c', :bar => 'd'
91
+ end
92
+ it "duplicate? should be true if it has duplicates" do
93
+ @duplicate.should be_duplicate
94
+ end
95
+ it "duplicate? should be false if it lacks duplicates" do
96
+ @non_duplicate.should_not be_duplicate
97
+ end
98
+ # shared behavior?
99
+ it_should_behave_like "any Dedupe helper method"
100
+ it_should_behave_like "any Dedupe instance method"
101
+ end
102
+ context "validation (valid?)" do
103
+ before do
104
+ @method_name = "valid?"
105
+ @existing = @model.create! :foo => 'a', :bar => 'b'
106
+ @duplicate = @model.new :foo => 'a', :bar => 'b'
107
+ @non_duplicate = @model.new :foo => 'c', :bar => 'd'
108
+ end
109
+ it "with unique attributes should be true" do
110
+ @non_duplicate.should be_valid
111
+ end
112
+ context "with duplicate attributes" do
113
+ it "should be false" do
114
+ @duplicate.should_not be_valid
115
+ end
116
+ it "should add an error" do
117
+ @duplicate.valid? # call valid
118
+ @duplicate.errors[:base].should include "Duplicates existing record"
119
+ end
120
+ end
121
+ it_should_behave_like "any Dedupe instance method"
122
+ end
123
+ end
124
+ end
125
+
126
+ describe "Mongoid model" do
127
+ before do
128
+ @macroless_model = MongoidMacrolessModel
129
+ @scopeless_model = MongoidScopelessModel
130
+ @invalid_scope_model = MongoidInvalidScopeModel
131
+ @model = MongoidModel
132
+ end
133
+ it_should_behave_like "any supported ORM"
134
+ end
135
+
136
+ describe "ActiveRecord model" do
137
+ before do
138
+ @macroless_model = ActiveRecordMacrolessModel
139
+ @macroless_model.destroy_all
140
+ @scopeless_model = ActiveRecordScopelessModel
141
+ @scopeless_model.destroy_all
142
+ @invalid_scope_model = ActiveRecordInvalidScopeModel
143
+ @invalid_scope_model.destroy_all
144
+ @model = ActiveRecordModel
145
+ @model.destroy_all
146
+ end
147
+ it_should_behave_like "any supported ORM"
148
+ end
@@ -0,0 +1,17 @@
1
+ require 'bundler'
2
+ begin
3
+ Bundler.setup(:default, :development)
4
+ rescue Bundler::BundlerError => e
5
+ $stderr.puts e.message
6
+ $stderr.puts "Run `bundle install` to install missing gems"
7
+ exit e.status_code
8
+ end
9
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
10
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
11
+
12
+ require "mongoid"
13
+ require "active_record"
14
+ require "dedupe"
15
+ require "rspec"
16
+
17
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |file| require file }
@@ -0,0 +1,35 @@
1
+ ActiveRecord::Base.establish_connection :adapter => 'sqlite3',
2
+ :database => ':memory:'
3
+ ActiveRecord::Migration.verbose = false
4
+ tables = %w{ active_record_macroless_models active_record_scopeless_models active_record_invalid_scope_models active_record_models }
5
+ ActiveRecord::Schema.define(:version => 1) do
6
+ tables.each do |table_name|
7
+ create_table table_name.intern, :force => true do |t|
8
+ t.datetime :created_at
9
+ t.datetime :updated_at
10
+ t.string :foo
11
+ t.string :bar
12
+ end
13
+ end
14
+ end
15
+
16
+ # a "vanilla" ActiveRecord model
17
+ class ActiveRecordMacrolessModel < ActiveRecord::Base
18
+ end
19
+ # ActiveRecord model with macro included, but required scope "forgotten"
20
+ class ActiveRecordScopelessModel < ActiveRecordMacrolessModel
21
+ validates_uniqueness :using => :with_attributes_of
22
+ end
23
+ # ActiveRecord model with gem improperly implemented
24
+ # returns an instance of Array instead of Criteria
25
+ class ActiveRecordInvalidScopeModel < ActiveRecordScopelessModel
26
+ def self.with_attributes_of(instance)
27
+ where(:foo => instance.foo, :bar => instance.bar).to_a
28
+ end
29
+ end
30
+ # ActiveRecord model with gem properly implemented
31
+ class ActiveRecordModel < ActiveRecordScopelessModel
32
+ def self.with_attributes_of(instance)
33
+ where(:foo => instance.foo, :bar => instance.bar)
34
+ end
35
+ end
@@ -0,0 +1,40 @@
1
+ Mongoid.configure do |config|
2
+ name = "mongoid_test"
3
+ host = "localhost"
4
+ config.master = Mongo::Connection.new.db(name)
5
+ config.logger = nil
6
+ end
7
+
8
+ RSpec.configure do |config|
9
+ config.before do
10
+ Mongoid.master.collections.select {|c| c.name !~ /system/ }.each(&:drop)
11
+ end
12
+ end
13
+
14
+ # a "vanilla" Mongoid model
15
+ class MongoidMacrolessModel
16
+ include Mongoid::Document
17
+ field :foo
18
+ field :bar
19
+ field :baz
20
+ end
21
+
22
+ # a Mongoid model with macro included, but required scope "forgotten"
23
+ class MongoidScopelessModel < MongoidMacrolessModel
24
+ validates_uniqueness :using => :with_attributes_of
25
+ end
26
+
27
+ # a Mongoid model with gem improperly implemented
28
+ # returns an instance of Array instead of Criteria
29
+ class MongoidInvalidScopeModel < MongoidScopelessModel
30
+ def self.with_attributes_of(instance)
31
+ where(:foo => instance.foo, :bar => instance.bar).to_a
32
+ end
33
+ end
34
+
35
+ # a Mongoid model with gem properly implemented
36
+ class MongoidModel < MongoidScopelessModel
37
+ def self.with_attributes_of(instance)
38
+ where(:foo => instance.foo, :bar => instance.bar)
39
+ end
40
+ end
metadata ADDED
@@ -0,0 +1,239 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dedupe
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 0
9
+ version: 0.0.0
10
+ platform: ruby
11
+ authors:
12
+ - Brent Hargrave
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-10-02 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: activesupport
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 3
29
+ - 0
30
+ - 0
31
+ version: 3.0.0
32
+ type: :runtime
33
+ prerelease: false
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: activemodel
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ~>
41
+ - !ruby/object:Gem::Version
42
+ segments:
43
+ - 3
44
+ - 0
45
+ - 0
46
+ version: 3.0.0
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: rspec
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ segments:
58
+ - 2
59
+ - 0
60
+ - 0
61
+ - beta
62
+ - 19
63
+ version: 2.0.0.beta.19
64
+ type: :development
65
+ prerelease: false
66
+ version_requirements: *id003
67
+ - !ruby/object:Gem::Dependency
68
+ name: bundler
69
+ requirement: &id004 !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ~>
73
+ - !ruby/object:Gem::Version
74
+ segments:
75
+ - 1
76
+ - 0
77
+ - 0
78
+ version: 1.0.0
79
+ type: :development
80
+ prerelease: false
81
+ version_requirements: *id004
82
+ - !ruby/object:Gem::Dependency
83
+ name: jeweler
84
+ requirement: &id005 !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ segments:
90
+ - 1
91
+ - 5
92
+ - 0
93
+ - pre3
94
+ version: 1.5.0.pre3
95
+ type: :development
96
+ prerelease: false
97
+ version_requirements: *id005
98
+ - !ruby/object:Gem::Dependency
99
+ name: rcov
100
+ requirement: &id006 !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ segments:
106
+ - 0
107
+ version: "0"
108
+ type: :development
109
+ prerelease: false
110
+ version_requirements: *id006
111
+ - !ruby/object:Gem::Dependency
112
+ name: mongoid
113
+ requirement: &id007 !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - "="
117
+ - !ruby/object:Gem::Version
118
+ segments:
119
+ - 2
120
+ - 0
121
+ - 0
122
+ - beta
123
+ - 19
124
+ version: 2.0.0.beta.19
125
+ type: :development
126
+ prerelease: false
127
+ version_requirements: *id007
128
+ - !ruby/object:Gem::Dependency
129
+ name: bson_ext
130
+ requirement: &id008 !ruby/object:Gem::Requirement
131
+ none: false
132
+ requirements:
133
+ - - "="
134
+ - !ruby/object:Gem::Version
135
+ segments:
136
+ - 1
137
+ - 0
138
+ - 9
139
+ version: 1.0.9
140
+ type: :development
141
+ prerelease: false
142
+ version_requirements: *id008
143
+ - !ruby/object:Gem::Dependency
144
+ name: activerecord
145
+ requirement: &id009 !ruby/object:Gem::Requirement
146
+ none: false
147
+ requirements:
148
+ - - ~>
149
+ - !ruby/object:Gem::Version
150
+ segments:
151
+ - 3
152
+ - 0
153
+ - 0
154
+ version: 3.0.0
155
+ type: :development
156
+ prerelease: false
157
+ version_requirements: *id009
158
+ - !ruby/object:Gem::Dependency
159
+ name: sqlite3-ruby
160
+ requirement: &id010 !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ~>
164
+ - !ruby/object:Gem::Version
165
+ segments:
166
+ - 1
167
+ - 3
168
+ - 1
169
+ version: 1.3.1
170
+ type: :development
171
+ prerelease: false
172
+ version_requirements: *id010
173
+ description: ActiveModel validation against duplicating records.
174
+ email: brent.hargrave@gmail.com
175
+ executables: []
176
+
177
+ extensions: []
178
+
179
+ extra_rdoc_files:
180
+ - LICENSE
181
+ - README.rdoc
182
+ files:
183
+ - .document
184
+ - .gitignore
185
+ - .rspec
186
+ - .rvmrc
187
+ - Gemfile
188
+ - Gemfile.lock
189
+ - LICENSE
190
+ - README.rdoc
191
+ - Rakefile
192
+ - VERSION
193
+ - lib/dedupe.rb
194
+ - lib/dedupe/errors.rb
195
+ - lib/dedupe/orm/active_record.rb
196
+ - lib/dedupe/orm/mongoid.rb
197
+ - lib/dedupe/validations.rb
198
+ - spec/dedupe_spec.rb
199
+ - spec/spec_helper.rb
200
+ - spec/support/active_record.rb
201
+ - spec/support/mongoid.rb
202
+ has_rdoc: true
203
+ homepage: http://github.com/jamescallmebrent/dedupe
204
+ licenses: []
205
+
206
+ post_install_message:
207
+ rdoc_options: []
208
+
209
+ require_paths:
210
+ - lib
211
+ required_ruby_version: !ruby/object:Gem::Requirement
212
+ none: false
213
+ requirements:
214
+ - - ">="
215
+ - !ruby/object:Gem::Version
216
+ hash: -1388205667040375508
217
+ segments:
218
+ - 0
219
+ version: "0"
220
+ required_rubygems_version: !ruby/object:Gem::Requirement
221
+ none: false
222
+ requirements:
223
+ - - ">="
224
+ - !ruby/object:Gem::Version
225
+ segments:
226
+ - 0
227
+ version: "0"
228
+ requirements: []
229
+
230
+ rubyforge_project:
231
+ rubygems_version: 1.3.7
232
+ signing_key:
233
+ specification_version: 3
234
+ summary: ActiveModel validation against duplicating records.
235
+ test_files:
236
+ - spec/dedupe_spec.rb
237
+ - spec/spec_helper.rb
238
+ - spec/support/active_record.rb
239
+ - spec/support/mongoid.rb