Reputation: 1610
I have a select that displays all enums of an object:
<%= f.select( :state_user
, User.states.keys.map {|state| [state.titleize,state] }) %>
How can I create an scope that allows me to select multiple states?
For example I want to filter all users that are either inactive or suspended.
Thanks
Upvotes: 4
Views: 2119
Reputation: 14029
Not sure if you're still looking for something like this but here's what I found.
I was able to implement this using the following
scope :for_states, -> (*state_names) {
where(state: states.values_at(*Array(state_names).flatten))
}
The *state_names
argument will allow any number of arguments to get packaged up into a state_names
array. Array(state_names)
ensures that this if a single argument was passed it will be treated as an array. Finally, flatten
allows a single array to be passed as an argument. After all that, the splat (*
) unpacks all elements of this array as arguments to the values_at
method.
You can use this as follows:
User.for_states :one_state
User.for_states :state_1, :state_2
User.for_states [:state_1, :state_2]
If you don't need the method to be as flexible, it could be simplified.
According to the Edge Rails Docs this should be even simpler in Rails 5 and you'll simply be able to do
User.where(state: [:state_1, :state_2])
Upvotes: 8
Reputation: 1610
I got it working with this scope:
scope :state, lambda { |enum_ids|
return nil if enum_ids.empty?
objArray = []
enum_ids.each do |key|
if (User.estados[key])
objArray << User.estados[key]
end
end
return nil if objArray.empty?
where (["account.state in (?)" , objArray])
}
Upvotes: 2