Rubocop complains: Style/GuardClause: Use a guard clause instead of wrapping the code inside a conditional expression. if issue_flag == true && issue_notification_sent && !issue_notification_follow_up_sent && send_follow_up ^^
My original code is
if issue_flag == true && issue_notification_sent && !issue_notification_follow_up_sent && send_follow_up
email_address = "[email protected]"
puts "Emailing Follow Up #{email_address} - #{sales_order}"
UserMailer.issue_notification(self, email_address).deliver_now
update(issue_notification_follow_up_sent: true)
end
and from reading the docs, it seems that I can solve this by implementing the following code instead:
return unless issue_flag == true && issue_notification_sent && !issue_notification_follow_up_sent && send_follow_up
email_address = "[email protected]"
puts "Emailing Follow Up #{email_address} - #{sales_order}"
UserMailer.issue_notification(self, email_address).deliver_now
update(issue_notification_follow_up_sent: true)
I can see that this essentially breaks early from the method unless the condition is met, but to me, this seems less readable. It also seems less maintainable as further conditionals cannot be added after this code unless they pass the condition on the first line, for instance, to execute something else if issue_flag == true && !issue_notification_sent
(anything matching this condition would have already returned on line 1 of the refactored code above).
Is there a better way to refactor this so that more conditions could be added after the code below, without the code returning prematurely?
Thanks.
I think we can do something like below
# issue_flag is boolean so we can directly put it
# create a new method with all the condition and give a proper name
return unless issue_flag && send_follow_up? # change name accourdingly
email_address = "[email protected]"
puts "Emailing Follow Up #{email_address} - #{sales_order}"
UserMailer.issue_notification(self, email_address).deliver_now
update(issue_notification_follow_up_sent: true)
end
# document its behaviour
def send_follow_up?
issue_notification_sent && !issue_notification_follow_up_sent && send_follow_up
end
The guard structure is used to send the control out of block so if you need change something or do something after the condition then you will not be able to use the guard clause. Have a look at the below code in such scenarios we will not use guard clause
def test
if something_here?
do_something
end
do_something_else
do_something_else1
do_something_else2
end