risa 1.0.0 → 1.0.2

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: f9f9703449e9c46799c4f74b3f098e067c54c6e39427adefdbfd14f9a5b0632e
4
- data.tar.gz: ee592c3adbaee9f4bb8f6a89effdc0e34fef0db44c0bd62f3662d5a356ec0846
3
+ metadata.gz: 8c8013dc8881f7cb09ede1757d465eac8902f24efd9d7d7028ff8d7c08bb6563
4
+ data.tar.gz: c8754eae69616d994f370003c43e91e05b31654c08c6ec3c3549dc6e8ca07da9
5
5
  SHA512:
6
- metadata.gz: d52bfc90c0505cdf35933e25e475e9aa016b660c9779952f135bf3b4ff6cb74e11e6dd9edf964807ef760c84d456da08b8729a58a84c28952de11900f3024241
7
- data.tar.gz: c1cebfe5caa8eb97d495ac554b4df86b3658024d95d578c240fa80e86ea5138caf3a4ef48487eea3183adc7a4a59ab394e5cfb5660fa139dfaf83ff788dab7c7
6
+ metadata.gz: 15a92f5133c83ce7d4ea7e4544a6aa31f14699be0667b5ca1df762501866838ec4d02da33dfa652e09dd1a3731263c3d119de2d073c233a3c62ecf6b749bba6d
7
+ data.tar.gz: 1a88eb4c601cc3e573536cc0d6030e8a2d8328c98d488dc9d9ca06b05c77229c661094a6299c3f4722ab969c260af809e77b9d243eb4497b2314a013943dee2d
data/CHANGELOG.md CHANGED
@@ -1,3 +1,4 @@
1
+
1
2
  # Changelog
2
3
 
3
4
  All notable changes to this project will be documented in this file.
@@ -7,6 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
8
 
8
9
  ---
9
10
 
11
+ ## [1.0.2] - 2025-11-09
12
+
13
+ ### 💥 Changed
14
+ * Updated the `rs()` helper for the more idiomatic `all()` helper
15
+
10
16
  ## [1.0.1] - 2025-11-01
11
17
 
12
18
  ### 🐛 Fixed
@@ -118,7 +124,7 @@ This is the first stable 1.0 release! It introduces auto-loading and finalizes t
118
124
 
119
125
  ### 🐛 Fixed
120
126
  * Fixed a `NoMethodError` when using `.order` on a key where some records had a `nil` value. Nils are now always sorted last by default.
121
- * `rs(:model).first` on an empty dataset now correctly returns `nil` instead of raising an error.
127
+ * `all(:model).first` on an empty dataset now correctly returns `nil` instead of raising an error.
122
128
 
123
129
  ## [0.1.0] - 2025-04-10
124
130
 
@@ -126,7 +132,7 @@ This is the first stable 1.0 release! It introduces auto-loading and finalizes t
126
132
  * **Initial Release!**
127
133
  * `Risa.define(:model_name)` block.
128
134
  * `from_array([...])` data source.
129
- * Global `rs()` helper for easy querying.
135
+ * Global `all()` helper for easy querying.
130
136
  * Basic `.where(key: value)` for exact matching.
131
137
  * `.order(:key)` for ascending sort.
132
138
  * Query execution methods: `.to_a`, `.first`, `.last`, `.each`.
data/README.md CHANGED
@@ -27,7 +27,7 @@ Risa.define :posts do
27
27
  end
28
28
 
29
29
  # Query it like you always wished you could:
30
- rs(:posts).where(published: true).order(:created_at, desc: true).first[:title]
30
+ all(:posts).where(published: true).order(:created_at, desc: true).first[:title]
31
31
  # => "Hello World"
32
32
  ```
33
33
 
@@ -60,7 +60,7 @@ Risa.define :posts do
60
60
  end
61
61
 
62
62
  # Query like you always wanted to:
63
- popular_ruby_posts = rs(:posts)
63
+ popular_ruby_posts = all(:posts)
64
64
  .where(tags: { contains: 'ruby' })
65
65
  .where(views: { greater_than: 1000 })
66
66
  .order(:views, desc: true)
@@ -69,7 +69,7 @@ popular_ruby_posts = rs(:posts)
69
69
  puts popular_ruby_posts.first[:title] # => "Why I Love Ruby"
70
70
  ```
71
71
 
