mr_muscle
mr_muscle

Reputation: 2900

Ruby case multiple conditions with and

I've got below case condition which works well.

case params[:event_type]
when 'publish'
  StoreActivityWorker.perform_async(params)
when 'delete'
  DeleteActivityWorker.perform_async(params)
end

But I want to add another conditions to each when - name == %w[Text Video Audio] so the code should be like:

case params[:event_type]
when 'publish' && name == %w[Text Video Audio]
  StoreActivityWorker.perform_async(params)
when 'delete' && name == %w[Text Video Audio]
  DeleteActivityWorker.perform_async(params)
end

but it won't work, it shows false every time.

name is just:

params.dig('entity', 'relationships', 'item_type', 'data', 'name')

Upvotes: 1

Views: 135

Answers (2)

user1934428
user1934428

Reputation: 22217

The expression 'publish' && name == %w[Text Video Audio] does not make sense. Remember that && is a shortcut operator: (E1) && (E2) evaluates E1, and if the result is falsy, returns this value (i.e. nil or false), without even looking at E2. If E1 is trueish, it evaluates and returns E2. In your case, 'publish' is trueish, and hence E2 is returned.

Your E2 is

name == %w[Text Video Audio]

and this expression evaluates to either be true or false, and neither can match your params[:event_type], because the event type is likely not truenor false, but a string, and therefore the condition does not fire.

Upvotes: 0

Viktor
Viktor

Reputation: 2783

Currently you're checking if

('publish' && name == %w[Text Video Audio]) === params[:event_type]

or if

('delete' && name == %w[Text Video Audio]) === params[:event_type]

The left side of === can be either true or false and I don't think params[:event_type] is going to be either of those two values, so neither of your two cases are going to be executed.

What you probably want is something like:

if name == %w[Text Video Audio]
  case params[:event_type]
  when 'publish'
    StoreActivityWorker.perform_async(params)
  when 'delete'
    DeleteActivityWorker.perform_async(params)
  end
end

Even that seems a bit off since you're checking if name is equal to %w[Text Video Audio] which I don't think is going to be the case. Perhaps you want:

%w[Text Video Audio].include?(name)

A nested case inside of an if statement is also not the best option. I might suggest a guard clause but without knowing the entire method it's hard to tell.

Upvotes: 2

Related Questions