Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add a scope for multiple enums in rails

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

like image 549
Cesar Avatar asked Jan 09 '23 10:01

Cesar


2 Answers

Not sure if you're still looking for something like this but here's what I found.

Solution

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:

  1. User.for_states :one_state
  2. User.for_states :state_1, :state_2
  3. User.for_states [:state_1, :state_2]

If you don't need the method to be as flexible, it could be simplified.

The Future

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])
like image 73
Aaron Avatar answered Jan 19 '23 05:01

Aaron


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])
 }
like image 32
Cesar Avatar answered Jan 19 '23 06:01

Cesar