Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enrich with where_null, where_in etc. methods #84

Open
vladfaust opened this issue Mar 26, 2019 · 5 comments
Open

Enrich with where_null, where_in etc. methods #84

vladfaust opened this issue Mar 26, 2019 · 5 comments
Labels
breaking Breaking change idea Just an idea rfc Request For Comments
Milestone

Comments

@vladfaust
Copy link
Member

Inspired by https://knexjs.org/

@vladfaust vladfaust added rfc Request For Comments breaking Breaking change idea Just an idea labels Mar 26, 2019
@vladfaust
Copy link
Member Author

Proposed methods:

where_in(field: Enumerable)
where_null(field)
where_gt(field: Comparable)
where_gte(field: Comparable)
where_lt(field: Comparable)
where_lte(field: Comparable)

Also remove and_*, not_* and or_* methods and replace with .and, .or, .not.

User
  .where_in(status: [:active, :pending])
  .and.where_gte(:age, 18)
  .or.not.where_null(:allow_adult_content)
SELECT * FROM users 
WHERE (status IN (?, ?)) 
AND (WHERE age > 18) 
OR NOT (WHERE allow_adult_content IS NULL)

@vladfaust vladfaust added this to the next minor milestone Apr 6, 2019
@pynixwang
Copy link

where.null
.gt
.lt

@vladfaust
Copy link
Member Author

vladfaust commented Apr 14, 2019

Agreed.

.where(id: 42) # id = 42
.where # For chaining

.not(id: 42) # NOT id = 42
.not # For chaining
.not(&block : self -> _) # See below

.and(id: 42) # (AND) id = 42
.and # For chaining
.and(&block : self -> _) # See below

.or(id: 42) # (OR) id = 42
.or # For chaining
.or(&block : self -> _) # See below

.is_null(:foo) # foo IS NULL
.is_not_null(:foo) # foo IS NOT NULL

.eq(id: 42) # id = 42 (for convenience)
.in(id: {1, 2}) # id IN ?, ?
.gt(id: 1) # id > 1
.gte(id: 1) # id >= 1
.lt(id: 100) # id < 100
.lte(id: 100) # id <= 100

Should add nested conditions to wrap them with parenthesis:

.or do |x|
  typeof(x) # => self
end

Examples:

User.where.is_not_null(:bio)
WHERE (bio IS NOT NULL)
User
  .where.in(status: [:pending, :activated])
  .or(&.is_null(:violation).and.gte(:reputation, 100))
WHERE (status IN ?, ?) OR ((violation IS NULL) AND (reputation >= ?))

@Blacksmoke16
Copy link

An easier way to do LIKE queries would also be helpful.

@vladfaust
Copy link
Member Author

How should we deal with such a bug?

User.where.join(posts: true) # Forgot to put the continuation after .where

A. Raise in runtime upon building the query, something like Cannot append empty WHERE clause
B. Ignore .where call and just build the query (assuming there is anything else in the callchain)
C. Return to #84 (comment) proposal

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking Breaking change idea Just an idea rfc Request For Comments
Projects
None yet
Development

No branches or pull requests

3 participants