doppel 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 3b290250de01378cd85bbfa84e6d88dea131f38e
4
- data.tar.gz: 544c2cd1124f92bc52f5bea8bf168faadb57149f
2
+ SHA256:
3
+ metadata.gz: 9eab8343fdeee594420ed35be0b9fdd95a6680dfe399bd899456c8310ac386ab
4
+ data.tar.gz: 11f9542c95546e9a2bb20e8eba1a0d8d2a24b06d4722ebdf2ad63da6e9a880de
5
5
  SHA512:
6
- metadata.gz: 4ed29bd8764e81f9b8e264e06712e965143958f104ca24ed7808e4d4e05765643106379661f11e6da638dd126821fcbe68d1fd0716c83aeed9033bbb9390e47e
7
- data.tar.gz: a173fcd541e8d22f13d90ec35fad7e0cc2082f2ac294ad8addd0615eb5ebb13d956c76faf693af6df1a492198e9da9184f9fd782ba8adf5b7b3335b1edc784ce
6
+ metadata.gz: 3bf1e5ff91cebc1cf4f8c0ce4735af8e9b1b927fdf04bc3ea817bd92cc4cc5023857946c26c434b96e4b8493cb97b792ddfa2c2a016e68bbd49ae94ab40610ee
7
+ data.tar.gz: b517911b708968537fb4e259fe0cd4f7056cb720dff35d2028bd2b035657a3e1cff5c4ca7d8fb43806a3886199f3f01bff165ecad7499757df2b8be95a472fc7
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /build/
5
+ /_yardoc/
6
+ /coverage/
7
+ /doc/
8
+ /pkg/
9
+ /spec/reports/
10
+ /tmp/
data/.travis.yml ADDED
@@ -0,0 +1,43 @@
1
+ language: ruby
2
+ sudo: false
3
+
4
+ cache: bundler
5
+ script:
6
+ - bundle exec rspec
7
+
8
+ after_success:
9
+ - bundle exec codeclimate-test-reporter
10
+
11
+ addons:
12
+ postgresql: "9.3"
13
+
14
+ rvm:
15
+ - 2.4
16
+ - 2.3
17
+ - 2.2
18
+ - 2.1
19
+ - 2.0
20
+
21
+ gemfile:
22
+ - gemfiles/activerecord-5.1.Gemfile
23
+ - gemfiles/activerecord-5.0.Gemfile
24
+ - gemfiles/activerecord-4.2.Gemfile
25
+ - gemfiles/activerecord-4.1.Gemfile
26
+ - gemfiles/activerecord-4.0.Gemfile
27
+
28
+ matrix:
29
+ exclude:
30
+ - rvm: 2.0
31
+ gemfile: gemfiles/activerecord-5.0.Gemfile
32
+ - rvm: 2.0
33
+ gemfile: gemfiles/activerecord-5.1.Gemfile
34
+
35
+ - rvm: 2.1
36
+ gemfile: gemfiles/activerecord-5.0.Gemfile
37
+ - rvm: 2.1
38
+ gemfile: gemfiles/activerecord-5.1.Gemfile
39
+
40
+ - rvm: 2.4
41
+ gemfile: gemfiles/activerecord-4.0.Gemfile
42
+ - rvm: 2.4
43
+ gemfile: gemfiles/activerecord-4.1.Gemfile
data/Gemfile ADDED
@@ -0,0 +1,19 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+
7
+ # Generates coverage stats of specs
8
+ gem 'simplecov'
9
+
10
+ # Publishes coverage to codeclimate
11
+ gem 'codeclimate-test-reporter'
12
+
13
+ gem 'rspec'
14
+
15
+ gem 'database_cleaner'
16
+
17
+ gem 'combustion'
18
+
19
+ end
@@ -1,4 +1,6 @@
1
- Copyright 2015 Dale Stevens
1
+ Copyright (c) 2017 Dale Stevens
2
+
3
+ MIT License
2
4
 
3
5
  Permission is hereby granted, free of charge, to any person obtaining
