activerecord-pretty-comparator 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0d0a276c6bc57bf58455e2750accf54fc6337a123478ca10f15178a8c8be69a0
4
+ data.tar.gz: 848f9be30dfcd6a3fc8e445fdeb9ca0eff50764a490d7479706e68e2a6c0007d
5
+ SHA512:
6
+ metadata.gz: 718434cdf54fdff58c6bca95136dc1114fb3b0a5c4a2cb4ce3b4599a8c5139ff3943e26fc912a0ab5c81b0f1158c9e6a90aa41fd852bb33f130aee9d25157c06
7
+ data.tar.gz: 7c15cb186815b80290bf251cf75be55a4752b899ed298e0a8538737f3126c20f5b8fcd36649cb760428a6c9dda756ea8943144a9985e2605ab1500f99a1c5b20
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,28 @@
1
+ require: rubocop-rspec
2
+ AllCops:
3
+ TargetRubyVersion: 3.0
4
+ Exclude:
5
+ - 'activerecord-pretty-comparator.gemspec'
6
+ - 'lib/activerecord-pretty-comparator.rb'
7
+ - 'vendor/**/*'
8
+ RespectGitIgnore: true
9
+ SuggestExtensions: false
10
+
11
+ Style/StringLiterals:
12
+ EnforcedStyle: double_quotes
13
+
14
+ Style/StringLiteralsInInterpolation:
15
+ EnforcedStyle: double_quotes
16
+
17
+ RSpec/IndexedLet:
18
+ Enabled: false
19
+
20
+ RSpec/MultipleExpectations:
21
+ Max: 4
22
+
23
+ RSpec/ExampleLength:
24
+ Max: 6
25
+
26
+ Metrics/BlockLength:
27
+ Exclude:
28
+ - spec/*.rb
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2024-07-17
4
+
5
+ - Initial release
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 technuma
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,100 @@
1
+ # ActiveRecord::Pretty::Comparator
2
+
3
+ A simple ActiveRecord extension to support `where` with comparison operators (`>`, `>=`, `<`, and `<=`).
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'activerecord-pretty-comparator'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install activerecord-pretty-comparator
20
+
21
+
22
+ ## Usage
23
+ ```ruby
24
+ posts = Post.order(:id)
25
+
26
+ posts.where("id >": 9).pluck(:id) # => [10, 11]
27
+ posts.where("id >=": 9).pluck(:id) # => [9, 10, 11]
28
+ posts.where("id <": 3).pluck(:id) # => [1, 2]
29
+ posts.where("id <=": 3).pluck(:id) # => [1, 2, 3]
30
+ ```
31
+
32
+ ## Why not `Post.where("id > ?", 1)` ?
33
+
34
+ As a main contributor of the predicate builder area, [@kamipo](https://github.com/kamipo) recommends
35
+ using the hash syntax, the hash syntax also have other useful
36
+ effects (making boundable queries, unscopeable queries, hash-like
37
+ relation merging friendly, automatic other table references detection).
38
+ ref: https://github.com/rails/rails/pull/39863#issue-659298581
39
+
40
+ ### Merge examples
41
+ ```ruby
42
+ # it doesn't work
43
+ # SELECT `posts`.`id` FROM `posts` WHERE (id > 1) AND `posts`.`id` = ? [["id", 1]]
44
+ Post.where("id > ?", 1).merge(Post.where(id: 1)).pluck(:id) # []
45
+
46
+ # it works
47
+ # SELECT `posts`.`id` FROM `posts` WHERE `posts`.`id` = ? [["id", 1]]
48
+ Post.where("id >": 1).merge(Post.where(id: 1)).pluck(:id) # [1]
49
+ ```
50
+
51
+ ### Unscope examples
52
+ ```ruby
53
+ # it doesn't work
54
+ # SELECT `posts`.* FROM `posts` WHERE (id > 1)
55
+ Post.where("id > ?", 1).unscope(where: :id)
56
+
57
+ # it works
58
+ # SELECT `posts`.* FROM `posts`
59
+ Post.where("id >": 1).unscope(where: :id)
60
+ ```
61
+
62
+ ### Precision examples
63
+ From type casting and table/column name resolution's point of view,
64
+ `where("created_at >=": time)` is better alternative than `where("created_at >= ?", time)`.
65
+
66
+ ```ruby
67
+ class Post < ActiveRecord::Base
68
+ attribute :created_at, :datetime, precision: 3
69
+ end
70
+
71
+ time = Time.now.utc # => 2020-06-24 10:11:12.123456 UTC
72
+
73
+ Post.create!(created_at: time) # => #<Post id: 1, created_at: "2020-06-24 10:11:12.123000">
74
+
75
+ # SELECT `posts`.* FROM `posts` WHERE (created_at >= '2020-06-24 10:11:12.123456')
76
+ Post.where("created_at >= ?", time) # => []
77
+
78
+ # SELECT `posts`.* FROM `posts` WHERE `posts`.`created_at` >= '2020-06-24 10:11:12.123000'
79
+ Post.where("created_at >=": time) # => [#<Post id: 1, created_at: "2020-06-24 10:11:12.123000">]
80
+ ```
81
+
82
+ ## Development
83
+
84
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
85
+
86
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
87
+
88
+ ## Contributing
89
+
90
+ Bug reports and pull requests are welcome on GitHub at https://github.com/technuma/activerecord-pretty-comparator.
91
+
92
+ ## License
93
+
94
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
95
+
96
+ ## Special thanks
97
+
98
+ [@kamipo](https://github.com/kamipo) :bow:
99
+
100
+ Original idea: https://blog.kamipo.net/entry/2021/01/14/191753 (ja)
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Pretty
5
+ module Comparator
6
+ VERSION = "0.1.0"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "comparator/version"
4
+ require "active_record"
5
+
6
+ module ActiveRecord
7
+ module Pretty
8
+ # :nodoc:
9
+ module Comparator
10
+ class Error < StandardError; end
11
+ ActiveSupport.on_load(:active_record) do
12
+ ActiveRecord::PredicateBuilder.prepend(Module.new do
13
+ def [](attr_name, value, operator = nil)
14
+ if !operator && attr_name.end_with?(">", ">=", "<", "<=")
15
+ /\A(?<attr_name>.+?)\s*(?<operator>>|>=|<|<=)\z/ =~ attr_name
16
+ operator = OPERATORS[operator]
17
+ end
18
+
19
+ super
20
+ end
21
+
22
+ OPERATORS = { ">" => :gt, ">=" => :gteq, "<" => :lt, "<=" => :lteq }.freeze # rubocop:disable Lint/ConstantDefinitionInBlock
23
+ end)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1 @@
1
+ require "active_record/pretty/comparator"
@@ -0,0 +1,8 @@
1
+ module ActiveRecord
2
+ module Pretty
3
+ module Comparator
4
+ VERSION: String
5
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
6
+ end
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,155 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activerecord-pretty-comparator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Kazuya Onuma
8
+ - Ryuta Kamizono
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2024-07-19 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '6.1'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '6.1'
28
+ - !ruby/object:Gem::Dependency
29
+ name: database_cleaner
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rake
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rspec
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: rubocop
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: rubocop-rspec
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: sqlite3
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ description: A simple ActiveRecord extension to support where with comparison operators
113
+ (`>`, `>=`, `<`, and `<=`).
114
+ email:
115
+ - technuma@gmail.com
116
+ - kamipo@gmail.com
117
+ executables: []
118
+ extensions: []
119
+ extra_rdoc_files: []
120
+ files:
121
+ - ".rspec"
122
+ - ".rubocop.yml"
123
+ - CHANGELOG.md
124
+ - LICENSE.txt
125
+ - README.md
126
+ - Rakefile
127
+ - lib/active_record/pretty/comparator.rb
128
+ - lib/active_record/pretty/comparator/version.rb
129
+ - lib/activerecord-pretty-comparator.rb
130
+ - sig/activerecord/pretty/comparator.rbs
131
+ homepage: https://github.com/technuma/activerecord-pretty-comparator
132
+ licenses:
133
+ - MIT
134
+ metadata: {}
135
+ post_install_message:
136
+ rdoc_options: []
137
+ require_paths:
138
+ - lib
139
+ required_ruby_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: 3.0.0
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ requirements: []
150
+ rubygems_version: 3.5.9
151
+ signing_key:
152
+ specification_version: 4
153
+ summary: A simple ActiveRecord extension to support where with comparison operators
154
+ (`>`, `>=`, `<`, and `<=`).
155
+ test_files: []