limitable 1.0.1 → 2.0.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 +4 -4
- data/CHANGELOG.md +17 -0
- data/README.md +19 -3
- data/lib/limitable/locale/en.yml +8 -0
- data/lib/limitable/locale.rb +13 -0
- data/lib/limitable/version.rb +1 -1
- data/lib/limitable.rb +43 -29
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fa345bff02b1a03c0ef3b2515de75383f9e1f55d2cf397fcd2660fe0a66b0746
|
4
|
+
data.tar.gz: 3f467cd6b86b8b97b1d7b9d749d0a507b943d9395c4691503cd051360d6ce557
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f3d2b2a5ba1904d1a6537bf635cc5ba1c8c374d381ae92fab53b44895e0df3c961ecfbd5bb6dd9440622bb256c5c994cf29a73f416fbea96d0974ea16fa5d46
|
7
|
+
data.tar.gz: e14012f9cb14604324304088be9cb9cd6dc620e40b2e5233f0d2964386ebccbd4fe755e12859cd95be2a73d3d60bb5c6c3c78bb5d747aca65aa8ff26120d35ea
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
# [2.0.0](https://github.com/benmelz/limitable/compare/v1.1.0...v2.0.0) (2023-07-30)
|
2
|
+
|
3
|
+
|
4
|
+
* feat!: custom translations (#15) ([bacc785](https://github.com/benmelz/limitable/commit/bacc7858d7d506bba60bad2f1d39c32732136aa3)), closes [#15](https://github.com/benmelz/limitable/issues/15) [#12](https://github.com/benmelz/limitable/issues/12)
|
5
|
+
|
6
|
+
|
7
|
+
### BREAKING CHANGES
|
8
|
+
|
9
|
+
* reword default validation error messages
|
10
|
+
|
11
|
+
# [1.1.0](https://github.com/benmelz/limitable/compare/v1.0.1...v1.1.0) (2023-07-17)
|
12
|
+
|
13
|
+
|
14
|
+
### Features
|
15
|
+
|
16
|
+
* support for binary column limits ([#14](https://github.com/benmelz/limitable/issues/14)) ([43224d1](https://github.com/benmelz/limitable/commit/43224d1351052833246b94666b7aca76f8c89aa5)), closes [#3](https://github.com/benmelz/limitable/issues/3)
|
17
|
+
|
1
18
|
## [1.0.1](https://github.com/benmelz/limitable/compare/v1.0.0...v1.0.1) (2023-06-09)
|
2
19
|
|
3
20
|
|
data/README.md
CHANGED
@@ -34,8 +34,8 @@ gem install limitable
|
|
34
34
|
|
35
35
|
## Usage
|
36
36
|
|
37
|
-
Once included in a model, `Limitable` will scan `integer`, `string` and `
|
38
|
-
|
37
|
+
Once included in a model, `Limitable` will scan `integer`, `string`, `text` and `binary` columns for size limits,
|
38
|
+
defining byte size validations accordingly. Limits are configurable through `ActiveRecord` migrations.
|
39
39
|
|
40
40
|
### Quick Start
|
41
41
|
|
@@ -59,6 +59,22 @@ class MyModel < ApplicationRecord
|
|
59
59
|
end
|
60
60
|
```
|
61
61
|
|
62
|
+
### Translations
|
63
|
+
|
64
|
+
`Limitable` ships with i18n support for its validation error messages. Each column type has its own translation key,
|
65
|
+
outlined alongside their default values in `lib/limitable/locale/en.yml`.
|
66
|
+
|
67
|
+
Each validator will pass a `limit` parameter (min/max integer for integer columns, bytes for string/text/binary),
|
68
|
+
which can be used to make the messages less ambiguous if desired.
|
69
|
+
|
70
|
+
e.g.
|
71
|
+
|
72
|
+
```yaml
|
73
|
+
en:
|
74
|
+
limitable:
|
75
|
+
string_limit_exceeded: "may not exceed %{limit} characters"
|
76
|
+
```
|
77
|
+
|
62
78
|
### SQL Adapters
|
63
79
|
|
64
80
|
`Limitable` is designed to be SQL adapter agnostic, however different adapters have different default behaviors that
|
@@ -72,7 +88,7 @@ limits in your database migrations/schema unless you want to change them from th
|
|
72
88
|
#### `pg`
|
73
89
|
|
74
90
|
PostgreSQL has and reports hard limits on its integer columns, however it supports and defaults to unlimited
|
75
|
-
string/text columns. If you wish for limits to be validated on those columns, they must be explicitly set in your
|
91
|
+
string/text/binary columns. If you wish for limits to be validated on those columns, they must be explicitly set in your
|
76
92
|
database migrations/schema.
|
77
93
|
|
78
94
|
#### `sqlite3`
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'i18n'
|
4
|
+
|
5
|
+
module Limitable
|
6
|
+
# == Limitable::Locale
|
7
|
+
#
|
8
|
+
# Loads the default limitable custom translations into i18n.
|
9
|
+
#
|
10
|
+
module Locale
|
11
|
+
I18n.load_path << File.expand_path('locale/en.yml', __dir__)
|
12
|
+
end
|
13
|
+
end
|
data/lib/limitable/version.rb
CHANGED
data/lib/limitable.rb
CHANGED
@@ -3,18 +3,19 @@
|
|
3
3
|
require 'active_record'
|
4
4
|
require 'i18n'
|
5
5
|
require_relative 'limitable/base'
|
6
|
+
require_relative 'limitable/locale'
|
6
7
|
require_relative 'limitable/version'
|
7
8
|
|
8
9
|
# == Limitable
|
9
10
|
#
|
10
11
|
# Module that declares database limit validations when included in an ActiveRecord model class. Supports limit
|
11
|
-
# inferences on integer, string and
|
12
|
+
# inferences on integer, string, text and binary columns.
|
12
13
|
#
|
13
14
|
module Limitable
|
14
15
|
class << self
|
15
16
|
def included(klass)
|
16
|
-
safe_column_names(klass)
|
17
|
-
|
17
|
+
safe_column_names(klass).each do |column_name|
|
18
|
+
attach_limit_validator_if_needed klass, column_name
|
18
19
|
end
|
19
20
|
end
|
20
21
|
|
@@ -23,53 +24,66 @@ module Limitable
|
|
23
24
|
def safe_column_names(klass)
|
24
25
|
klass.column_names
|
25
26
|
rescue ActiveRecord::ActiveRecordError, ArgumentError
|
26
|
-
|
27
|
+
[]
|
27
28
|
end
|
28
29
|
|
29
|
-
def
|
30
|
+
def attach_limit_validator_if_needed(klass, column_name)
|
30
31
|
column = klass.column_for_attribute column_name
|
31
32
|
limit = column.sql_type_metadata.limit
|
32
33
|
return if limit.blank?
|
33
34
|
|
34
35
|
case column.type
|
35
|
-
when :integer
|
36
|
-
|
37
|
-
when :string, :text
|
38
|
-
add_string_limit_validation klass, column_name, limit
|
36
|
+
when :integer, :string, :text, :binary
|
37
|
+
klass.validate(&send(:"build_#{column.type}_limit_validator", column_name, limit))
|
39
38
|
end
|
40
39
|
end
|
41
40
|
|
42
|
-
def
|
41
|
+
def build_integer_limit_validator(column_name, limit)
|
43
42
|
min, max = integer_limit_range limit
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
43
|
+
lambda do
|
44
|
+
value = begin
|
45
|
+
self.class.type_for_attribute(column_name).serialize self[column_name]
|
46
|
+
rescue ActiveModel::RangeError => e
|
47
|
+
e.message.match(/(?<number>\d+) is out of range/)[:number].to_i
|
48
|
+
end
|
49
|
+
next unless value.is_a? Integer
|
48
50
|
|
49
|
-
errors.add column_name, I18n.t('
|
50
|
-
errors.add column_name, I18n.t('
|
51
|
+
errors.add column_name, I18n.t('limitable.integer_limit_exceeded.lower', limit: min) if value < min
|
52
|
+
errors.add column_name, I18n.t('limitable.integer_limit_exceeded.upper', limit: max) if value > max
|
51
53
|
end
|
52
54
|
end
|
53
55
|
|
54
|
-
def
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
end
|
56
|
+
def build_string_limit_validator(column_name, limit)
|
57
|
+
lambda do
|
58
|
+
value = self.class.type_for_attribute(column_name).serialize self[column_name]
|
59
|
+
next unless value.is_a?(String) && value.bytesize > limit
|
59
60
|
|
60
|
-
|
61
|
-
|
62
|
-
rescue ActiveModel::RangeError => e
|
63
|
-
e.message.match(/(?<number>\d+) is out of range/)[:number].to_i
|
61
|
+
errors.add column_name, I18n.t('limitable.string_limit_exceeded', limit: limit)
|
62
|
+
end
|
64
63
|
end
|
65
64
|
|
66
|
-
def
|
67
|
-
|
68
|
-
value =
|
65
|
+
def build_text_limit_validator(column_name, limit)
|
66
|
+
lambda do
|
67
|
+
value = self.class.type_for_attribute(column_name).serialize self[column_name]
|
69
68
|
next unless value.is_a?(String) && value.bytesize > limit
|
70
69
|
|
71
|
-
errors.add column_name, I18n.t('
|
70
|
+
errors.add column_name, I18n.t('limitable.text_limit_exceeded', limit: limit)
|
72
71
|
end
|
73
72
|
end
|
73
|
+
|
74
|
+
def build_binary_limit_validator(column_name, limit)
|
75
|
+
lambda do
|
76
|
+
value = self.class.type_for_attribute(column_name).serialize self[column_name]
|
77
|
+
next unless value.is_a?(ActiveModel::Type::Binary::Data) && value.to_s.bytesize > limit
|
78
|
+
|
79
|
+
errors.add column_name, I18n.t('limitable.binary_limit_exceeded', limit: limit)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def integer_limit_range(limit)
|
84
|
+
max = (1 << ((limit * 8) - 1)) - 1
|
85
|
+
min = -max
|
86
|
+
[min, max]
|
87
|
+
end
|
74
88
|
end
|
75
89
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: limitable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Benjamin Melz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-07-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -63,6 +63,8 @@ files:
|
|
63
63
|
- README.md
|
64
64
|
- lib/limitable.rb
|
65
65
|
- lib/limitable/base.rb
|
66
|
+
- lib/limitable/locale.rb
|
67
|
+
- lib/limitable/locale/en.yml
|
66
68
|
- lib/limitable/version.rb
|
67
69
|
homepage: https://github.com/benmelz/limitable
|
68
70
|
licenses:
|
@@ -70,7 +72,7 @@ licenses:
|
|
70
72
|
metadata:
|
71
73
|
homepage_uri: https://github.com/benmelz/limitable
|
72
74
|
source_code_uri: https://github.com/benmelz/limitable
|
73
|
-
changelog_uri: https://github.com/benmelz/limitable/blob/
|
75
|
+
changelog_uri: https://github.com/benmelz/limitable/blob/v2.0.0/CHANGELOG.md
|
74
76
|
rubygems_mfa_required: 'true'
|
75
77
|
post_install_message:
|
76
78
|
rdoc_options: []
|