72
- That global `rs()` helper? It's there because life's too short to type `Risa.query()` every time.
72
+ That global `all()` helper? It's there because life's too short to type `Risa.query()` every time.
73
73
 
74
74
  ---
75
75
 
@@ -152,8 +152,8 @@ Risa.define :posts do
152
152
  end
153
153
 
154
154
  # Now your queries read like English:
155
- trending_ruby_posts = rs(:posts).published.tagged('ruby').popular.recent(5)
156
- featured_content = rs(:posts).published.featured.recent
155
+ trending_ruby_posts = all(:posts).published.tagged('ruby').popular.recent(5)
156
+ featured_content = all(:posts).published.featured.recent
157
157
  ```
158
158
 
159
159
  Scopes are chainable, composable, and parameterizable. They're basically custom query methods that don't suck.
@@ -167,7 +167,7 @@ Risa provides a fluent, chainable API for filtering and sorting your data. Queri
167
167
  ### Basic Queries (The Classics)
168
168
 
169
169
  ```ruby
170
- posts = rs(:posts) # Get the query builder for :posts
170
+ posts = all(:posts) # Get the query builder for :posts
171
171
 
172
172
  # Get results
173
173
  posts.to_a # Get all matching records as an array of Risa::InstanceWrapper objects
@@ -188,10 +188,10 @@ Chain multiple `.where` calls or provide multiple conditions in a hash to combin
188
188
 
189
189
  ```ruby
190
190
  # Find published posts tagged 'ruby'
191
- rs(:posts).where(published: true).where(tags: { contains: 'ruby' })
191
+ all(:posts).where(published: true).where(tags: { contains: 'ruby' })
192
192
 
193
193
  # Equivalent using a single hash
194
- rs(:posts).where(published: true, tags: { contains: 'ruby' })
194
+ all(:posts).where(published: true, tags: { contains: 'ruby' })
195
195
  ```
196
196
 
197
197
  ### OR Logic (`or_where`)
@@ -200,7 +200,7 @@ Use `.or_where` to add conditions combined with `OR`.
200
200
 
201
201
  ```ruby
202
202
  # Find posts that are featured OR have more than 1000 views
203
- rs(:posts).where(featured: true).or_where(views: { greater_than: 1000 })
203
+ all(:posts).where(featured: true).or_where(views: { greater_than: 1000 })
204
204
  # => WHERE featured = true OR views > 1000
205
205
  ```
206
206
 
@@ -210,23 +210,23 @@ Use blocks with `where` and `or_where` to create nested logical groups. Conditio
210
210
 
211
211
  ```ruby
212
212
  # Find posts where (author_id = 1 AND published = true)
213
- rs(:posts).where do |q|
213
+ all(:posts).where do |q|
214
214
  q.where(author_id: 1).where(published: true)
215
215
  end
216
216
 
217
217
  # Find posts where (author_id = 1 AND (published = true OR featured = true))
218
- rs(:posts).where(author_id: 1).where do |q|
218
+ all(:posts).where(author_id: 1).where do |q|
219
219
  q.where(published: true).or_where(featured: true)
220
220
  end
221
221
  # => WHERE author_id = 1 AND (published = true OR featured = true)
222
222
 
223
223
  # Find posts where (author_id = 1 AND published = true) OR (views > 1000)
224
- rs(:posts).where { |q| q.where(author_id: 1).where(published: true) }
224
+ all(:posts).where { |q| q.where(author_id: 1).where(published: true) }
225
225
  .or_where(views: { greater_than: 1000 })
226
226
  # => WHERE (author_id = 1 AND published = true) OR views > 1000
227
227
 
228
228
  # Find posts where (author_id = 1 AND published = true) OR (author_id = 2 AND featured = true)
229
- rs(:posts).where { |q| q.where(author_id: 1).where(published: true) }
229
+ all(:posts).where { |q| q.where(author_id: 1).where(published: true) }
230
230
  .or_where { |q| q.where(author_id: 2).where(featured: true) }
231
231
  # => WHERE (author_id = 1 AND published = true) OR (author_id = 2 AND featured = true)
232
232
  ```
@@ -237,32 +237,32 @@ Use hash conditions within `where` or `or_where` for powerful comparisons and ne
237
237
 
