-
Notifications
You must be signed in to change notification settings - Fork 61
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
Ability to create selectors passing symbols #95
Comments
That can actually become nasty !
... I was wondering why I had so many users in my test database :P ( |
Personally I really think we should not override things like e.g. |
You're right. But maybe we could define an extra convenience method that preprocesses the inputs so as to replace "meaningful enums" by their "meaningless database representation" Something like that def preprocess_enums_in_hash(class, hash={})
preprocessed_hash = {}
hash.each do |key,val|
# The key corresponds to an enum value ? if yes convert it to {key_cd, integer_value_of(value)}
# EX : {gender: :male} should be converted to {gender_cd: 0} because we know :gender is an enum declared in the class class
if is_enum_of(class, key)?
enum_symbol = "#{key.to_s}_cd" # Also handle the case where enums are prefixed
enum_value = integer_value_of_enum(class, enum_symbol, val)
preprocessed_hash << {:enum_symbol => enum_value}
else
# Don't modify the current (key, val) of the hash
preprocessed_hash << {key => val}
end
end
preprocessed_hash
end Then Person.where(preprocess_enums_in_hash(Person, {age: 21, gender: :male} Would become Person.where(age: 21, gender_cd: 0} |
All right if somebody can start a Pull Request I'm happy to merge, one thing I'd prefer it to be optional, so that an additional file needs to be required or something and that it registers itself as extension. Update: from an "API" perspective I'd rather have it be something like |
I vote for the As per the name, something like |
I vote for
In my mind, it was external because it reminded me of |
@Startouf as per the nature of the gem, I was imagining it used for DB queries only, otherwise a simple Also, in my mind, the method should also take care of dealing with lists of values and translate them into the right DB selector, e.g.:
Hence the name I came up with. Does this make sense to everybody? |
We should go with |
I believe ActiveRecord/Mongoid are already doing the transformations from |
Yes, correct, I think at the moment we should focus on the following: { gender: :male } # => { gender: 0 }
{ gender: [:male, :female] } # => { gender: [0, 1] }
{ foo: "bar", gender: :female } # => { foo: "bar", gender: 1 } |
Do we need the inverse operation ?
|
No, I don't think we need the inversions. |
An intriguing idea was given in #101, to basically add a method like Klass.gender_scope(:female) # => where(gender_cd: 1) this could be extend to allow both single arguments or hashes, with the expansion / support as described above? Klass.gender_scope(gender: :male, foo: "bar") # => where(gender_cd: 0, foo: "bar") |
One thing that often happens to me is to recycle a selector (not a scope) with different classes that extend/include a certain field. The main purpose is to be able to pass a selector to another method without necessarily knowing which class is going to use it (something you can do with whatever other key/value pair). Example: class A
STATUSES = [:active, :paused, :inactive]
as_enum :status, STATUSES, source: :status
end
class B
include A
# more fields
end
class C
include A
# more fields
end Somewhere else: selector = { status: A::STATUSES[:active], another_field: 'abc' } # ideally it'd be `{ status: :active, another_field: 'abc' }`
x = B.where(selector.merge({ yet_another_field: true })).count
y = C.where(selector.merge({ one_more_field: 25 })).first I don't think the suggested method would make easier achieving such goal, unless we provide also the ability to get the selector only. |
@lucke84 why isn't it possible with the selector = { status: :active, field: 'abc' }
x = B.xxx_scope(selector.merge(yet_another_field: true)).count
y = C.xxx_scope(selector.merge(one_more_field: 25)).first |
That's right, it should work. Cool! Can we also think about adding support for a generic e.g.: Klass.where_with_enum({ status: :active, another_enum: :something }).first instead of Klass.status_scope({ status: :active, another_enum: :something }).first |
Hey, so I introduced Project.where(
status_cd: [
Project.statuses(:pending),
Project.statuses(:active)
]) So I added the scope, and now I can just say Project.status_scope([:pending, :active]) If I want to chain these Project.status_scope(:active).language_scope(:ruby) I can see why it might be cool to write in a single call Project.where_with_enum(status: :active, language: :ruby) (In my head I'd call it |
I should also say, ie. Project.status_scope(:doesnt_exist) and Project.where_with_enum(status: :doesn't_exist) should both raise an |
+1 @matthewrudy that is exactly my point :) |
@matthewrudy, wow, nice work 👍 and I assume you basically delegate Any chance you can already create WIP pull request so we can take a look at the code? |
I might be too late but i would prefer
|
👍 thanks for the input and no you are not too late, development of v3 has been kind of stale recently, sorry for that. Update and my tendency is also towards |
I am for not having single scopes too. Has any work been done in this direction? |
@aledalgrande, no AFAIK no work has been done into this direction yet. |
Let's say we have a simple Mongoid model:
As far as I can see (correct me if I'm wrong!), it's not possible to query using a selector that takes the symbol corresponding to a value of an enum, like this:
while instead is possible to do this:
I'm aware of the fact that it's possible to use chained selectors, like this:
but in our codebase we often build selectors as hashes that are passed to instances of different classes.
Besides this maybe not being the best approach of all times, IMHO it'd be very beneficial to be able to consume the gem in a consistent way, always passing the symbol (key of the hash), not the value.
Do you think it's a complicated matter? Can you give me pointers to where to look at, so maybe I can submit a PR?
The text was updated successfully, but these errors were encountered: