type_scopes 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e6f3c1b8e9ddeff61759d2244082f11058895dd1
4
+ data.tar.gz: 388729c5dee7cd2e6fd6668e558618ad68a236b4
5
+ SHA512:
6
+ metadata.gz: 9abff35463947151c2ab63053c7fda13ee2107c08f4a979ef0354224a20ea0dd6686392e49ae0319ed053f5df7473b9717e6838ffe983e81a4835627d310e277
7
+ data.tar.gz: 1dd119ba66eba838255ae0d7458e03459b7a493d01a489f2883d9ec093e9e9aa2651b10a878f4bd8f7fc53d72764702b5cb94a6da397cd5a549fa6cb9390a48a
data/README.md ADDED
@@ -0,0 +1,68 @@
1
+ # Type Scopes
2
+
3
+ Type scopes creates useful scopes based on the type of the columns of your models.
4
+ It handles dates, times, strings and numerics.
5
+
6
+ Here is an example of all the available scopes:
7
+
8
+ ```ruby
9
+ # paid_at: datetime
10
+ # amount: decimal
11
+ # description: string
12
+ class Transaction < ActiveRecord::Base
13
+ include TypeScopes
14
+ end
15
+
16
+ # Time scopes
17
+ Transaction.paid_to("2017-09-06") # => where("paid_to <= '2017-09-06'")
18
+ Transaction.paid_from("2017-09-06") # => where("paid_to >= '2017-09-06'")
19
+ Transaction.paid_after("2017-09-06") # => where("paid_to > '2017-09-06'")
20
+ Transaction.paid_before("2017-09-06") #= where("paid_to < '2017-09-06'")
21
+ Transaction.paid_between("2017-09-06", "2017-09-07") # => where("paid_to BETWEEN '2017-09-06' AND '2017-09-07'")
22
+
23
+ # Numeric scopes
24
+ Transaction.amount_to(100) # => where("amount <= 100")
25
+ Transaction.amount_from(100) # => where("amount >= 100")
26
+ Transaction.amount_above(100) # => where("amount > 100")
27
+ Transaction.amount_below(100) # => where("amount < 100")
28
+ Transaction.amount_between(100, 200) # => where("amount BETWEEN 100 AND 200")
29
+
30
+ # String scopes
31
+ Transaction.description_contains("foo") # => where("description LIKE '%foo%'")
32
+ Transaction.description_starts_with("foo") # => where("description LIKE 'foo%'")
33
+ Transaction.description_ends_with("foo") # => where("description LIKE '%foo'")
34
+ ```
35
+
36
+ For the string scope the pattern matching is escaped:
37
+
38
+ ```ruby
39
+ Transaction.description_contains("%foo_") # => where("description LIKE '%[%]foo[_]%'")
40
+ ```
41
+
42
+ ## Install
43
+
44
+ Add to your Gemfile:
45
+
46
+ ```ruby
47
+ gem "type_scopes"
48
+ ```
49
+
50
+ And run in your terminal:
51
+
52
+ ```shell
53
+ bundle install
54
+ ```
55
+
56
+ Then include TypeScopes from your models:
57
+
58
+ ```ruby
59
+ class Transaction < ActiveRecord::Base
60
+ include TypeScopes
61
+ end
62
+ ```
63
+
64
+ ## MIT License
65
+
66
+ Made by [Base Secrète](https://basesecrete.com/en).
67
+
68
+ Rails developer? Check out [RoRvsWild](https://www.rorvswild.com), our Ruby on Rails application monitoring tool.
@@ -0,0 +1,24 @@
1
+ module NumericScopes
2
+ def self.included(model)
3
+ model.extend(ClassMethods)
4
+ model.create_numeric_scopes
5
+ end
6
+
7
+ module ClassMethods
8
+ def create_numeric_scopes
9
+ for column in columns
10
+ if column.sql_type.index("integer") == 0
11
+ create_numeric_scopes_for_column(column.name)
12
+ end
13
+ end
14
+ end
15
+
16
+ def create_numeric_scopes_for_column(name)
17
+ scope :"#{name}_to", lambda { |value| where("#{quoted_table_name}.#{name} <= ?", value) }
18
+ scope :"#{name}_from", lambda { |value| where("#{quoted_table_name}.#{name} >= ?", value) }
19
+ scope :"#{name}_above", lambda { |value| where("#{quoted_table_name}.#{name} > ?", value) }
20
+ scope :"#{name}_below", lambda { |value| where("#{quoted_table_name}.#{name} < ?", value) }
21
+ scope :"#{name}_between", lambda { |from, to| where("#{quoted_table_name}.#{name} BETWEEN ? AND ?", from, to) }
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,28 @@
1
+ module StringScopes
2
+ def self.included(model)
3
+ model.extend(ClassMethods)
4
+ model.create_string_scopes
5
+ end
6
+
7
+ def self.escape(string)
8
+ string = string.gsub("%".freeze, "[%]".freeze)
9
+ string.gsub!("_".freeze, "[_]".freeze)
10
+ string
11
+ end
12
+
13
+ module ClassMethods
14
+ def create_string_scopes
15
+ for column in columns
16
+ if column.sql_type.index("character") == 0 || column.sql_type.index("text") == 0
17
+ create_string_scopes_for_column(column.name)
18
+ end
19
+ end
20
+ end
21
+
22
+ def create_string_scopes_for_column(name)
23
+ scope :"#{name}_contains", lambda { |str| where("#{quoted_table_name}.#{name} LIKE ?", "%#{StringScopes.escape(str)}%") }
24
+ scope :"#{name}_starts_with", lambda { |str| where("#{quoted_table_name}.#{name} LIKE ?", "#{StringScopes.escape(str)}%") }
25
+ scope :"#{name}_ends_with", lambda { |str| where("#{quoted_table_name}.#{name} LIKE ?", "%#{StringScopes.escape(str)}") }
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,29 @@
1
+ module TimestampScopes
2
+ def self.included(model)
3
+ model.extend(ClassMethods)
4
+ model.create_timestamp_scopes
5
+ end
6
+
7
+ module ClassMethods
8
+ def create_timestamp_scopes
9
+ for column in columns
10
+ if column.sql_type.index("timestamp") == 0
11
+ create_timestamp_scopes_for_column(column.name)
12
+ end
13
+ end
14
+ end
15
+
16
+ def create_timestamp_scopes_for_column(name)
17
+ short_name = shorten_column_name(name)
18
+ scope :"#{short_name}_to", lambda { |date| where("#{quoted_table_name}.#{name} <= ?", date) }
19
+ scope :"#{short_name}_from", lambda { |date| where("#{quoted_table_name}.#{name} >= ?", date) }
20
+ scope :"#{short_name}_after", lambda { |date| where("#{quoted_table_name}.#{name} > ?", date) }
21
+ scope :"#{short_name}_before", lambda { |date| where("#{quoted_table_name}.#{name} < ?", date) }
22
+ scope :"#{short_name}_between", lambda { |from, to| where("#{quoted_table_name}.#{name} BETWEEN ? AND ?", from, to) }
23
+ end
24
+
25
+ def shorten_column_name(name)
26
+ name.chomp("_at").chomp("_on")
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,3 @@
1
+ module TypeScopes
2
+ VERSION = "0.1.0".freeze
3
+ end
@@ -0,0 +1,11 @@
1
+ require "string_scopes"
2
+ require "numeric_scopes"
3
+ require "timestamp_scopes"
4
+
5
+ module TypeScopes
6
+ def self.included(model)
7
+ model.include(StringScopes)
8
+ model.include(NumericScopes)
9
+ model.include(TimestampScopes)
10
+ end
11
+ end
@@ -0,0 +1,20 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'type_scopes/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "type_scopes"
8
+ spec.version = TypeScopes::VERSION
9
+ spec.authors = ["Alexis Bernard"]
10
+ spec.email = ["alexis@bernard.io"]
11
+ spec.summary = "Automatic scopes for ActiveRecord models."
12
+ spec.description = "Useful scopes based on columns' types (dates, times, strings and numerics)."
13
+ spec.homepage = "https://github.com/BaseSecrete/type_scopes"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+ end
metadata ADDED
@@ -0,0 +1,52 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: type_scopes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Alexis Bernard
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-09-06 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Useful scopes based on columns' types (dates, times, strings and numerics).
14
+ email:
15
+ - alexis@bernard.io
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - README.md
21
+ - lib/numeric_scopes.rb
22
+ - lib/string_scopes.rb
23
+ - lib/timestamp_scopes.rb
24
+ - lib/type_scopes.rb
25
+ - lib/type_scopes/version.rb
26
+ - type_scopes.gemspec
27
+ homepage: https://github.com/BaseSecrete/type_scopes
28
+ licenses:
29
+ - MIT
30
+ metadata: {}
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubyforge_project:
47
+ rubygems_version: 2.4.8
48
+ signing_key:
49
+ specification_version: 4
50
+ summary: Automatic scopes for ActiveRecord models.
51
+ test_files: []
52
+ has_rdoc: