atdis 0.2 → 0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.ruby-version +1 -1
- data/.travis.yml +0 -1
- data/Gemfile +1 -1
- data/README.md +25 -2
- data/Rakefile +1 -1
- data/docs/ATDIS-1.0.2 Application Tracking Data Interchange Specification (v1.0.2).doc +0 -0
- data/docs/ATDIS-1.0.2 Application Tracking Data Interchange Specification (v1.0.2).pdf +0 -0
- data/lib/atdis.rb +2 -7
- data/lib/atdis/feed.rb +80 -8
- data/lib/atdis/model.rb +74 -128
- data/lib/atdis/models/address.rb +17 -0
- data/lib/atdis/models/application.rb +31 -0
- data/lib/atdis/models/authority.rb +19 -0
- data/lib/atdis/models/document.rb +16 -0
- data/lib/atdis/models/event.rb +16 -0
- data/lib/atdis/models/info.rb +81 -0
- data/lib/atdis/models/land_title_ref.rb +26 -0
- data/lib/atdis/models/location.rb +23 -0
- data/lib/atdis/models/page.rb +56 -0
- data/lib/atdis/models/pagination.rb +68 -0
- data/lib/atdis/models/person.rb +14 -0
- data/lib/atdis/models/reference.rb +13 -0
- data/lib/atdis/models/response.rb +16 -0
- data/lib/atdis/models/torrens_title.rb +24 -0
- data/lib/atdis/validators.rb +26 -10
- data/lib/atdis/version.rb +1 -1
- data/spec/atdis/feed_spec.rb +78 -22
- data/spec/atdis/model_spec.rb +80 -131
- data/spec/atdis/models/address_spec.rb +22 -0
- data/spec/atdis/models/application_spec.rb +246 -0
- data/spec/atdis/models/authority_spec.rb +34 -0
- data/spec/atdis/models/document_spec.rb +19 -0
- data/spec/atdis/models/event_spec.rb +29 -0
- data/spec/atdis/models/info_spec.rb +303 -0
- data/spec/atdis/models/land_title_ref_spec.rb +39 -0
- data/spec/atdis/models/location_spec.rb +95 -0
- data/spec/atdis/models/page_spec.rb +296 -0
- data/spec/atdis/models/pagination_spec.rb +153 -0
- data/spec/atdis/models/person_spec.rb +19 -0
- data/spec/atdis/models/reference_spec.rb +55 -0
- data/spec/atdis/models/response_spec.rb +5 -0
- data/spec/atdis/models/torrens_title_spec.rb +52 -0
- data/spec/atdis/separated_url_spec.rb +4 -4
- metadata +141 -135
- data/docs/ATDIS-1.0.7 Application Tracking Data Interchange Specification (v1.0).doc +0 -0
- data/docs/ATDIS-1.0.7 Application Tracking Data Interchange Specification (v1.0).pdf +0 -0
- data/lib/atdis/application.rb +0 -78
- data/lib/atdis/document.rb +0 -14
- data/lib/atdis/event.rb +0 -17
- data/lib/atdis/location.rb +0 -21
- data/lib/atdis/page.rb +0 -130
- data/lib/atdis/person.rb +0 -12
- data/spec/atdis/application_spec.rb +0 -539
- data/spec/atdis/document_spec.rb +0 -19
- data/spec/atdis/event_spec.rb +0 -29
- data/spec/atdis/location_spec.rb +0 -148
- data/spec/atdis/page_spec.rb +0 -492
- data/spec/atdis/person_spec.rb +0 -19
@@ -0,0 +1,17 @@
|
|
1
|
+
module ATDIS
|
2
|
+
module Models
|
3
|
+
class Address < Model
|
4
|
+
set_field_mappings ({
|
5
|
+
street: String,
|
6
|
+
suburb: String,
|
7
|
+
postcode: String,
|
8
|
+
state: String
|
9
|
+
})
|
10
|
+
|
11
|
+
# Mandatory parameters
|
12
|
+
validates :street, :suburb, :postcode, :state, presence_before_type_cast: {spec_section: "4.3.3"}
|
13
|
+
|
14
|
+
validates :postcode, format: { with: /\A[0-9]{4}\z/, message: ATDIS::ErrorMessage.new("is not a valid postcode", "4.3.3")}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "atdis/models/info"
|
2
|
+
require "atdis/models/reference"
|
3
|
+
require "atdis/models/location"
|
4
|
+
require "atdis/models/event"
|
5
|
+
require "atdis/models/document"
|
6
|
+
require "atdis/models/person"
|
7
|
+
|
8
|
+
module ATDIS
|
9
|
+
module Models
|
10
|
+
class Application < Model
|
11
|
+
set_field_mappings ({
|
12
|
+
info: Info,
|
13
|
+
reference: Reference,
|
14
|
+
locations: Location,
|
15
|
+
events: Event,
|
16
|
+
documents: Document,
|
17
|
+
people: Person,
|
18
|
+
extended: Object,
|
19
|
+
})
|
20
|
+
|
21
|
+
# Mandatory attributes
|
22
|
+
validates :info, :reference, :locations, :events, :documents, presence_before_type_cast: {spec_section: "4.3"}
|
23
|
+
|
24
|
+
validates :people, array: {spec_section: "4.3"}
|
25
|
+
validates :locations, :events, :documents, filled_array: {spec_section: "4.3"}
|
26
|
+
|
27
|
+
# This model is only valid if the children are valid
|
28
|
+
validates :info, :reference, :locations, :events, :documents, :people, valid: true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ATDIS
|
2
|
+
module Models
|
3
|
+
class Authority < Model
|
4
|
+
set_field_mappings ({
|
5
|
+
ref: URI,
|
6
|
+
name: String
|
7
|
+
})
|
8
|
+
|
9
|
+
# ref is a "Unique Authority Identifier" and should have the form http://www.council.nsw.gov.au/atdis/1.0
|
10
|
+
# It should also be consistent for each council.
|
11
|
+
|
12
|
+
# Mandatory attributes
|
13
|
+
validates :ref, :name, presence_before_type_cast: {spec_section: "4.3.1"}
|
14
|
+
|
15
|
+
validates :ref, http_url: {spec_section: "4.3.1"}
|
16
|
+
validates :ref, format: { with: /atdis\/1.0\z/, message: ATDIS::ErrorMessage.new("is not a valid Unique Authority Identifier", "4.3.1")}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module ATDIS
|
2
|
+
module Models
|
3
|
+
class Document < Model
|
4
|
+
set_field_mappings ({
|
5
|
+
ref: String,
|
6
|
+
title: String,
|
7
|
+
document_url: URI
|
8
|
+
})
|
9
|
+
|
10
|
+
# Mandatory parameters
|
11
|
+
validates :ref, :title, :document_url, presence_before_type_cast: {spec_section: "4.3.5"}
|
12
|
+
# Other validations
|
13
|
+
validates :document_url, http_url: {spec_section: "4.3.5"}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module ATDIS
|
2
|
+
module Models
|
3
|
+
class Event < Model
|
4
|
+
set_field_mappings ({
|
5
|
+
id: String,
|
6
|
+
timestamp: DateTime,
|
7
|
+
description: String,
|
8
|
+
event_type: String,
|
9
|
+
status: String
|
10
|
+
})
|
11
|
+
|
12
|
+
# Mandatory parameters
|
13
|
+
validates :id, :timestamp, :description, presence_before_type_cast: {spec_section: "4.3.4"}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require "atdis/models/authority"
|
2
|
+
|
3
|
+
module ATDIS
|
4
|
+
module Models
|
5
|
+
class Info < Model
|
6
|
+
set_field_mappings ({
|
7
|
+
dat_id: String,
|
8
|
+
development_type: String,
|
9
|
+
application_type: String,
|
10
|
+
last_modified_date: DateTime,
|
11
|
+
description: String,
|
12
|
+
authority: Authority,
|
13
|
+
lodgement_date: DateTime,
|
14
|
+
determination_date: DateTime,
|
15
|
+
determination_type: String,
|
16
|
+
status: String,
|
17
|
+
notification_start_date: DateTime,
|
18
|
+
notification_end_date: DateTime,
|
19
|
+
officer: String,
|
20
|
+
estimated_cost: String,
|
21
|
+
related_apps: URI
|
22
|
+
})
|
23
|
+
|
24
|
+
# Mandatory parameters
|
25
|
+
# determination_date is not in this list because even though it is mandatory
|
26
|
+
# it can be null if there is no value
|
27
|
+
validates :dat_id, :development_type, :last_modified_date, :description,
|
28
|
+
:authority, :lodgement_date, :status,
|
29
|
+
presence_before_type_cast: {spec_section: "4.3.1"}
|
30
|
+
# Other validations
|
31
|
+
validates :application_type, inclusion: { in: [
|
32
|
+
"DA", "CDC", "S96", "Review", "Appeal", "Other"
|
33
|
+
],
|
34
|
+
message: ATDIS::ErrorMessage.new("does not have one of the allowed types", "4.3.1")}
|
35
|
+
validates :last_modified_date, :lodgement_date, :determination_date,
|
36
|
+
:notification_start_date, :notification_end_date,
|
37
|
+
date_time: {spec_section: "4.3.1"}
|
38
|
+
# We don't need to separately validate presence because this covers it
|
39
|
+
validates :determination_type, inclusion: { in: [
|
40
|
+
"Pending", "Refused by Council", "Refused under delegation", "Withdrawn",
|
41
|
+
"Approved by Council", "Approved under delegation", "Rejected"
|
42
|
+
],
|
43
|
+
message: ATDIS::ErrorMessage.new("does not have one of the allowed types", "4.3.1")
|
44
|
+
}
|
45
|
+
validate :notification_dates_consistent!
|
46
|
+
validates :related_apps, array: {spec_section: "4.3.1"}
|
47
|
+
validates :related_apps, array_http_url: {spec_section: "4.3.1"}
|
48
|
+
validate :related_apps_url_format
|
49
|
+
validate :dat_id_is_url_encoded!
|
50
|
+
|
51
|
+
# This model is only valid if the children are valid
|
52
|
+
validates :authority, valid: true
|
53
|
+
|
54
|
+
# TODO Validate contents of estimated_cost
|
55
|
+
|
56
|
+
def dat_id_is_url_encoded!
|
57
|
+
if dat_id && CGI::escape(dat_id) != dat_id
|
58
|
+
errors.add(:dat_id, ErrorMessage.new("should be url encoded", "4.3.1"))
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def related_apps_url_format
|
63
|
+
if related_apps.respond_to?(:all?) && !related_apps.all? {|url| url.to_s =~ /atdis\/1.0\/[^\/]+\.json/}
|
64
|
+
errors.add(:related_apps, ErrorMessage.new("contains url(s) not in the expected format", "4.3.1"))
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def notification_dates_consistent!
|
69
|
+
if notification_start_date_before_type_cast && notification_end_date_before_type_cast.blank?
|
70
|
+
errors.add(:notification_end_date, ErrorMessage["can not be blank if notification_start_date is set", "4.3.1"])
|
71
|
+
end
|
72
|
+
if notification_start_date_before_type_cast.blank? && notification_end_date_before_type_cast
|
73
|
+
errors.add(:notification_start_date, ErrorMessage["can not be blank if notification_end_date is set", "4.3.1"])
|
74
|
+
end
|
75
|
+
if notification_start_date && notification_end_date && notification_start_date > notification_end_date
|
76
|
+
errors.add(:notification_end_date, ErrorMessage["can not be earlier than notification_start_date", "4.3.1"])
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "atdis/models/torrens_title"
|
2
|
+
|
3
|
+
module ATDIS
|
4
|
+
module Models
|
5
|
+
class LandTitleRef < Model
|
6
|
+
set_field_mappings ({
|
7
|
+
torrens: TorrensTitle,
|
8
|
+
other: Hash
|
9
|
+
})
|
10
|
+
|
11
|
+
# This model is only valid if the children are valid
|
12
|
+
validates :torrens, valid: true
|
13
|
+
|
14
|
+
validate :check_title_presence
|
15
|
+
|
16
|
+
def check_title_presence
|
17
|
+
if torrens.nil? && other.nil?
|
18
|
+
errors.add(:torrens, ATDIS::ErrorMessage.new("or other needs be present", "4.3.3"))
|
19
|
+
end
|
20
|
+
if torrens && other
|
21
|
+
errors.add(:torrens, ATDIS::ErrorMessage.new("and other can't both be present", "4.3.3"))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'atdis/models/address'
|
2
|
+
require "atdis/models/land_title_ref"
|
3
|
+
require "rgeo/geo_json"
|
4
|
+
|
5
|
+
module ATDIS
|
6
|
+
module Models
|
7
|
+
class Location < Model
|
8
|
+
set_field_mappings ({
|
9
|
+
address: Address,
|
10
|
+
land_title_ref: LandTitleRef,
|
11
|
+
geometry: RGeo::GeoJSON
|
12
|
+
})
|
13
|
+
|
14
|
+
# Mandatory parameters
|
15
|
+
validates :address, :land_title_ref, presence_before_type_cast: {spec_section: "4.3.3"}
|
16
|
+
|
17
|
+
validates :geometry, geo_json: {spec_section: "4.3.3"}
|
18
|
+
|
19
|
+
# This model is only valid if the children are valid
|
20
|
+
validates :address, :land_title_ref, valid: true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require "atdis/models/response"
|
2
|
+
require "atdis/models/pagination"
|
3
|
+
|
4
|
+
module ATDIS
|
5
|
+
module Models
|
6
|
+
class Page < Model
|
7
|
+
set_field_mappings ({
|
8
|
+
response: Response,
|
9
|
+
count: Fixnum,
|
10
|
+
pagination: Pagination,
|
11
|
+
})
|
12
|
+
|
13
|
+
# Mandatory parameters
|
14
|
+
validates :response, presence_before_type_cast: {spec_section: "4.3"}
|
15
|
+
# section 6.5 is not explicitly about this but it does contain an example which should be helpful
|
16
|
+
validates :response, array: {spec_section: "6.4"}
|
17
|
+
validate :count_is_consistent, :all_pagination_is_present
|
18
|
+
|
19
|
+
# This model is only valid if the children are valid
|
20
|
+
validates :response, valid: true
|
21
|
+
validates :pagination, valid: true
|
22
|
+
|
23
|
+
# If some of the pagination fields are present all of the required ones should be present
|
24
|
+
def all_pagination_is_present
|
25
|
+
if pagination && count.nil?
|
26
|
+
errors.add(:count, ErrorMessage["should be present if pagination is being used", "6.4"])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def count_is_consistent
|
31
|
+
if count
|
32
|
+
errors.add(:count, ErrorMessage["is not the same as the number of applications returned", "6.4"]) if count != response.count
|
33
|
+
errors.add(:count, ErrorMessage["should not be larger than the number of results per page", "6.4"]) if count > pagination.per_page
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def previous_url
|
38
|
+
raise "Can't use previous_url when loaded with read_json" if url.nil?
|
39
|
+
ATDIS::SeparatedURL.merge(url, page: pagination.previous) if pagination && pagination.previous
|
40
|
+
end
|
41
|
+
|
42
|
+
def next_url
|
43
|
+
raise "Can't use next_url when loaded with read_json" if url.nil?
|
44
|
+
ATDIS::SeparatedURL.merge(url, page: pagination.next) if pagination && pagination.next
|
45
|
+
end
|
46
|
+
|
47
|
+
def previous_page
|
48
|
+
Page.read_url(previous_url) if previous_url
|
49
|
+
end
|
50
|
+
|
51
|
+
def next_page
|
52
|
+
Page.read_url(next_url) if next_url
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module ATDIS
|
2
|
+
module Models
|
3
|
+
class Pagination < Model
|
4
|
+
set_field_mappings ({
|
5
|
+
previous: Fixnum,
|
6
|
+
next: Fixnum,
|
7
|
+
current: Fixnum,
|
8
|
+
per_page: Fixnum,
|
9
|
+
count: Fixnum,
|
10
|
+
pages: Fixnum
|
11
|
+
})
|
12
|
+
|
13
|
+
validate :all_pagination_is_present, :previous_is_consistent,
|
14
|
+
:next_is_consistent, :current_is_consistent,
|
15
|
+
:count_is_consistent
|
16
|
+
|
17
|
+
# If some of the pagination fields are present all of the required ones should be present
|
18
|
+
def all_pagination_is_present
|
19
|
+
errors.add(:current, ErrorMessage["should be present if pagination is being used", "6.4"]) if current.nil?
|
20
|
+
errors.add(:per_page, ErrorMessage["should be present if pagination is being used", "6.4"]) if per_page.nil?
|
21
|
+
errors.add(:count, ErrorMessage["should be present if pagination is being used", "6.4"]) if count.nil?
|
22
|
+
errors.add(:pages, ErrorMessage["should be present if pagination is being used", "6.4"]) if pages.nil?
|
23
|
+
end
|
24
|
+
|
25
|
+
def previous_is_consistent
|
26
|
+
if previous && current && previous != current - 1
|
27
|
+
errors.add(:previous, ErrorMessage["should be one less than current page number or null if first page", "6.4"])
|
28
|
+
end
|
29
|
+
if previous && current && current == 1
|
30
|
+
errors.add(:previous, ErrorMessage["should be null if on the first page", "6.4"])
|
31
|
+
end
|
32
|
+
if previous.nil? && current && current > 1
|
33
|
+
errors.add(:previous, ErrorMessage["can't be null if not on the first page", "6.4"])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def next_is_consistent
|
38
|
+
if self.next && current && self.next != current + 1
|
39
|
+
errors.add(:next, ErrorMessage["should be one greater than current page number or null if last page", "6.4"])
|
40
|
+
end
|
41
|
+
if self.next.nil? && current != pages
|
42
|
+
errors.add(:next, ErrorMessage["can't be null if not on the last page", "6.4"])
|
43
|
+
end
|
44
|
+
if self.next && current == pages
|
45
|
+
errors.add(:next, ErrorMessage["should be null if on the last page", "6.4"])
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def current_is_consistent
|
50
|
+
if current && pages && current > pages
|
51
|
+
errors.add(:current, ErrorMessage["is larger than the number of pages", "6.4"])
|
52
|
+
end
|
53
|
+
if current && current < 1
|
54
|
+
errors.add(:current, ErrorMessage["can not be less than 1", "6.4"])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def count_is_consistent
|
59
|
+
if pages && per_page && count && count > pages * per_page
|
60
|
+
errors.add(:count, ErrorMessage["is larger than can be retrieved through paging", "6.4"])
|
61
|
+
end
|
62
|
+
if pages && per_page && count && count <= (pages - 1) * per_page
|
63
|
+
errors.add(:count, ErrorMessage["could fit into a smaller number of pages", "6.4"])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module ATDIS
|
2
|
+
module Models
|
3
|
+
class Person < Model
|
4
|
+
set_field_mappings ({
|
5
|
+
name: String,
|
6
|
+
role: String,
|
7
|
+
contact: String
|
8
|
+
})
|
9
|
+
|
10
|
+
# Mandatory parameters
|
11
|
+
validates :name, :role, presence_before_type_cast: {spec_section: "4.3.6"}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module ATDIS
|
2
|
+
module Models
|
3
|
+
class Reference < Model
|
4
|
+
set_field_mappings ({
|
5
|
+
more_info_url: URI,
|
6
|
+
comments_url: URI
|
7
|
+
})
|
8
|
+
|
9
|
+
validates :more_info_url, presence_before_type_cast: {spec_section: "4.3.2"}
|
10
|
+
validates :more_info_url, :comments_url, http_url: {spec_section: "4.3.2"}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "atdis/models/application"
|
2
|
+
|
3
|
+
module ATDIS
|
4
|
+
module Models
|
5
|
+
class Response < Model
|
6
|
+
set_field_mappings ({
|
7
|
+
application: Application
|
8
|
+
})
|
9
|
+
|
10
|
+
validates :application, presence_before_type_cast: {spec_section: "4.3"}
|
11
|
+
|
12
|
+
# This model is only valid if the children are valid
|
13
|
+
validates :application, valid: true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module ATDIS
|
2
|
+
module Models
|
3
|
+
class TorrensTitle < Model
|
4
|
+
set_field_mappings ({
|
5
|
+
lot: String,
|
6
|
+
section: String,
|
7
|
+
dpsp_id: String
|
8
|
+
})
|
9
|
+
|
10
|
+
# Mandatory attributes
|
11
|
+
# section is not in this list because it can be null (even though it is mandatory)
|
12
|
+
validates :lot, :dpsp_id, presence_before_type_cast: {spec_section: "4.3.3"}
|
13
|
+
# TODO: Provide warning if dpsp_id doesn't start with "DP" or "SP"
|
14
|
+
|
15
|
+
validate :section_can_not_be_empty_string
|
16
|
+
|
17
|
+
def section_can_not_be_empty_string
|
18
|
+
if section == ""
|
19
|
+
errors.add(:section, ATDIS::ErrorMessage.new("can't be blank", "4.3.3"))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/atdis/validators.rb
CHANGED
@@ -22,35 +22,51 @@ module ATDIS
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
class
|
25
|
+
class HttpUrlValidator < ActiveModel::EachValidator
|
26
26
|
def validate_each(record, attribute, value)
|
27
27
|
raw_value = record.send("#{attribute}_before_type_cast")
|
28
|
-
if raw_value.present? &&
|
29
|
-
message = "is not a valid
|
28
|
+
if raw_value.present? && !value.kind_of?(URI::HTTP) && !value.kind_of?(URI::HTTPS)
|
29
|
+
message = "is not a valid URL"
|
30
30
|
message = ErrorMessage[message, options[:spec_section]] if options[:spec_section]
|
31
31
|
record.errors.add(attribute, message)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
class
|
36
|
+
class ArrayHttpUrlValidator < ActiveModel::EachValidator
|
37
37
|
def validate_each(record, attribute, value)
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
if value.present? && value.kind_of?(Array) &&
|
39
|
+
value.any?{|v| !v.kind_of?(URI::HTTP) && !v.kind_of?(URI::HTTPS)}
|
40
|
+
message = "contains an invalid URL"
|
41
|
+
message = ErrorMessage[message, options[:spec_section]] if options[:spec_section]
|
42
|
+
record.errors.add(attribute, message)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class ArrayValidator < ActiveModel::EachValidator
|
48
|
+
def validate_each(record, attribute, value)
|
49
|
+
if value && !value.kind_of?(Array)
|
50
|
+
message = "should be an array"
|
41
51
|
message = ErrorMessage[message, options[:spec_section]] if options[:spec_section]
|
42
52
|
record.errors.add(attribute, message)
|
43
53
|
end
|
44
54
|
end
|
45
55
|
end
|
46
56
|
|
47
|
-
|
57
|
+
# Can't be an empty array
|
58
|
+
class FilledArrayValidator < ActiveModel::EachValidator
|
48
59
|
def validate_each(record, attribute, value)
|
49
60
|
if value && !value.kind_of?(Array)
|
50
61
|
message = "should be an array"
|
51
62
|
message = ErrorMessage[message, options[:spec_section]] if options[:spec_section]
|
52
63
|
record.errors.add(attribute, message)
|
53
64
|
end
|
65
|
+
if value && value.kind_of?(Array) && value.empty?
|
66
|
+
message = "should not be an empty array"
|
67
|
+
message = ErrorMessage[message, options[:spec_section]] if options[:spec_section]
|
68
|
+
record.errors.add(attribute, message)
|
69
|
+
end
|
54
70
|
end
|
55
71
|
end
|
56
72
|
|
@@ -59,7 +75,7 @@ module ATDIS
|
|
59
75
|
def validate_each(record, attribute, value)
|
60
76
|
raw_value = record.send("#{attribute}_before_type_cast")
|
61
77
|
if !raw_value.kind_of?(Array) && !raw_value.present?
|
62
|
-
message = "can't be blank"
|
78
|
+
message = "can't be blank"
|
63
79
|
message = ErrorMessage[message, options[:spec_section]] if options[:spec_section]
|
64
80
|
record.errors.add(attribute, message)
|
65
81
|
end
|
@@ -70,7 +86,7 @@ module ATDIS
|
|
70
86
|
class ValidValidator < ActiveModel::EachValidator
|
71
87
|
def validate_each(record, attribute, value)
|
72
88
|
if (value.respond_to?(:valid?) && !value.valid?) || (value && !value.respond_to?(:valid?) && !value.all?{|v| v.valid?})
|
73
|
-
record.errors.add(attribute, ErrorMessage["is not valid", nil])
|
89
|
+
record.errors.add(attribute, ErrorMessage["is not valid (see further errors for details)", nil])
|
74
90
|
end
|
75
91
|
end
|
76
92
|
end
|