Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
Gemfile.lock
pkg/*
.DS_Store
gemfiles/*.gemfile.lock
20 changes: 11 additions & 9 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
language: ruby

rvm:
- 1.9.3
- 2.0.0
- 2.1.0
- 2.1.1

gemfile:
- Gemfile
matrix:
include:
- rvm: 2.5.7
gemfile: gemfiles/mongoid_7.gemfile
- rvm: 2.5.7
gemfile: gemfiles/mongoid_6.gemfile
- rvm: 2.5.7
gemfile: gemfiles/mongoid_6_rails_5.1.gemfile

services:
- mongodb

env:
- CODECLIMATE_REPO_TOKEN=b216164ab66da464aa02fe5b862811ba0526c8dc7ea291ebe53056be4b6b5e1f

script: "bundle exec rspec"
script:
- bundle exec rspec
- bundle exec codeclimate-test-reporter
12 changes: 12 additions & 0 deletions Appraisals
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
appraise 'mongoid-7' do
gem 'mongoid', '~> 7.0'
end

appraise 'mongoid-6' do
gem 'mongoid', '~> 6.0'
end

appraise 'mongoid-6-rails-5.1' do
gem 'mongoid', '~> 6.0'
gem 'rails', '~> 5.1'
end
6 changes: 3 additions & 3 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ source "http://rubygems.org"
gemspec

group :test do
gem 'rspec', '2.14.1'
gem "codeclimate-test-reporter", require: nil
gem 'database_cleaner'
gem 'mongoid-rspec', '1.5.1'
gem "database_cleaner"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bundler/OrderedGems: Gems should be sorted in an alphabetical order within their section of the Gemfile. Gem database_cleaner should appear before rspec.

gem "mongoid-rspec"
gem "rspec"
end
34 changes: 19 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ gem 'mongoid_token', '~> 3.0.0'

# For mongoid >= 5
gem 'mongoid_token', '~> 4.0.0'

# For mongoid >= 6
gem 'mongoid_token', '~> 5.0.0'
```

Then update your bundle
Expand Down Expand Up @@ -101,8 +104,8 @@ This one is easy, it's just an integer.
__Example:__

```ruby
token :length => 6 # Tokens are now of length 6
token :length => 12 # Whow, whow, whow. Slow down egghead.
token length: 6 # Tokens are now of length 6
token length: 12 # Whow, whow, whow. Slow down egghead.
```

You get the idea.
Expand Down Expand Up @@ -130,8 +133,8 @@ never start with zeros

__Examples:__
```ruby
token :contains => :alpha_upper, :length => 8
token :contains => :fixed_numeric
token contains: :alpha_upper, length: 8
token contains: :fixed_numeric
```

#### Patterns (`:pattern`)
Expand Down Expand Up @@ -160,7 +163,7 @@ generated character, and are as follows:
__Example:__

```ruby
token :pattern => "PRE-%C%C-%d%d%d%d" # Generates something like: 'PRE-ND-3485'
token pattern: "PRE-%C%C-%d%d%d%d" # Generates something like: 'PRE-ND-3485'
```

You can also add a repetition modifier, which can help improve readability on
Expand All @@ -169,7 +172,7 @@ more complex patterns. You simply add any integer after the letter.
__Examples:__

```ruby
token :pattern => "APP-%d6" # Generates something like; "APP-638924"
token pattern: "APP-%d6" # Generates something like; "APP-638924"
```

### Field Name (`:field_name`)
Expand All @@ -180,9 +183,9 @@ use multiple tokens one a single document.

__Examples:__
```ruby
token :length => 6
token :field_name => :sharing_token, :length => 12
token :field_name => :yet_another
token length: 6
token field_name: :sharing_token, length: 12
token field_name: :yet_another
```


Expand All @@ -192,7 +195,7 @@ This will prevent the gem from creating the extra `find_by_*` methods.

__Example:__
```ruby
token :skip_finders => true
token skip_finders: true
```


Expand All @@ -204,7 +207,7 @@ this behaviour off:

__Example:__
```ruby
token :override_to_param => false
token override_to_param: false
```


Expand All @@ -217,8 +220,8 @@ option is for you.

__Examples:__
```ruby
token :retry_count => 9
token :retry_count => 0
token retry_count: 9
token retry_count: 0
```

# Notes
Expand All @@ -238,5 +241,6 @@ In particular: [olliem](https://github.com/olliem),
[msolli](https://github.com/msolli),
[siong1987](https://github.com/siong1987),
[stephan778](https://github.com/stephan778),
[eagleas](https://github.com/eagleas), and
[jamesotron](https://github.com/jamesotron).
[eagleas](https://github.com/eagleas),
[jamesotron](https://github.com/jamesotron), and
[ritxi](https://github.com/ritxi).
14 changes: 14 additions & 0 deletions gemfiles/mongoid_6.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# This file was generated by Appraisal

source "http://rubygems.org"

gem "mongoid", "~> 6.0"

group :test do
gem "codeclimate-test-reporter", require: nil
gem "database_cleaner"
gem "mongoid-rspec"
gem "rspec"
end

gemspec path: "../"
15 changes: 15 additions & 0 deletions gemfiles/mongoid_6_rails_5.1.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# This file was generated by Appraisal

source "http://rubygems.org"

gem "mongoid", "~> 6.0"
gem "rails", "~> 5.1"

group :test do
gem "codeclimate-test-reporter", require: nil
gem "database_cleaner"
gem "mongoid-rspec"
gem "rspec"
end

gemspec path: "../"
14 changes: 14 additions & 0 deletions gemfiles/mongoid_7.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# This file was generated by Appraisal

source "http://rubygems.org"

gem "mongoid", "~> 7.0"

group :test do
gem "codeclimate-test-reporter", require: nil
gem "database_cleaner"
gem "mongoid-rspec"
gem "rspec"
end

gemspec path: "../"
33 changes: 20 additions & 13 deletions lib/mongoid/token.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
require 'mongoid/token/exceptions'
require 'mongoid/token/options'
require 'mongoid/token/generator'
require 'mongoid/token/finders'
require 'mongoid/token/collision_resolver'
# frozen_string_literal: true

module Mongoid
module Token
Expand All @@ -25,17 +21,26 @@ def token(*args)
override_to_param(options) if options.override_to_param?
end

def resolvers
@resolvers
end

private

def add_token_field_and_index(options)
self.field options.field_name, :type => String, :default => default_value(options)
self.index({ options.field_name => 1 }, { :unique => true, :sparse => true })
field options.field_name, type: String, default: default_value(options)
index({ options.field_name => 1 }, unique: true, sparse: true)
end

def add_token_collision_resolver(options)
resolver = Mongoid::Token::CollisionResolver.new(self, options.field_name, options.retry_count)
@resolvers ||= []
resolver = Mongoid::Token::CollisionResolver.new(
self, options.field_name, options.retry_count
)
resolver.create_new_token = Proc.new do |document|
document.send(:create_token, options.field_name, options.pattern)
end
@resolvers.push(resolver)
end

def define_custom_finders(options)
Expand All @@ -53,24 +58,26 @@ def set_token_callbacks(options)
end

def override_to_param(options)
self.send(:define_method, :to_param) do
self.send(options.field_name) || super()
send(:define_method, :to_param) do
send(options.field_name) || super()
end
end

def default_value(options)
options.generate_on_init && Mongoid::Token::Generator.generate(options.pattern) || nil
options.generate_on_init &&
Mongoid::Token::Generator.generate(options.pattern) || nil
end
end

protected

def create_token(field_name, pattern)
self.send :"#{field_name.to_s}=", self.generate_token(pattern)
send :"#{field_name}=", generate_token(pattern)
end

def create_token_if_nil(field_name, pattern)
if self[field_name.to_sym].blank?
self.create_token field_name, pattern
create_token field_name, pattern
end
end

Expand Down
32 changes: 17 additions & 15 deletions lib/mongoid/token/collision_resolver.rb
Original file line number Diff line number Diff line change
@@ -1,37 +1,39 @@
require 'mongoid/token/collisions'
# frozen_string_literal: true

module Mongoid
module Token
module SafeOperationsHandler
def insert(options = {})
safe_operation { super(options) }
end

def upsert(options = {})
safe_operation { super(options) }
end

def safe_operation(&block)
resolve_token_collisions { with(write: { w: 1 }, &block) }
end
end

class CollisionResolver
attr_accessor :create_new_token
attr_reader :klass
attr_reader :field_name
attr_reader :retry_count

def initialize(klass, field_name, retry_count)
@create_new_token = Proc.new {|doc|}
@create_new_token = proc { |doc| }
@klass = klass
@field_name = field_name
@retry_count = retry_count
klass.send(:include, Mongoid::Token::Collisions)
alias_method_with_collision_resolution(:insert)
alias_method_with_collision_resolution(:upsert)
klass.send(:prepend, SafeOperationsHandler)
end

def create_new_token_for(document)
@create_new_token.call(document)
end

private
def alias_method_with_collision_resolution(method)
handler = self
klass.send(:define_method, :"#{method.to_s}_with_#{handler.field_name}_safety") do |method_options = {}|
self.resolve_token_collisions handler do
with(:safe => true).send(:"#{method.to_s}_without_#{handler.field_name}_safety", method_options)
end
end
klass.alias_method_chain method.to_sym, :"#{handler.field_name}_safety"
end
end
end
end
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
# frozen_string_literal: true

module Mongoid
module Token
class Error < StandardError; end

class CollisionRetriesExceeded < Error
def initialize(resource = "unknown resource", attempts = "unspecified")
@resource = resource
@attempts = attempts
end

def to_s
"Failed to generate unique token for #{@resource} after #{@attempts} attempts."
"Failed to generate unique token for #{@resource} after #{@attempts} "\
"attempts."
end
end
end
Expand Down
Loading