validates_overlap 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|