validates_overlap 0.1.3 → 0.2.0
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.
- checksums.yaml +8 -8
- data/README.md +10 -1
- data/VERSION +1 -1
- data/lib/validates_overlap/overlap_validator.rb +8 -3
- data/spec/dummy/spec/models/meeting_spec.rb +34 -10
- data/validates_overlap.gemspec +2 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NzBhYmYyMmEzMWNmNTg4YjdhMzBkZWI5MGU5YWZhMGRkMDRjODUzYw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MzhiZjk5M2ZmMDNlNGFkYjczNjU3YWZjNzA1ZDgyMzU2NjJjZDg1MQ==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YjU4MWY3MTdjMzAwZTRkOGRiZmYzOWU1MzAxOTgyMzBhYzMyYjI4Zjc2YzU3
|
10
|
+
MTEwMTEwNGFkNGFhMzNmMjg5MjliYjZmMjkwNzIwMTYxNGE0NGJmOTAyODQw
|
11
|
+
MmZmOTc1ZmQzOGQzZDI3Y2Q3OGJjOGQ2NTU4N2JjOGQ3NWM0ZGY=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
N2ExNGI2N2ZkZDUwZTVmMzM1NmIyYjliMWQ1N2FhMzIzZmY2ZTNjODU0NjVl
|
14
|
+
ZTgzN2ZhZWEwM2NlMzM3Y2FjOTYzYjk4ZDIwN2UzN2IyODc4ZGRmYTc5MmU2
|
15
|
+
M2YzODg5MzM5ZGU5YWM3NjllM2U1YzhlNmJjY2RmNDk3Y2FiZjA=
|
data/README.md
CHANGED
@@ -44,7 +44,7 @@ validates :starts_at, :ends_at, :overlap => {:exclude_edges => ["starts_at", "en
|
|
44
44
|
validates :starts_at, :ends_at, :overlap => {:message_title => "Some validation title", :message_content => "Some validation message"}
|
45
45
|
```
|
46
46
|
|
47
|
-
#### with complicated
|
47
|
+
#### with complicated relations
|
48
48
|
|
49
49
|
Example describes valildatation of user, positions and time slots.
|
50
50
|
User can't be assigned 2 times on position which is under time slot with time overlap.
|
@@ -60,3 +60,12 @@ class Position < ActiveRecord::Base
|
|
60
60
|
}
|
61
61
|
end
|
62
62
|
```
|
63
|
+
|
64
|
+
#### apply named scopes
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
class ActiveMeeting < ActiveRecord::Base
|
68
|
+
validates :starts_at, :ends_at, :overlap => {:query_options => {:active => true}}
|
69
|
+
scope :active, where(:is_active => true)
|
70
|
+
end
|
71
|
+
```
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
@@ -2,6 +2,8 @@ require 'active_support/i18n'
|
|
2
2
|
I18n.load_path << File.dirname(__FILE__) + '/locale/en.yml'
|
3
3
|
|
4
4
|
class OverlapValidator < ActiveModel::EachValidator
|
5
|
+
BEGIN_OF_UNIX_TIME = Time.at(-2147483648).to_datetime
|
6
|
+
END_OF_UNIX_TIME = Time.at(2147483648).to_datetime
|
5
7
|
|
6
8
|
attr_accessor :sql_conditions
|
7
9
|
attr_accessor :sql_values
|
@@ -28,8 +30,8 @@ class OverlapValidator < ActiveModel::EachValidator
|
|
28
30
|
# Check if exists at least one record in DB which is crossed with current record
|
29
31
|
def find_crossed(record)
|
30
32
|
self.scoped_model = record.class
|
31
|
-
self.generate_overlap_sql_conditions(record)
|
32
33
|
self.generate_overlap_sql_values(record)
|
34
|
+
self.generate_overlap_sql_conditions(record)
|
33
35
|
self.add_attributes(record, options[:scope]) if options && options[:scope].present?
|
34
36
|
self.add_query_options(options[:query_options]) if options && options[:query_options].present?
|
35
37
|
|
@@ -99,7 +101,7 @@ class OverlapValidator < ActiveModel::EachValidator
|
|
99
101
|
# Return hash of values for overlap sql condition
|
100
102
|
def generate_overlap_sql_values(record)
|
101
103
|
starts_at_value, ends_at_value = resolve_values_from_attributes(record)
|
102
|
-
self.sql_values = {:starts_at_value => starts_at_value, :ends_at_value => ends_at_value}
|
104
|
+
self.sql_values = {:starts_at_value => starts_at_value || BEGIN_OF_UNIX_TIME, :ends_at_value => ends_at_value || END_OF_UNIX_TIME}
|
103
105
|
end
|
104
106
|
|
105
107
|
# Return the condition string depend on exclude_edges option.
|
@@ -107,7 +109,10 @@ class OverlapValidator < ActiveModel::EachValidator
|
|
107
109
|
except_option = Array(options[:exclude_edges]).map(&:to_s)
|
108
110
|
starts_at_sign = except_option.include?(starts_at_attr.to_s.split(".").last) ? "<" : "<="
|
109
111
|
ends_at_sign = except_option.include?(ends_at_attr.to_s.split(".").last) ? ">" : ">="
|
110
|
-
|
112
|
+
query = []
|
113
|
+
query << "(#{ends_at_attr} IS NULL OR #{ends_at_attr} #{ends_at_sign} :starts_at_value)"
|
114
|
+
query << "(#{starts_at_attr} IS NULL OR #{starts_at_attr} #{starts_at_sign} :ends_at_value)"
|
115
|
+
query.join(" AND ")
|
111
116
|
end
|
112
117
|
|
113
118
|
|
@@ -3,17 +3,16 @@ require_relative '../factories/meeting'
|
|
3
3
|
|
4
4
|
describe Meeting do
|
5
5
|
|
6
|
-
before(:all) do
|
7
|
-
Meeting.delete_all
|
8
|
-
end
|
9
|
-
|
10
|
-
it "create meeting" do
|
11
|
-
lambda {
|
12
|
-
FactoryGirl.create(:meeting)
|
13
|
-
}.should change(Meeting, :count).by(1)
|
14
|
-
end
|
15
|
-
|
16
6
|
context "Validation" do
|
7
|
+
before(:all) do
|
8
|
+
Meeting.delete_all
|
9
|
+
end
|
10
|
+
|
11
|
+
it "create meeting" do
|
12
|
+
lambda {
|
13
|
+
FactoryGirl.create(:meeting)
|
14
|
+
}.should change(Meeting, :count).by(1)
|
15
|
+
end
|
17
16
|
|
18
17
|
OVERLAP_TIME_RANGES.each do |description, time_range|
|
19
18
|
it "is not valid if exists meeting which #{description}" do
|
@@ -38,4 +37,29 @@ describe Meeting do
|
|
38
37
|
|
39
38
|
end
|
40
39
|
|
40
|
+
context "Validation of endless objects" do
|
41
|
+
before(:all) do
|
42
|
+
Meeting.delete_all
|
43
|
+
FactoryGirl.create(:meeting, :ends_at => nil)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "with overlap object" do
|
47
|
+
meeting = FactoryGirl.build(:meeting, :starts_at => "2011-01-05".to_date, :ends_at => "2011-01-08".to_date)
|
48
|
+
meeting.should_not be_valid
|
49
|
+
meeting = FactoryGirl.build(:meeting, :starts_at => "2012-01-05".to_date, :ends_at => "2012-01-08".to_date)
|
50
|
+
meeting.should_not be_valid
|
51
|
+
meeting = FactoryGirl.build(:meeting, :starts_at => "2010-01-05".to_date, :ends_at => "2010-01-08".to_date)
|
52
|
+
meeting.should be_valid
|
53
|
+
end
|
54
|
+
|
55
|
+
it "with another endless obejct" do
|
56
|
+
meeting = FactoryGirl.build(:meeting, :starts_at => "2010-01-05".to_date, :ends_at => nil)
|
57
|
+
meeting.should_not be_valid
|
58
|
+
meeting = FactoryGirl.build(:meeting, :starts_at => nil, :ends_at => "2010-01-05".to_date)
|
59
|
+
meeting.should be_valid
|
60
|
+
meeting = FactoryGirl.build(:meeting, :starts_at => nil, :ends_at => nil)
|
61
|
+
meeting.should_not be_valid
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
41
65
|
end
|
data/validates_overlap.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "validates_overlap"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Robin Bortlik"]
|
12
|
-
s.date = "2013-
|
12
|
+
s.date = "2013-10-18"
|
13
13
|
s.description = "It can be useful when you you are developing some app where you will work with meetings, events etc."
|
14
14
|
s.email = "robinbortlik@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: validates_overlap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robin Bortlik
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-10-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -220,3 +220,4 @@ signing_key:
|
|
220
220
|
specification_version: 4
|
221
221
|
summary: This gem helps validate records with time overlap.
|
222
222
|
test_files: []
|
223
|
+
has_rdoc:
|