effective_resources 2.8.1 → 2.8.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 016f2e6e705dc75e0ea58ff2e95f9ce5553122d82a1dd0280ccc327a284b4e93
4
- data.tar.gz: eedc423555203163a7c9d3674729c3ab56dd1d69d448d289fef0a0c06bbad3d0
3
+ metadata.gz: a3306eaeb2757f8d71427567e38353c13c2ff2b7ebc9bfd4fa59dbfe24af3ed9
4
+ data.tar.gz: 561544b09df06f7210d0dd07a48547ac3b2d8661654fb0129e92f7ad413a4a56
5
5
  SHA512:
6
- metadata.gz: 296abe054bdc8e96495d75a2172187b89c093311a5819f7df89c13af90298611673285cec429d96c1a45da88b15e65f0c54e3f0108193f8fdff12117edbf611d
7
- data.tar.gz: 6278969a0aefe37f56bae5c036e944ab0d22c7c8142a09127cbfa9b1448be49fd9568b1bb7185db7896f985e85d0594b4864aaa4994d50ba1e0ab2d5590f4326
6
+ metadata.gz: e7ca40c7ee7b3aa67659a45f62ecc86bd34e1ca3454f1baf0c601cd4437b960064ad9b58645dca6cfac931e327e86cbb39875dcda44eff32459caa7c94d6649c
7
+ data.tar.gz: 1489d7f93a9a8429f4cabe58c113864e7193f681feb6fc012ed2788d79b9be7f0ced3e12ae3622b30fd7beb122716249e987705f0b981f3f5df8b09e9c909a59
data/README.md CHANGED
@@ -213,6 +213,19 @@ Just put another `app/views/posts/index.html.haml` in the posts directory to ove
213
213
 
214
214
  Sure why not. These don't really fit into my code base anywhere else.
215
215
 
216
+ ### acts_as_paginable
217
+
218
+ Quickly adds a `paginate` scope to your model that can then be used in your views and also integrates well with `effective_bootstrap`. The pagination method is `Limit and Offset`.
219
+
220
+ ```ruby
221
+ # Given any model you just need to call it like
222
+ class Thing < ApplicationRecord
223
+ acts_as_paginable
224
+ end
225
+
226
+ # Now you can use it like:
227
+ Thing.all.paginate(page: 1, per_page: 5)
228
+ ```
216
229
  ### acts_as_tokened
217
230
 
218
231
  Quickly adds rails 5 `has_secure_token` to your model, along with some `Post.find()` enhancements to work with tokens instead of IDs.
@@ -72,8 +72,10 @@ module ActsAsPurchasableWizard
72
72
  # From Billing Step
73
73
  order.billing_address = owner.billing_address if owner.try(:billing_address).present?
74
74
 
75
+ # This will update all order items to match the prices from their
76
+ order.try(:update_purchasable_attributes)
77
+
75
78
  # Important to add/remove anything
76
- # This will update the prices, but the purchasables must be persisted
77
79
  order.save!
78
80
 
79
81
  order
@@ -313,11 +313,10 @@ module Effective
313
313
  )
314
314
 
315
315
  if as == :date
316
- term = term.to_date
317
- end_at = end_at.to_date
316
+ relation.where("#{sql_column} >= ? AND #{sql_column} < ?", term.to_date, (end_at + 1.day).to_date)
317
+ else
318
+ relation.where("#{sql_column} >= ? AND #{sql_column} <= ?", term, end_at)
318
319
  end
319
-
320
- relation.where("#{sql_column} >= ? AND #{sql_column} <= ?", term, end_at)
321
320
  elsif value.respond_to?(:strftime) && operation == :eq
322
321
  relation.where(attribute.matches(value))
323
322
  end
@@ -347,7 +346,7 @@ module Effective
347
346
 
348
347
  case operation
349
348
  when :eq then relation.where("#{sql_column} = ?", term)
350
- when :matches then search_columns_by_ilike_term(relation, term, columns: name)
349
+ when :matches then search_columns_by_ilike_term(relation, term, columns: (sql_column.presence || name))
351
350
  when :not_eq then relation.where(attribute.not_eq(term))
352
351
  when :does_not_match then relation.where(attribute.does_not_match("%#{term}%"))
353
352
  when :starts_with then relation.where(attribute.matches("#{term}%"))
@@ -426,7 +425,10 @@ module Effective
426
425
 
427
426
  # Do any of these columns contain all the terms?
428
427
  conditions = columns.map do |name|