238
238
  ```ruby
239
239
  # Text searches
240
- rs(:posts).where(title: { contains: 'Ruby' })
241
- rs(:posts).where(title: { starts_with: 'How to' })
242
- rs(:posts).where(title: { ends_with: '101' })
240
+ all(:posts).where(title: { contains: 'Ruby' })
241
+ all(:posts).where(title: { starts_with: 'How to' })
242
+ all(:posts).where(title: { ends_with: '101' })
243
243
 
244
244
  # Numeric comparisons
245
- rs(:posts).where(views: { greater_than: 1000 })
246
- rs(:posts).where(views: { less_than_or_equal: 500 })
247
- rs(:posts).where(score: { from: 7.5, to: 9.0 }) # Inclusive range
248
- rs(:posts).where(views: 100..500) # Ruby Range works too
245
+ all(:posts).where(views: { greater_than: 1000 })
246
+ all(:posts).where(views: { less_than_or_equal: 500 })
247
+ all(:posts).where(score: { from: 7.5, to: 9.0 }) # Inclusive range
248
+ all(:posts).where(views: 100..500) # Ruby Range works too
249
249
 
250
250
  # Existence and emptiness
251
- rs(:posts).where(featured_image: { exists: true }) # Key is present and not nil
252
- rs(:posts).where(featured_image: { exists: false }) # Key is missing or nil
253
- rs(:posts).where(tags: { empty: false }) # Not nil, not '', not []
254
- rs(:posts).where(tags: { empty: true }) # Is nil, '', or []
251
+ all(:posts).where(featured_image: { exists: true }) # Key is present and not nil
252
+ all(:posts).where(featured_image: { exists: false }) # Key is missing or nil
253
+ all(:posts).where(tags: { empty: false }) # Not nil, not '', not []
254
+ all(:posts).where(tags: { empty: true }) # Is nil, '', or []
255
255
 
256
256
  # Array / Set operations
257
- rs(:posts).where(id: { in: [1, 3, 5] }) # Value is one of these
258
- rs(:posts).where(id: [1, 3, 5]) # Shortcut for :in
259
- rs(:posts).where(status: { not_in: ['draft', 'archived'] }) # Value is NOT one of these
260
- rs(:posts).where(tags: ['ruby', 'web']) # Exact array match (order matters)
257
+ all(:posts).where(id: { in: [1, 3, 5] }) # Value is one of these
258
+ all(:posts).where(id: [1, 3, 5]) # Shortcut for :in
259
+ all(:posts).where(status: { not_in: ['draft', 'archived'] }) # Value is NOT one of these
260
+ all(:posts).where(tags: ['ruby', 'web']) # Exact array match (order matters)
261
261
 
262
262
  # Negation
263
- rs(:posts).where(published: { not: true }) # Value is not true (false or nil)
264
- rs(:posts).where(title: { not: 'Hello' }) # Value is not 'Hello'
265
- rs(:posts).where(views: { not: nil }) # Same as { exists: true }
263
+ all(:posts).where(published: { not: true }) # Value is not true (false or nil)
264
+ all(:posts).where(title: { not: 'Hello' }) # Value is not 'Hello'
265
+ all(:posts).where(views: { not: nil }) # Same as { exists: true }
266
266
  ```
267
267
 
268
268
  ### Ordering (Nil-Safe and Type-Aware)
@@ -271,13 +271,13 @@ Sort your results using `.order`. Nils are always sorted last.
271
271
 
272
272
  ```ruby
273
273
  # Ascending (default)
274
- rs(:posts).order(:published_at)
274
+ all(:posts).order(:published_at)
275
275
 
276
276
  # Descending
277
- rs(:posts).order(:views, desc: true)
277
+ all(:posts).order(:views, desc: true)
278
278
 
279
279
  # Strings sort naturally
280
- rs(:posts).order(:title)
280
+ all(:posts).order(:title)
281
281
  ```
282
282
 
283
283
  Mixed types? No problem. Risa handles the type coercion so you don't have to think about it during sorting.
@@ -287,11 +287,11 @@ Mixed types? No problem. Risa handles the type coercion so you don't have to thi
287
287
 