4
6
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,78 +1,47 @@
1
- # Doppel [![Build Status](https://secure.travis-ci.org/TwilightCoders/doppel.png)](http://travis-ci.org/TwilightCoders/doppel) [![Gem Version](https://badge.fury.io/rb/doppel.png)](http://badge.fury.io/rb/doppel) [![Code Climate](https://codeclimate.com/github/TwilightCoders/doppel.png)](https://codeclimate.com/github/TwilightCoders/doppel) [![Dependency Status](https://gemnasium.com/TwilightCoders/doppel.svg)](https://gemnasium.com/TwilightCoders/doppel)
1
+ [![Version ](https://img.shields.io/gem/v/doppel.svg?maxAge=2592000)](https://rubygems.org/gems/doppel)
2
+ [![Build Status ](https://travis-ci.org/TwilightCoders/doppel.svg)](https://travis-ci.org/TwilightCoders/doppel)
3
+ [![Code Climate ](https://api.codeclimate.com/v1/badges/427b6d065c1b772cecfb/maintainability)](https://codeclimate.com/github/TwilightCoders/doppel/maintainability)
4
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/427b6d065c1b772cecfb/test_coverage)](https://codeclimate.com/github/TwilightCoders/doppel/test_coverage)
5
+ [![Dependencies ](https://gemnasium.com/badges/github.com/TwilightCoders/doppel.svg)](https://gemnasium.com/github.com/TwilightCoders/doppel)
2
6
 
3
- ## Description
7
+ # Doppel
4
8
 
5
- This `acts_as` extension provides the ability to find similar records matching a set of specified fuzzy matched fields.
9
+ Doppel provides convenience scopes on your ActiveRecord Models for finding similar or exact records.
6
10
 
7
- ## Requirements
11
+ Compatible with ActiveRecord `4.0`, `4.1`, `4.2`, `5.0`, `5.1`
8
12
 
9
- The database engine currently must impliment the [`levenshtein`](http://www.postgresql.org/docs/9.4/static/fuzzystrmatch.html) extension/feature. I believe this is currently limited to PostgreSQL.
13
+ ## Usage
10
14
 
11
- ## Installation
12
-
13
- In your Gemfile:
15
+ Add this line to your application's Gemfile:
14
16
 
15
17
  gem 'doppel'
16
18
 
17
- Or, from the command line:
19
+ And then execute:
18
20
 
19
- gem install doppel
21
+ $ bundle
20
22
 
21
- ## Example
23
+ Or install it yourself as:
22
24
 
23
- To use, call `has_many_doppels` method in the model:
25
+ $ gem install doppel
24
26
 
25
- ```ruby
26
- class Company < ActiveRecord::Base
27
- has_many_doppels [:name]
28
- end
27
+ ### Application Code
29
28
 
30
- [1] pry(main)> duplicates = Company.with_name_doppels
31
- Company Load (89586.2ms) SELECT DISTINCT companies.* FROM companies, companies as doppel_companies WHERE (companies.id != doppel_companies.id) AND (levenshtein(companies.name, doppel_companies.name) < 2) GROUP BY companies.id HAVING COUNT(doppel_companies.id) > 0
32
- Company Load (89586.2ms) SELECT DISTINCT companies.* FROM companies, companies as doppel_companies WHERE (companies.id != doppel_companies.id) AND (levenshtein(companies.name, doppel_companies.name) < 2) GROUP BY companies.id HAVING COUNT(doppel_companies.id) > 0
33
- => [#<Company:0x007fe486a84a18 id: 4332, type: "Company", name: "Basically Infinity", created_at: ..., updated_at: ... >,
34
- #<Company:0x007fe485e70010 id: 5179, type: "Company", name: "Stucco", created_at: ..., updated_at: ... >,
35
- #<Company:0x007fe485e6b5d8 id: 3234, type: "Company", name: "ÜSER", created_at: ..., updated_at: ... >,
36
- #<Company:0x007fe485e6aae8 id: 8456, type: "Company", name: "Orange", created_at: ..., updated_at: ... >]
29
+ Doppel is automatically available to your ActiveRecord Models
37
30
 
38
- # From here you'll be able to do the following.
31
+ ```ruby
39
32
 
40
- [2] pry(main)> duplicates.first.name_doppels
41
- Company Load (13.1ms) SELECT "companies".* FROM "companies" WHERE (levenshtein('Basically Infinity', companies.name) < 2) AND ("companies"."id" != $1) [["id", 4332]]
42
- Company Load (13.1ms) SELECT "companies".* FROM "companies" WHERE (levenshtein('Basically Infinity', companies.name) < 2) AND ("companies"."id" != $1) [["id", 4332]]
43
- => [#<Company:0x007fe483464a00 id: 4057, type: "Company", name: "Interim Physicians", created_at: ..., updated_at: ... >]
33
+ class User < Account
34
+ # ...
35
+ end
44
36
 
37
+ User.find_similar(:name)
45
38
  ```
46
39
 
47
- ## Instance Methods Added To ActiveRecord Models
48
-
49
- You'll have a number of methods added to each instance of the ActiveRecord model that to which `doppel` is added.
50
-
51
- These depend on how `has_many_doppels` is configured. For each field that is supplied, you'll have
52
-
53
- `#{field_name}_doppels`
54
-
55
- in addition to
56
-
57
- `doppels`
58
-
59
- which will return any matching duplicates from all fields supplied.
60
-
61
- ## The Future
62
-
63
- Currently `doppel` only supports `levenshtein` text searching. I have tentative plans to impliment a more modular framework and support other field types such as dates or numerics.
64
-
65
- ## Contributing to `doppel`
66
-
67
- - Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
68
- - Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
69
- - Fork the project
70
- - Start a feature/bugfix branch
71
- - Commit and push until you are happy with your contribution
72
- - Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
73
- - Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
74
- - I would recommend using Rails 3.1.x and higher for testing the build before a pull request. The current test harness does not quite work with 3.0.x. The plugin itself works, but the issue lies with testing infrastructure.
75
40
 
76
- ## Copyright
41
+ ## Contributing
77
42
 
78
- Copyright (c) 2015 Dale Stevens, released under the MIT license
43
+ 1. Fork it ( https://github.com/TwilightCoders/active_record-mti/fork )
44
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
45
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
46
+ 4. Push to the branch (`git push origin my-new-feature`)
47
+ 5. Create a new Pull Request
data/Rakefile CHANGED
@@ -1,30 +1,6 @@
1
- begin
2
- require 'bundler/setup'
3
- rescue LoadError
4
- puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
- end
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
6
3
 
7
- require 'rdoc/task'
4
+ RSpec::Core::RakeTask.new
8
5
 
9
- RDoc::Task.new(:rdoc) do |rdoc|
10
- rdoc.rdoc_dir = 'rdoc'
11
- rdoc.title = 'Doppel'
12
- rdoc.options << '--line-numbers'
13
- rdoc.rdoc_files.include('README.md')
14
- rdoc.rdoc_files.include('lib/**/*.rb')
15
- end
16
-
17
-
18
- Bundler::GemHelper.install_tasks
19
-
20
- require 'rake/testtask'
21
-
22
- Rake::TestTask.new(:test) do |t|
23
- t.libs << 'lib'
24
- t.libs << 'test'
25
- t.pattern = 'test/**/*_test.rb'
26
- t.verbose = false
27
- end
28
-
29
-
30
- task default: :test
6
+ task default: :spec
data/doppel.gemspec ADDED
@@ -0,0 +1,40 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'doppel/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "doppel"
8
+ spec.version = Doppel::VERSION
9
+ spec.authors = ["Dale Stevens"]
10
+ spec.email = ["dale@twilightcoders.net"]
11
+
12
+ spec.summary = %q{Find exact and similar records}
13
+ # spec.description = %q{Gives ActiveRecord support for PostgreSQL's native inherited tables}
14
+ spec.homepage = "https://github.com/twilightcoders/doppel"
15
+ spec.license = "MIT"
16
+
17
+ if spec.respond_to?(:metadata)
18
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
19
+ else
20
+ raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.'
21
+ end
22
+
23
+ spec.files = `git ls-files -z`.split("\x0")
24
+ spec.bindir = 'bin'
25
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
26
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
27
+ spec.require_paths = ['lib', 'spec']
28
+
29
+ rails_versions = ['>= 4', '< 6']
30
+ spec.required_ruby_version = '>= 2.0'
31
+
32
+ spec.add_runtime_dependency 'pg', '~> 0'
33
+ spec.add_runtime_dependency 'activerecord', rails_versions
34
+
35
+ spec.add_development_dependency 'pry-byebug', '~> 3'
36
+ spec.add_development_dependency 'bundler', '~> 1.3'
37
+ spec.add_development_dependency 'rake', '~> 12.0'
38
+ spec.add_development_dependency 'combustion', '~> 0.7'
39
+
40
+ end
@@ -0,0 +1,3 @@
1
+ eval_gemfile File.join(File.dirname(__FILE__), "../Gemfile")
2
+
3
+ gem 'activerecord', '~> 4.0.0'
@@ -0,0 +1,3 @@
1
+ eval_gemfile File.join(File.dirname(__FILE__), "../Gemfile")
2
+
3
+ gem 'activerecord', '~> 4.1.0'
@@ -0,0 +1,3 @@
1
+ eval_gemfile File.join(File.dirname(__FILE__), "../Gemfile")
2
+
3
+ gem 'activerecord', '~> 4.2.0'
@@ -0,0 +1,3 @@
1
+ eval_gemfile File.join(File.dirname(__FILE__), "../Gemfile")
2
+
3
+ gem 'activerecord', '~> 5.0.0'
@@ -0,0 +1,3 @@
1
+ eval_gemfile File.join(File.dirname(__FILE__), "../Gemfile")
2
+
3
+ gem 'activerecord', '~> 5.1.0'
@@ -0,0 +1,42 @@
1
+ module Doppel
2
+ # == Multi-Table Inheritance
3
+ module ActiveRecord
4
+ module Base
5
+
6
+ def self.prepended(base)
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ module ClassMethods
11
+ def inherited(subclass)
12
+ super
13
+
14
+ return unless subclass.respond_to?(:scope)
15
+
16
+ subclass.class_eval do
17
+ scope :find_similar, -> (column, sensitivity: 2.0, count: 0, debug: false) do
18
+ at1 = arel_table
19
+ at2 = at1.alias
20
+ lev = Arel::Nodes::NamedFunction.new("levenshtein", [at1[column.to_sym], at2[column.to_sym]])
21
+
22
+ selects = [at1[Arel.star]]
23
+ selects << lev.clone.as('lev') if debug
24
+
25
+ select(selects).
26
+ where(at1[primary_key].not_eq(at2[primary_key])).
27
+ where(lev.lteq(sensitivity)).
28
+ from([at1, at2]).
29
+ group(at1[primary_key], at1[column.to_sym], at2[column.to_sym]).
30
+ having(at1[primary_key].count.gt(count)).distinct(at1[Arel.star])
31
+ end
32
+
33
+ scope :find_exact, -> (column, count: 0) do
34
+ find_similar(column, sensitivity: 0, count: count)
35
+ end
36
+ end
37
+
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,13 @@
1
+ require 'rails/railtie'
2
+
3
+ module Doppel
4
+ class Railtie < Rails::Railtie
5
+ initializer 'doppel.load' do |_app|
6
+ Doppel.logger.debug "active_record-mti.load"
7
+ ActiveSupport.on_load(:active_record) do
8
+ Doppel.load
9
+ end
10
+ end
11
+ end
12
+ end
13
+
@@ -1,3 +1,3 @@
1
1
  module Doppel
2
- VERSION = '0.0.1'
2
+ VERSION = '0.1.0'
3
3
  end
data/lib/doppel.rb CHANGED
@@ -1,6 +1,27 @@
1
- require 'doppel/acts_as_doppel'
1
+ require 'doppel/version'
2
+
3
+ require 'doppel/active_record/base'
4
+ require 'doppel/railtie' if defined?(Rails::Railtie)
2
5
 
3
6
  module Doppel
4
- end
5
7
 
6
- ActiveRecord::Base.send :include, Doppel::ActsAsDoppel
8
+ class << self
9
+ attr_writer :logger
10
+
11
+ def logger
12
+ @logger ||= Logger.new($stdout).tap do |log|
13
+ log.progname = self.name
14
+ log.level = Logger::INFO
15
+ end
16
+ end
17
+ end
18
+
19
+ def self.root
20
+ @root ||= Pathname.new(File.expand_path('../../', File.dirname(__FILE__)))
21
+ end
22
+
23
+ def self.load
24
+ ::ActiveRecord::Base.send :prepend, ActiveRecord::Base
25
+ end
26
+
27
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ describe Doppel::ActiveRecord::Base do
4
+
5
+ context '#find_similar' do
6
+ it "emails" do
7
+
8
+ User.create(name: "John Doe", email: 'foo@bar.baz')
9
+ User.create(name: "John Deer", email: 'foo@bar.baz')
10
+ User.create(name: "Dear John", email: 'bar24@foo.baz')
11
+
12
+ similar_users = User.find_similar(:email).to_a
13
+
14
+ expect(similar_users.count).to eq(2)
15
+ end
16
+
17
+ it "names" do
18
+
19
+ User.create(name: "John Deer", email: 'foo@bar.baz')
20
+ User.create(name: "John Dear", email: 'foo1@bar.baz')
21
+ User.create(name: "Dear John", email: 'bar24@foo.baz')
22
+
23
+ similar_users = User.find_similar(:name).to_a
24
+
25
+ expect(similar_users.count).to eq(2)
26
+ end
27
+ end
28
+
29
+ context '#find_exact' do
30
+ it "emails" do
31
+
32
+ User.create(name: "John Doe", email: 'foo@bar.baz')
33
+ User.create(name: "John Deer", email: 'foo@bar.baz')
34
+ User.create(name: "Dear John", email: 'bar24@foo.baz')
35
+
36
+ exact_users = User.find_exact(:email).to_a
37
+
38
+ expect(exact_users.count).to eq(2)
39
+ end
40
+
41
+ it "names" do
42
+
43
+ User.create(name: "John Deer", email: 'foo@bar.baz')
44
+ User.create(name: "John Deer", email: 'foo1@bar.baz')
45
+ User.create(name: "Dear John", email: 'bar24@foo.baz')
46
+
47
+ exact_users = User.find_exact(:name).to_a
48
+
49
+ expect(exact_users.count).to eq(2)
50
+ end
51
+ end
52
+
53
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe Doppel do
4
+
5
+ context 'helper' do
6
+
7
+ it "root has the right value" do
8
+ expect(Doppel.root).not_to be_nil
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,29 @@
1
+ ENV['RAILS_ENV'] = 'test'
2
+
3
+ require 'pry'
4
+ require 'database_cleaner'
5
+ require 'combustion'
6
+
7
+ require 'simplecov'
8
+ SimpleCov.start do
9
+ add_filter 'spec'
10
+ end
11
+
12
+ Combustion.path = 'spec/support/rails'
13
+ Combustion.initialize! :active_record
14
+
15
+ RSpec.configure do |config|
16
+ config.order = 'random'
17
+
18
+ # Configure the DatabaseCleaner
19
+ config.before(:suite) do
20
+ DatabaseCleaner.strategy = :transaction
21
+ DatabaseCleaner.clean_with(:truncation)
22
+ end
23
+
24
+ config.around(:each) do |example|
25
+ DatabaseCleaner.cleaning do
26
+ example.run
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,6 @@
1
+ class User < ::ActiveRecord::Base
2
+
3
+ has_many :posts
4
+ has_many :comments
5
+
6
+ end
@@ -0,0 +1,4 @@
1
+ test:
2
+ adapter: postgresql
3
+ encoding: unicode
4
+ database: doppel-test
@@ -0,0 +1,3 @@
1
+ Rails.application.routes.draw do
2
+ #
3
+ end
@@ -0,0 +1,13 @@
1
+ ActiveRecord::Schema.define do
2
+
3
+ enable_extension "fuzzystrmatch"
4
+
5
+ self.verbose = false
6
+
7
+ create_table :users do |t|
8
+ t.string :name, index: :btree
9
+ t.string :email, index: :btree
10
+ t.timestamps null: false
11
+ end
12
+
13
+ end
@@ -0,0 +1 @@
1
+ *.log
File without changes
metadata CHANGED
@@ -1,72 +1,152 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: doppel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dale Stevens
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-27 00:00:00.000000000 Z
11
+ date: 2017-12-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rails
14
+ name: pg
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '4.2'
19
+ version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '4.2'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: sqlite3
28
+ name: activerecord
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :development
33
+ version: '4'
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '6'
37
+ type: :runtime
35
38
  prerelease: false
36
39
  version_requirements: !ruby/object:Gem::Requirement
37
40
  requirements:
38
41
  - - ">="
39
42
  - !ruby/object:Gem::Version
40
- version: '0'
41
- description: Provides convenient scopes for finding duplicate records.
43
+ version: '4'
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '6'
47
+ - !ruby/object:Gem::Dependency
48
+ name: pry-byebug
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '3'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '3'
61
+ - !ruby/object:Gem::Dependency
62
+ name: bundler
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '1.3'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '1.3'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rake
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '12.0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '12.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: combustion
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '0.7'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '0.7'
103
+ description:
42
104
  email:
43
105
  - dale@twilightcoders.net
44
106
  executables: []
45
107
  extensions: []
46
108
  extra_rdoc_files: []
47
109
  files:
48
- - MIT-LICENSE
110
+ - ".gitignore"
111
+ - ".travis.yml"
112
+ - Gemfile
113
+ - LICENSE.txt
49
114
  - README.md
50
115
  - Rakefile
116
+ - doppel.gemspec
117
+ - gemfiles/activerecord-4.0.Gemfile
118
+ - gemfiles/activerecord-4.1.Gemfile
119
+ - gemfiles/activerecord-4.2.Gemfile
120
+ - gemfiles/activerecord-5.0.Gemfile
121
+ - gemfiles/activerecord-5.1.Gemfile
51
122
  - lib/doppel.rb
52
- - lib/doppel/acts_as_doppel.rb
123
+ - lib/doppel/active_record/base.rb
124
+ - lib/doppel/railtie.rb
53
125
  - lib/doppel/version.rb
54
- - lib/tasks/doppel_tasks.rake
55
- - test/doppel_test.rb
56
- - test/test_helper.rb
57
- homepage: http://github.com/TwilightCoders/doppel
126
+ - spec/doppel/active_record/base_spec.rb
127
+ - spec/doppel/doppel_spec.rb
128
+ - spec/spec_helper.rb
129
+ - spec/support/rails/app/models/user.rb
130
+ - spec/support/rails/config/database.yml
131
+ - spec/support/rails/config/routes.rb
132
+ - spec/support/rails/db/schema.rb
133
+ - spec/support/rails/log/.gitignore
134
+ - spec/support/rails/public/favicon.ico
135
+ homepage: https://github.com/twilightcoders/doppel
58
136
  licenses:
59
137
  - MIT
60
- metadata: {}
138
+ metadata:
139
+ allowed_push_host: https://rubygems.org
61
140
  post_install_message:
62
141
  rdoc_options: []
63
142
  require_paths:
64
143
  - lib
144
+ - spec
65
145
  required_ruby_version: !ruby/object:Gem::Requirement
66
146
  requirements:
67
147
  - - ">="
68
148
  - !ruby/object:Gem::Version
69
- version: '0'
149
+ version: '2.0'
70
150
  required_rubygems_version: !ruby/object:Gem::Requirement
71
151
  requirements:
72
152
  - - ">="
@@ -74,10 +154,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
74
154
  version: '0'
75
155
  requirements: []
76
156
  rubyforge_project:
77
- rubygems_version: 2.4.5
157
+ rubygems_version: 2.7.0
78
158
  signing_key:
79
159
  specification_version: 4
80
- summary: Provides convenient scopes for finding duplicate records.
160
+ summary: Find exact and similar records
81
161
  test_files:
82
- - test/doppel_test.rb
83
- - test/test_helper.rb
162
+ - spec/doppel/active_record/base_spec.rb
163
+ - spec/doppel/doppel_spec.rb
164
+ - spec/spec_helper.rb
165
+ - spec/support/rails/app/models/user.rb
166
+ - spec/support/rails/config/database.yml
167
+ - spec/support/rails/config/routes.rb
168
+ - spec/support/rails/db/schema.rb
169
+ - spec/support/rails/log/.gitignore
170
+ - spec/support/rails/public/favicon.ico
@@ -1,52 +0,0 @@
1
- module Doppel
2
- module ActsAsDoppel
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- end
7
-
8
- module ClassMethods
9
- def has_many_doppels(fields = [], options = {})
10
- options = Doppel::ActsAsDoppel.merge_default_options(options)
11
- other_table_name = "doppel_#{table_name}"
12
- table_name_key = "#{table_name}.#{primary_key}"
13
- other_table_name_key = "#{other_table_name}.#{primary_key}"
14
- fields.each do |field|
15
- class_eval <<-END, __FILE__, __LINE__ + 1
16
- scope "with_#{field}_doppels", lambda { |count = #{options[:count]}, lev = #{options[:sensitivity]}|
17
- select("DISTINCT #{table_name}.*")
18
- .where("#{table_name_key} != #{other_table_name_key}")
19
- .where("levenshtein(#{table_name}.#{field}, #{other_table_name}.#{field}) < \#\{lev\}")
20
- .from("#{table_name}, #{table_name} as #{other_table_name}")
21
- .group(table_name_key).having("COUNT(#{other_table_name_key}) > \#\{count\}")
22
- }
23
-
24
- def #{field}_doppels
25
- @#{field}_doppels ||= self.where("levenshtein(\#\{self.sanitize(#{field})\}, #{table_name}.#{field}) < 2").where.not(#{primary_key}: #{primary_key})
26
- end
27
- END
28
- # scope "with_#{field}_doppels", lambda { |count = options[:count], lev = options[:sensitivity]|
29
- # select("DISTINCT #{table_name}.*")
30
- # .where("#{table_name_key} != #{other_table_name_key}")
31
- # .where("levenshtein(#{table_name}.#{field}, #{other_table_name}.#{field}) < #{lev}")
32
- # .from("#{table_name}, #{table_name} as #{other_table_name}")
33
- # .group(table_name_key).having("COUNT(#{other_table_name_key}) > #{count}")
34
- # }
35
- end
36
-
37
- # scope 'with_any_doppels', lambda { |count = options[:count], lev = options[:sensitivity]|
38
- # fields.inject(self) { |query, field| query.merge(send("with_#{field}_doppels")) }
39
- # }
40
-
41
- # alias_method 'with_dopels', "with_#{fields.first}_doppels" if fields.one?
42
- end
43
- end
44
-
45
- def self.merge_default_options(options = {})
46
- {
47
- sensitivity: 2,
48
- count: 0
49
- }.merge(options)
50
- end
51
- end
52
- end
@@ -1,4 +0,0 @@
1
- # desc "Explaining what the task does"
2
- # task :doppel do
3
- # # Task goes here
4
- # end
data/test/doppel_test.rb DELETED
@@ -1,7 +0,0 @@
1
- require 'test_helper'
2
-
3
- class DoppelTest < ActiveSupport::TestCase
4
- test "truth" do
5
- assert_kind_of Module, Doppel
6
- end
7
- end
data/test/test_helper.rb DELETED
@@ -1,19 +0,0 @@
1
- # Configure Rails Environment
2
- ENV["RAILS_ENV"] = "test"
3
-
4
- require File.expand_path("../../test/dummy/config/environment.rb", __FILE__)
5
- ActiveRecord::Migrator.migrations_paths = [File.expand_path("../../test/dummy/db/migrate", __FILE__)]
6
- require "rails/test_help"
7
-
8
- # Filter out Minitest backtrace while allowing backtrace from other libraries
9
- # to be shown.
10
- Minitest.backtrace_filter = Minitest::BacktraceFilter.new
11
-
12
- # Load support files
13
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
14
-
15
- # Load fixtures from the engine
16
- if ActiveSupport::TestCase.respond_to?(:fixture_path=)
17
- ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
18
- ActiveSupport::TestCase.fixtures :all
19
- end