validates_duplicity_of 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 01d0732a53d7733346abb9126487f5e2cf13b478
4
+ data.tar.gz: c672292cedde949a2a10e449f087f1b5bc282c4e
5
+ SHA512:
6
+ metadata.gz: c05fd1101e362a516e674764c37efe36e3fb4b10ffcedf16b08b91e9f3c464eecd199caac12eaecdcde56afd18f925cd047511d186671319acfd35867194f642
7
+ data.tar.gz: 918bba5b2e531a1aa1ab74dba6e1ef5dd258a003b2d5280f8f51187f4cf81ca0742d7108f5362ff44a46ae460b8f35dbeae5fd2ffc6da50852f77c4c485154b9
checksums.yaml.gz.sig ADDED
Binary file
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .DS_Store
19
+ *.sqlite3
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in validates_duplicity_of.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Vincent Durand
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # validates_duplicity_of
2
+
3
+ ActiveRecord (>= 3) callback which handle the name duplication in your model with ease.
4
+ Ruby 2 only!
5
+
6
+ **Example :**
7
+
8
+ Untilted File > Untilted File (1) > Untilted File (2) …
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ gem 'validates_duplicity_of'
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install validates_duplicity_of
23
+
24
+ ## Usage
25
+
26
+ Use method `validates_duplicity_of` with attribute in your Rails model. Scope is optional.
27
+
28
+ class Post
29
+ validates_duplicity_of :name, scope: :user_id
30
+ end
31
+
32
+ p = Post.create name: "Foo", user_id: 1
33
+ p.name
34
+ => "Foo"
35
+
36
+ p = Post.create name: "Foo", user_id: 1
37
+ p.name
38
+ => "Foo (1)"
39
+
40
+
41
+ ## Contributing
42
+
43
+ 1. Fork it
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 new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,3 @@
1
+ module ValidatesDuplicityOf
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,19 @@
1
+ require 'validates_duplicity_of/version'
2
+ require 'active_record'
3
+
4
+ module ValidatesDuplicityOf
5
+ def validates_duplicity_of(attr_name, scope: nil)
6
+ before_save do
7
+ return unless changed.include? attr_name.to_s
8
+ if self.class.exists?(Hash[*[attr_name, self[attr_name], scope, self[scope]].compact])
9
+ realtion = scope ? self.class.where(Hash[*[scope, self[scope]]]) : self.class
10
+ names = realtion.where(self.class.arel_table[attr_name].matches("#{self[attr_name]} (%)")).pluck(attr_name)
11
+ name_ids = names.map{ |name| name.match(/\((\d+)\)$/)[1].to_i }
12
+ index = name_ids.sort.last.to_i + 1
13
+ self[attr_name].concat " (#{index})"
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ ActiveRecord::Base.extend ValidatesDuplicityOf
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe "validates_duplicity_of" do
4
+ context "without scope" do
5
+ before(:each) { Post.create name: "New name" }
6
+ after(:each) { Post.delete_all }
7
+
8
+ it "should update name if post already exists" do
9
+ 10.times do |index|
10
+ post = Post.create name: "New name"
11
+ expect(post.name).to eq "New name (#{index + 1})"
12
+ end
13
+ end
14
+
15
+ it "should update name with last index" do
16
+ Post.create name: "New name (5)"
17
+ post = Post.create name: "New name"
18
+ expect(post.name).to eq "New name (6)"
19
+ end
20
+
21
+ it "should not update name if post as the same name" do
22
+ post = Post.create name: "New name"
23
+ expect(post.name).to eq "New name (1)"
24
+ post.update_attributes name: "New name (1)"
25
+ expect(post.name).to eq "New name (1)"
26
+ end
27
+
28
+ it "should update name with already indexed name" do
29
+ post = Post.create name: "New name"
30
+ expect(post.name).to eq "New name (1)"
31
+ 10.times do |index|
32
+ post = Post.create name: "New name (1)"
33
+ expect(post.name).to eq "New name (1) (#{index + 1})"
34
+ end
35
+ end
36
+ end
37
+
38
+ context "with scope" do
39
+ before(:each) do
40
+ Note.create title: "New title", user_id: 1
41
+ Note.create title: "New title", user_id: 2
42
+ end
43
+ after(:each) { Note.delete_all }
44
+
45
+ it "should update title if note already exists" do
46
+ 10.times do |index|
47
+ note = Note.create title: "New title", user_id: 1
48
+ expect(note.title).to eq "New title (#{index + 1})"
49
+ note = Note.create title: "New title", user_id: 2
50
+ expect(note.title).to eq "New title (#{index + 1})"
51
+ end
52
+ end
53
+
54
+ it "should update title with last index" do
55
+ Note.create title: "New title (5)", user_id: 1
56
+ note = Note.create title: "New title", user_id: 1
57
+ expect(note.title).to eq "New title (6)"
58
+ Note.create title: "New title (10)", user_id: 2
59
+ note = Note.create title: "New title", user_id: 2
60
+ expect(note.title).to eq "New title (11)"
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,7 @@
1
+ require 'validates_duplicity_of'
2
+ require 'active_record'
3
+
4
+ ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: File.dirname(__FILE__) + "/validates_duplicity_of.sqlite3")
5
+
6
+ load File.dirname(__FILE__) + '/support/schema.rb'
7
+ load File.dirname(__FILE__) + '/support/models.rb'
@@ -0,0 +1,7 @@
1
+ class Post < ActiveRecord::Base
2
+ validates_duplicity_of :name
3
+ end
4
+
5
+ class Note < ActiveRecord::Base
6
+ validates_duplicity_of :title, scope: :user_id
7
+ end
@@ -0,0 +1,12 @@
1
+ ActiveRecord::Schema.define do
2
+ self.verbose = false
3
+
4
+ create_table :posts, force: true do |t|
5
+ t.string :name
6
+ end
7
+
8
+ create_table :notes, force: true do |t|
9
+ t.string :title
10
+ t.integer :user_id
11
+ end
12
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'validates_duplicity_of/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "validates_duplicity_of"
8
+ spec.version = ValidatesDuplicityOf::VERSION
9
+ spec.authors = ["Vincent Durand"]
10
+ spec.email = ["vincent.durand@madwork.org"]
11
+ spec.description = %q{ActiveRecord callback which handle the name duplication in your model.}
12
+ spec.summary = %q{ActiveRecord callback which handle the name duplication in your model with ease.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec", ">= 2.3"
24
+ spec.add_development_dependency "sqlite3-ruby"
25
+
26
+ spec.add_dependency "activerecord", ">= 3.0"
27
+ end
data.tar.gz.sig ADDED
@@ -0,0 +1 @@
1
+ ���e o]�c�DB��ǚ�EY�o�J�Rj�3k���;q����O�����|���d/y���]�z�7 �M�-�2���W�6)��­}�?��)�wy�xQ"�R�{YR����h�T�
metadata ADDED
@@ -0,0 +1,155 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: validates_duplicity_of
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Vincent Durand
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDkjCCAnqgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMRcwFQYDVQQDDA52aW5j
14
+ ZW50LmR1cmFuZDEXMBUGCgmSJomT8ixkARkWB21hZHdvcmsxEzARBgoJkiaJk/Is
15
+ ZAEZFgNvcmcwHhcNMTMwOTE4MTY0MDEwWhcNMTQwOTE4MTY0MDEwWjBHMRcwFQYD
16
+ VQQDDA52aW5jZW50LmR1cmFuZDEXMBUGCgmSJomT8ixkARkWB21hZHdvcmsxEzAR
17
+ BgoJkiaJk/IsZAEZFgNvcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
18
+ AQDzlsghBvfbH4yPzi3dXyfkmxjy/uksOkYwzqwbZ6z/TvJdIjY9Xqi/gLe2AxGF
19
+ kuVxDuxih84WDG8qxCnAfUxt2nDGAVEspmTXHBAsyZqLLDRiP5LvmH/eAKsJY+rU
20
+ ERSJOaLAotMqHHqXiWnpRgFnzE6RM3Cnqq8LH0jIGF9F8gZVLZeRD+VXK4IX1Vyd
21
+ HgZKgTPL15k92u7bzqBw7niPCBa9LfYxID6E1bnSHw/kb+7hWarVd/sxpgeH0jgb
22
+ f8ieDs8S9+bL/TfzEDAOALAqMDgPXPX1mDKESDZ/wBGW/tP3NSbVKsSZFK8b0e00
23
+ Au/fVbAe+P7+T8po/a5UhjMbAgMBAAGjgYgwgYUwCQYDVR0TBAIwADALBgNVHQ8E
24
+ BAMCBLAwHQYDVR0OBBYEFKne49vGKR3nRMYhyEbJDI2BVQikMCUGA1UdEQQeMByB
25
+ GnZpbmNlbnQuZHVyYW5kQG1hZHdvcmsub3JnMCUGA1UdEgQeMByBGnZpbmNlbnQu
26
+ ZHVyYW5kQG1hZHdvcmsub3JnMA0GCSqGSIb3DQEBBQUAA4IBAQB0EDvvwy8uol26
27
+ Xm4O1iYcfgkTTX11UwgI6XIbS+1AzUwhl4BdWWFFxcy7v2/UMcx4QaJm+tL2B05V
28
+ CcVFS8tOMaGk6s7fPdhFswRp+HE9Ex5aiCMAhoIdUbrR5LCJTWyiEBLJhforT+3R
29
+ RARQ4FabsVVHevPHxzEAUGGGdWzbG4BcvKpWxbsOz/6yVgy3dpscmanMPH6pBpNH
30
+ XD6+HDD0HP0RBeQtHV2LIhLpiJLmNWRmJ9/Cfry72diEnM7173RAelpJNj0kRYjJ
31
+ xDr7hfCTJQsNosd7V5q7Uz+SYPK9ALyONt5t3KKYEWS/mBCStEuQXwjIsWG/bqwr
32
+ vqfQstIS
33
+ -----END CERTIFICATE-----
34
+ date: 2013-10-17 00:00:00.000000000 Z
35
+ dependencies:
36
+ - !ruby/object:Gem::Dependency
37
+ name: bundler
38
+ requirement: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ~>
41
+ - !ruby/object:Gem::Version
42
+ version: '1.3'
43
+ type: :development
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ~>
48
+ - !ruby/object:Gem::Version
49
+ version: '1.3'
50
+ - !ruby/object:Gem::Dependency
51
+ name: rake
52
+ requirement: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ type: :development
58
+ prerelease: false
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ - !ruby/object:Gem::Dependency
65
+ name: rspec
66
+ requirement: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '2.3'
71
+ type: :development
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '2.3'
78
+ - !ruby/object:Gem::Dependency
79
+ name: sqlite3-ruby
80
+ requirement: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - '>='
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ type: :development
86
+ prerelease: false
87
+ version_requirements: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ - !ruby/object:Gem::Dependency
93
+ name: activerecord
94
+ requirement: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '3.0'
99
+ type: :runtime
100
+ prerelease: false
101
+ version_requirements: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '3.0'
106
+ description: ActiveRecord callback which handle the name duplication in your model.
107
+ email:
108
+ - vincent.durand@madwork.org
109
+ executables: []
110
+ extensions: []
111
+ extra_rdoc_files: []
112
+ files:
113
+ - .gitignore
114
+ - Gemfile
115
+ - LICENSE.txt
116
+ - README.md
117
+ - Rakefile
118
+ - lib/validates_duplicity_of.rb
119
+ - lib/validates_duplicity_of/version.rb
120
+ - spec/lib/validates_duplicity_of_spec.rb
121
+ - spec/spec_helper.rb
122
+ - spec/support/models.rb
123
+ - spec/support/schema.rb
124
+ - validates_duplicity_of.gemspec
125
+ homepage: ''
126
+ licenses:
127
+ - MIT
128
+ metadata: {}
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - '>='
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ requirements: []
144
+ rubyforge_project:
145
+ rubygems_version: 2.1.7
146
+ signing_key:
147
+ specification_version: 4
148
+ summary: ActiveRecord callback which handle the name duplication in your model with
149
+ ease.
150
+ test_files:
151
+ - spec/lib/validates_duplicity_of_spec.rb
152
+ - spec/spec_helper.rb
153
+ - spec/support/models.rb
154
+ - spec/support/schema.rb
155
+ has_rdoc:
metadata.gz.sig ADDED
Binary file