288
288
  ```ruby
289
289
  # Classic pagination
290
- rs(:posts).limit(10) # First 10
291
- rs(:posts).offset(20).limit(10) # Items 21-30
290
+ all(:posts).limit(10) # First 10
291
+ all(:posts).offset(20).limit(10) # Items 21-30
292
292
 
293
293
  # Modern pagination with metadata
294
- pages = rs(:posts).order(:created_at, desc: true).paginate(per_page: 5)
294
+ pages = all(:posts).order(:created_at, desc: true).paginate(per_page: 5)
295
295
 
296
296
  page = pages.first
297
297
  page.items # Array of posts for this page
@@ -318,7 +318,7 @@ The Page object has everything you need for pagination UI without any mental mat
318
318
  Results aren't plain hashes—they're immutable wrappers that feel like hashes but prevent accidents:
319
319
 
320
320
  ```ruby
321
- post = rs(:posts).first
321
+ post = all(:posts).first
322
322
 
323
323
  # Access like a hash (symbol or string keys both work)
324
324
  post[:title] # => "Hello World"
@@ -353,7 +353,7 @@ Risa.reload
353
353
  Risa.defined_models # => [:posts, :users, :tags]
354
354
 
355
355
  # Use the explicit API when you need it
356
- Risa.query(:posts).where(...) # Same as rs(:posts).where(...)
356
+ Risa.query(:posts).where(...) # Same as all(:posts).where(...)
357
357
  ```
358
358
 
359
359
  Error messages are actually helpful:
@@ -416,9 +416,9 @@ end
416
416
  Access related data using simple dot notation on your `Risa::InstanceWrapper` objects.
417
417
 
418
418
  ```ruby
419
- alice = rs(:authors).find_by(id: 1)
420
- post = rs(:posts).find_by(id: 101)
421
- profile = rs(:profiles).find_by(profile_id: 201)
419
+ alice = all(:authors).find_by(id: 1)
420
+ post = all(:posts).find_by(id: 101)
421
+ profile = all(:profiles).find_by(profile_id: 201)
422
422
 
423
423
  # Belongs To (returns InstanceWrapper or nil)
424
424
  author_name = post.author.name
@@ -459,11 +459,11 @@ Risa.define :posts do
459
459
  belongs_to :creator, class_name: :users, foreign_key: :creator_id, primary_key: :user_pk
460
460
  end
461
461
 
462
- admin = rs(:users).first
462
+ admin = all(:users).first
463
463
  admin_article_title = admin.articles.first.title
464
464
  # => "Admin Post"
465
465
 
466
- post = rs(:posts).find_by(id: 105)
466
+ post = all(:posts).find_by(id: 105)
467
467
  creator_name = post.creator.username
468
468
  # => "admin"
469
469
  ```
@@ -498,11 +498,11 @@ Risa.define :post_tags do # The join collection
498
498
  end
499
499
 
500
500
  # Usage:
501
- post = rs(:posts).find_by(id: 101)
501
+ post = all(:posts).find_by(id: 101)
502
502
  tag_names = post.tags.map { |t| t.name }
503
503
  # => ["ruby", "web"]
504
504
 
505
- tag = rs(:tags).find_by(name: 'ruby')
505
+ tag = all(:tags).find_by(name: 'ruby')
506
506
  post_titles = tag.posts.map { |p| p.title }
507
507
  # => ["Intro to Risa", "Advanced Ruby"]
508
508
 
@@ -561,7 +561,7 @@ end
561
561
  Presenter methods are automatically available directly on the `InstanceWrapper` objects returned by your queries.
562
562
 
563
563
  ```ruby
564
- post = rs(:posts).first
564
+ post = all(:posts).first
565
565
 
566
566
  # Access hash data keys
567
567
  puts post.id # => 1
@@ -601,8 +601,8 @@ require 'hr'
601
601
  Risa.load_from('data') # Loads all .rb files in data/
602
602
 
603
603
  # Now all collections are available
604
- rs(:users).where(active: true)
605
- rs(:posts).order(:created_at)
604
+ all(:users).where(active: true)
605
+ all(:posts).order(:created_at)
606
606
  ```
607
607
 
608
608
  **Development mode reloading:**
data/lib/risa/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Risa
2
- VERSION = "1.0.0"
2
+ VERSION = "1.0.2"
3
3
  end
data/lib/risa.rb CHANGED
@@ -85,6 +85,6 @@ module Risa
85
85
  end
86
86
  end
87
87
 
88
- def rs(model_name)
88
+ def all(model_name)
89
89
  Risa.query(model_name)
90
90
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: risa
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Garcia