active_record_in_time_scope 0.1.7 → 0.1.8
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/README.md +76 -0
- data/lib/active_record_in_time_scope/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1c7368eb997ae0a2489562309c633db819e903274260d88295476fd964071b12
|
|
4
|
+
data.tar.gz: 8aeebd6b5cac7f98646d0b035560cc027d046b9f9164c9b0390aeb73ecafb594
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8a6bcd19c674377ae8216a8b4bd67e2a3233d3dec766bd1549a45f864c3688574d372397179047e0b1d664371258c5c21585e0dfd5104b37f40ade7d437b73bc
|
|
7
|
+
data.tar.gz: 05057f9961c6767269d048fc4fefcb3e7f7fd628785d104efbfa84762d24381fbaa81b7f273a6a2be3410690f265d93f6da85ba0a6e3d2f521bb50ab3f34a778
|
data/README.md
CHANGED
|
@@ -95,6 +95,20 @@ end
|
|
|
95
95
|
|
|
96
96
|
For records where each row is valid until the next one:
|
|
97
97
|
|
|
98
|
+
| id | user_id | amount | start_at |
|
|
99
|
+
|----|---------|--------|------------|
|
|
100
|
+
| 1 | 1 | 100 | 2024-10-01 |
|
|
101
|
+
| 2 | 1 | 120 | 2024-10-10 |
|
|
102
|
+
| 3 | 1 | 150 | 2024-10-15 |
|
|
103
|
+
|
|
104
|
+
```ruby
|
|
105
|
+
# Time.current = 2024-10-20 → row id=3 (latest) is selected
|
|
106
|
+
Price.in_time
|
|
107
|
+
|
|
108
|
+
# 2024-10-12 → row id=2 (latest before 10/12) is selected
|
|
109
|
+
Price.in_time(Time.parse("2024-10-12"))
|
|
110
|
+
```
|
|
111
|
+
|
|
98
112
|
```ruby
|
|
99
113
|
class Price < ActiveRecord::Base
|
|
100
114
|
in_time_scope start_at: { null: false }, end_at: { column: nil }
|
|
@@ -108,10 +122,56 @@ end
|
|
|
108
122
|
User.includes(:current_price) # No N+1, fetches only latest per user
|
|
109
123
|
```
|
|
110
124
|
|
|
125
|
+
**`latest_in_time` — latest record per FK before the given time:**
|
|
126
|
+
|
|
127
|
+
```mermaid
|
|
128
|
+
flowchart LR
|
|
129
|
+
A["id=1\n10/01"] --> B["id=2\n10/10"] --> C["id=3\n10/15"]
|
|
130
|
+
T(["⏱ time=10/20"]) -.->|latest_in_time| C
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
──────●──────────●──────────●──────────▶ time
|
|
135
|
+
10/01 10/10 10/15 10/20(now)
|
|
136
|
+
id=1 id=2 id=3
|
|
137
|
+
↑
|
|
138
|
+
latest_in_time
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**`earliest_in_time` — earliest record per FK before the given time:**
|
|
142
|
+
|
|
143
|
+
```mermaid
|
|
144
|
+
flowchart LR
|
|
145
|
+
A["id=1\n10/01"] --> B["id=2\n10/10"] --> C["id=3\n10/15"]
|
|
146
|
+
T(["⏱ time=10/20"]) -.->|earliest_in_time| A
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
──────●──────────●──────────●──────────▶ time
|
|
151
|
+
10/01 10/10 10/15 10/20(now)
|
|
152
|
+
id=1 id=2 id=3
|
|
153
|
+
↑
|
|
154
|
+
earliest_in_time
|
|
155
|
+
```
|
|
156
|
+
|
|
111
157
|
### End-Only Pattern (Expiration)
|
|
112
158
|
|
|
113
159
|
For records that are active until they expire:
|
|
114
160
|
|
|
161
|
+
| id | code | expired_at |
|
|
162
|
+
|----|------|------------|
|
|
163
|
+
| 1 | ABC | 2024-11-30 |
|
|
164
|
+
| 2 | XYZ | 2024-10-05 |
|
|
165
|
+
| 3 | DEF | 2024-12-31 |
|
|
166
|
+
|
|
167
|
+
```ruby
|
|
168
|
+
# Time.current = 2024-10-20 → id=1 (ABC) and id=3 (DEF) selected (not yet expired)
|
|
169
|
+
Coupon.in_time
|
|
170
|
+
|
|
171
|
+
# 2024-10-06 → id=1 (ABC) and id=3 (DEF) selected (XYZ expired on 10/05)
|
|
172
|
+
Coupon.in_time(Time.parse("2024-10-06"))
|
|
173
|
+
```
|
|
174
|
+
|
|
115
175
|
```ruby
|
|
116
176
|
class Coupon < ActiveRecord::Base
|
|
117
177
|
in_time_scope start_at: { column: nil }, end_at: { null: false }
|
|
@@ -120,6 +180,22 @@ end
|
|
|
120
180
|
|
|
121
181
|
### Inverse Scopes
|
|
122
182
|
|
|
183
|
+
```mermaid
|
|
184
|
+
flowchart LR
|
|
185
|
+
A["before_in_time"] -->|"● start_at"| B["in_time"] -->|"○ end_at"| C["after_in_time"]
|
|
186
|
+
D["out_of_time"] -->|"● start_at"| B
|
|
187
|
+
B -->|"○ end_at"| E["out_of_time"]
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
before_in_time │ in_time │ after_in_time
|
|
192
|
+
───────────────●─────────────────────○──────────────▶ time
|
|
193
|
+
start_at end_at
|
|
194
|
+
|
|
195
|
+
out_of_time │ in_time │ out_of_time
|
|
196
|
+
───────────────●─────────────────────○──────────────▶ time
|
|
197
|
+
```
|
|
198
|
+
|
|
123
199
|
Query records outside the time window:
|
|
124
200
|
|
|
125
201
|
```ruby
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: active_record_in_time_scope
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- kyohah
|
|
@@ -217,7 +217,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
217
217
|
- !ruby/object:Gem::Version
|
|
218
218
|
version: '0'
|
|
219
219
|
requirements: []
|
|
220
|
-
rubygems_version: 4.0.
|
|
220
|
+
rubygems_version: 4.0.3
|
|
221
221
|
specification_version: 4
|
|
222
222
|
summary: Add time-window scopes to ActiveRecord models
|
|
223
223
|
test_files: []
|