Reputation: 3558
Here is the code block that is chocking rubocop:
def self.browser_not_supported(browser)
return true if browser.chrome? && browser.version.to_i < AppConfig.requirements['browser_google'].to_i
return true if browser.firefox? && browser.version.to_i < AppConfig.requirements['browser_firefox'].to_i
return true if browser.safari? && browser.version.to_i < AppConfig.requirements['browser_safari'].to_i
return true if browser.ie? && browser.version.to_i < AppConfig.requirements['browser_msft'].to_i
return true unless browser.modern?
end
The goal of this function is to determine which browser the customer is using via the browser gem. If the customer is using a legacy browser we kick them out of the application asking them to upgrade. Right now, I have this ignore so the cop does not choke but I am curious how experts out there would rework this.
Please note this code is also used in an initializer:
Rails.configuration.middleware.use Browser::Middleware do
redirect_to '/error/browser-upgrade-required' if ApplicationHelper.browser_not_supported(browser)
end
Upvotes: 1
Views: 646
Reputation: 4639
I might do something like this. Eval
in this circumstance can be used safely because nothing user submitted is being evaluated. It's all code you control.
def self.browser_not_supported(browser)
unsupported?(browser) || !browser.modern?
end
private
def self.unsupported?(browser)
browsers.any? do |name, tech_name|
if eval("#{browser}.#{name}?")
browser.version.to_i < AppConfig.requirements[tech_name].to_i
end
end
end
def self.browsers
{
chrome: 'browser_google',
firefox: 'browser_firefox',
safari: 'browser_safari',
ie: 'browser_msft'
}
end
Upvotes: 0
Reputation: 5721
I would recommend splitting your large method into a bunch of smaller methods and using instance variables to help reduce the duplication:
class BrowserChecker
def initialize(browser)
@browser = browser
@version = browser.version.to_i
end
def browser_not_supported?
[email protected]? || chrome_bad? || firefox_bad? || io_bad?
end
private
def chrome_bad?
@browser.chrome? && @version < AppConfig.requirements['browser_google'].to_i
end
def firefox_bad?
@browser.firefox? && @version < AppConfig.requirements['browser_firefox'].to_i
end
def safari_bad?
@browser.safari? && @version < AppConfig.requirements['browser_safari'].to_i
end
def ie_bad?
@browser.ie? && @version < AppConfig.requirements['browser_msft'].to_i
end
end
# called like this
BrowserChecker.new(some_browser_object)
As a style preference, I have also appended each of the methods with a question mark to indicate they return booleans.
You could also use a bit of metaprogramming magic to have ruby write the [browser]_bad?
functions for you but that may end up less readable:
class BrowserChecker
def initialize(browser)
@browser = browser
end
def browser_not_supported
[email protected]? || chrome_bad? || firefox_bad? || io_bad?
end
['google', 'firefox', 'safari', 'msft'].each do |browser|
define_method "#{browser}_bad?".to_sym do
@browser.send("#{browser}?".to_sym) && @version < AppConfig.requirements["browser_#{browser}"].to_i
end
end
end
I haven't run this code so please excuse a few typos.
Upvotes: 1