429
- keys = terms.keys.map { |key| (fuzzy ? "#{sql_column(name)} #{ilike} :#{key}" : "#{sql_column(name)} = :#{key}") }
428
+ column = (name.to_s.include?('.') ? name : sql_column(name))
429
+ raise("expected an sql column for #{name}") if column.blank?
430
+
431
+ keys = terms.keys.map { |key| (fuzzy ? "#{column} #{ilike} :#{key}" : "#{column} = :#{key}") }
430
432
  '(' + keys.join(' AND ') + ')'
431
433
  end.join(' OR ')
432
434
 
@@ -0,0 +1,50 @@
1
+ #
2
+ # Custom validator for attachments' content types
3
+ #
4
+ # @example
5
+ #
6
+ # -> validates :image, content_type: :image
7
+ # -> validates :image, content_type: [:jpg, :webp]
8
+ # -> validates :image, content_type: [:image, :pdf]
9
+ # -> validates :image, content_type: { in: :image, message: 'must be a valid image' }
10
+ #
11
+ class ContentTypeValidator < ActiveModel::EachValidator
12
+ EXPANSIONS = {
13
+ image: %i[png jpeg jpg jpe pjpeg gif bmp svg webp],
14
+ document: %i[text txt docx doc xml pdf csv],
15
+ calendar: %i[ics],
16
+ spreadsheet: %i[xlsx xls],
17
+ video: %i[mpeg mpg mp3 m4a mpg4 aac webm mp4 m4v],
18
+ }.freeze
19
+
20
+ def validate_each(record, attribute, value)
21
+ # Support for optional attachments
22
+ return unless value.present? && value.attached?
23
+
24
+ keys = EXPANSIONS.keys
25
+ values = EXPANSIONS.values.flatten
26
+ options = instance_values["options"]
27
+ message = options.try(:[], :message) || "must have a valid content type"
28
+ types = options[:with] || options[:in]
29
+
30
+ # Ensure array and ensure symbols
31
+ types = [types].flatten.compact.map(&:to_sym)
32
+
33
+ allowed_types = []
34
+ types.each do |types|
35
+ if types.in?(keys)
36
+ allowed_types << EXPANSIONS[types]
37
+ elsif types.in?(values)
38
+ allowed_types << types
39
+ else
40
+ raise("unknown content_type types: #{types}")
41
+ end
42
+ end
43
+ allowed_types = allowed_types.flatten.map(&:to_sym).uniq
44
+
45
+ unless value.filename.extension.to_sym.in?(allowed_types)
46
+ record.errors.add(attribute, message)
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,23 @@
1
+ #
2
+ # Custom validator for file sizes
3
+ #
4
+ # @example
5
+ #
6
+ # -> validates :image, size: { less_than: 2.megabytes }
7
+ # -> validates :image, size: { less_than: 2.megabytes, message: 'is too large, please upload a file smaller than 2MB' }
8
+ #
9
+ class SizeValidator < ActiveModel::EachValidator
10
+ def validate_each(record, attribute, value)
11
+ return unless value.present? && value.attached?
12
+
13
+ options = instance_values["options"]
14
+
15
+ max_size = options.try(:[], :less_than) || 2.megabytes
16
+ message = options.try(:[], :message) || "is too large, please upload a file smaller than #{max_size / 1.megabyte}MB"
17
+
18
+ if value.blob.byte_size > max_size
19
+ record.errors.add(attribute, message)
20
+ end
21
+
22
+ end
23
+ end
@@ -1,3 +1,3 @@
1
1
  module EffectiveResources
2
- VERSION = '2.8.1'.freeze
2
+ VERSION = '2.8.3'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_resources
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.8.1
4
+ version: 2.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-15 00:00:00.000000000 Z
11
+ date: 2023-06-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -122,6 +122,34 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: psych
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "<"
130
+ - !ruby/object:Gem::Version
131
+ version: '4'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "<"
137
+ - !ruby/object:Gem::Version
138
+ version: '4'
139
+ - !ruby/object:Gem::Dependency
140
+ name: net-smtp
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
125
153
  description: Make any controller an effective resource controller.
126
154
  email:
127
155
  - info@codeandeffect.com
@@ -195,6 +223,8 @@ files:
195
223
  - app/models/effective/resources/relation.rb
196
224
  - app/models/effective/resources/sql.rb
197
225
  - app/models/effective/resources/tenants.rb
226
+ - app/validators/content_type_validator.rb
227
+ - app/validators/size_validator.rb
198
228
  - app/views/application/_flash.html.haml
199
229
  - app/views/application/create.js.erb
200
230
  - app/views/application/destroy.js.erb
@@ -244,7 +274,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
244
274
  - !ruby/object:Gem::Version
245
275
  version: '0'
246
276
  requirements: []
247
- rubygems_version: 3.4.10
277
+ rubygems_version: 3.3.7
248
278
  signing_key:
249
279
  specification_version: 4
250
280
  summary: Make any controller an effective resource controller.