Unsafe reflection method constantize called with parameter value Open
@related_to_item = params[:relate_to_type].constantize.find(params[:relate_to_item])
- Read upRead up
- Exclude checks
Brakeman reports on several cases of remote code execution, in which a user is able to control and execute code in ways unintended by application authors.
The obvious form of this is the use of eval
with user input.
However, Brakeman also reports on dangerous uses of send
, constantize
, and other methods which allow creation of arbitrary objects or calling of arbitrary methods.
Possible SQL injection Open
@basket_stats_hash["#{zoom_class}_private"] = basket.send(zoom_class.tableize).count(conditions: private_conditions)
- Read upRead up
- Exclude checks
Injection is #1 on the 2013 OWASP Top Ten web security risks. SQL injection is when a user is able to manipulate a value which is used unsafely inside a SQL query. This can lead to data leaks, data loss, elevation of privilege, and other unpleasant outcomes.
Brakeman focuses on ActiveRecord methods dealing with building SQL statements.
A basic (Rails 2.x) example looks like this:
User.first(:conditions => "username = '#{params[:username]}'")
Brakeman would produce a warning like this:
Possible SQL injection near line 30: User.first(:conditions => ("username = '#{params[:username]}'"))
The safe way to do this query is to use a parameterized query:
User.first(:conditions => ["username = ?", params[:username]])
Brakeman also understands the new Rails 3.x way of doing things (and local variables and concatenation):
username = params[:user][:name].downcase
password = params[:user][:password]
User.first.where("username = '" + username + "' AND password = '" + password + "'")
This results in this kind of warning:
Possible SQL injection near line 37:
User.first.where((((("username = '" + params[:user][:name].downcase) + "' AND password = '") + params[:user][:password]) + "'"))
See the Ruby Security Guide for more information and Rails-SQLi.org for many examples of SQL injection in Rails.
Possible unprotected redirect Open
redirect_to service_target
- Read upRead up
- Exclude checks
Unvalidated redirects and forwards are #10 on the OWASP Top Ten.
Redirects which rely on user-supplied values can be used to "spoof" websites or hide malicious links in otherwise harmless-looking URLs. They can also allow access to restricted areas of a site if the destination is not validated.
Brakeman will raise warnings whenever redirect_to
appears to be used with a user-supplied value that may allow them to change the :host
option.
For example,
redirect_to params.merge(:action => :home)
will create a warning like
Possible unprotected redirect near line 46: redirect_to(params)
This is because params
could contain :host => 'evilsite.com'
which would redirect away from your site and to a malicious site.
If the first argument to redirect_to
is a hash, then adding :only_path => true
will limit the redirect to the current host. Another option is to specify the host explicitly.
redirect_to params.merge(:only_path => true)
redirect_to params.merge(:host => 'myhost.com')
If the first argument is a string, then it is possible to parse the string and extract the path:
redirect_to URI.parse(some_url).path
If the URL does not contain a protocol (e.g., http://
), then you will probably get unexpected results, as redirect_to
will prepend the current host name and a protocol.
Unsafe reflection method constantize called with parameter value Open
@relate_to_item = params[:relate_to_type].constantize.find(params[:relate_to_item])
- Read upRead up
- Exclude checks
Brakeman reports on several cases of remote code execution, in which a user is able to control and execute code in ways unintended by application authors.
The obvious form of this is the use of eval
with user input.
However, Brakeman also reports on dangerous uses of send
, constantize
, and other methods which allow creation of arbitrary objects or calling of arbitrary methods.
Possible unprotected redirect Open
redirect_to redirect_registration.new_url, status: redirect_registration.status_code
- Read upRead up
- Exclude checks
Unvalidated redirects and forwards are #10 on the OWASP Top Ten.
Redirects which rely on user-supplied values can be used to "spoof" websites or hide malicious links in otherwise harmless-looking URLs. They can also allow access to restricted areas of a site if the destination is not validated.
Brakeman will raise warnings whenever redirect_to
appears to be used with a user-supplied value that may allow them to change the :host
option.
For example,
redirect_to params.merge(:action => :home)
will create a warning like
Possible unprotected redirect near line 46: redirect_to(params)
This is because params
could contain :host => 'evilsite.com'
which would redirect away from your site and to a malicious site.
If the first argument to redirect_to
is a hash, then adding :only_path => true
will limit the redirect to the current host. Another option is to specify the host explicitly.
redirect_to params.merge(:only_path => true)
redirect_to params.merge(:host => 'myhost.com')
If the first argument is a string, then it is possible to parse the string and extract the path:
redirect_to URI.parse(some_url).path
If the URL does not contain a protocol (e.g., http://
), then you will probably get unexpected results, as redirect_to
will prepend the current host name and a protocol.
Possible unprotected redirect Open
redirect_to "/#{@site_basket.urlified_name}"
- Read upRead up
- Exclude checks
Unvalidated redirects and forwards are #10 on the OWASP Top Ten.
Redirects which rely on user-supplied values can be used to "spoof" websites or hide malicious links in otherwise harmless-looking URLs. They can also allow access to restricted areas of a site if the destination is not validated.
Brakeman will raise warnings whenever redirect_to
appears to be used with a user-supplied value that may allow them to change the :host
option.
For example,
redirect_to params.merge(:action => :home)
will create a warning like
Possible unprotected redirect near line 46: redirect_to(params)
This is because params
could contain :host => 'evilsite.com'
which would redirect away from your site and to a malicious site.
If the first argument to redirect_to
is a hash, then adding :only_path => true
will limit the redirect to the current host. Another option is to specify the host explicitly.
redirect_to params.merge(:only_path => true)
redirect_to params.merge(:host => 'myhost.com')
If the first argument is a string, then it is possible to parse the string and extract the path:
redirect_to URI.parse(some_url).path
If the URL does not contain a protocol (e.g., http://
), then you will probably get unexpected results, as redirect_to
will prepend the current host name and a protocol.
User controlled method execution Open
@existing_relation = @related_to_item.send(params[:related_class].tableize).include?(item)
- Read upRead up
- Exclude checks
Using unfiltered user data to select a Class or Method to be dynamically sent is dangerous.
It is much safer to whitelist the desired target or method.
Unsafe use of method:
method = params[:method]
@result = User.send(method.to_sym)
Safe:
method = params[:method] == 1 ? :method_a : :method_b
@result = User.send(method, *args)
Unsafe use of target:
table = params[:table]
model = table.classify.constantize
@result = model.send(:method)
Safe:
target = params[:target] == 1 ? Account : User
@result = target.send(:method, *args)
Including user data in the arguments passed to an Object#send is safe, as long as the method can properly handle potentially bad data.
Safe:
args = params["args"] || []
@result = User.send(:method, *args)
Unsafe reflection method constantize called with parameter value Open
@related_to_item = params[:relate_to_type].constantize.find(params[:relate_to_item])
- Read upRead up
- Exclude checks
Brakeman reports on several cases of remote code execution, in which a user is able to control and execute code in ways unintended by application authors.
The obvious form of this is the use of eval
with user input.
However, Brakeman also reports on dangerous uses of send
, constantize
, and other methods which allow creation of arbitrary objects or calling of arbitrary methods.
Class has too many lines. [610/100] Open
class ApplicationController < ActionController::Base
# helper :all # include all helpers, all the time
protect_from_forgery # See ActionController::RequestForgeryProtection for details
include DefaultUrlOptions
- Read upRead up
- Exclude checks
This cop checks if the length a class exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable.
Assignment Branch Condition size for setup_related_topic_and_zoom_and_redirect is too high. [99.22/15] Open
def setup_related_topic_and_zoom_and_redirect(item, commented_item = nil, options = {})
where_to_redirect = 'show_self'
if !commented_item.nil? && @successful
update_zoom_and_related_caches_for(commented_item)
where_to_redirect = 'commentable'
- Read upRead up
- Exclude checks
This cop checks that the ABC size of methods is not higher than the configured maximum. The ABC size is based on assignments, branches (method calls), and conditions. See http://c2.com/cgi/wiki?AbcMetric
File application_controller.rb
has 611 lines of code (exceeds 250 allowed). Consider refactoring. Open
class ApplicationController < ActionController::Base
# helper :all # include all helpers, all the time
protect_from_forgery # See ActionController::RequestForgeryProtection for details
include DefaultUrlOptions
Class ApplicationController
has 56 methods (exceeds 20 allowed). Consider refactoring. Open
class ApplicationController < ActionController::Base
# helper :all # include all helpers, all the time
protect_from_forgery # See ActionController::RequestForgeryProtection for details
include DefaultUrlOptions
Method has too many lines. [52/10] Open
def setup_related_topic_and_zoom_and_redirect(item, commented_item = nil, options = {})
where_to_redirect = 'show_self'
if !commented_item.nil? && @successful
update_zoom_and_related_caches_for(commented_item)
where_to_redirect = 'commentable'
- Read upRead up
- Exclude checks
This cop checks if the length of a method exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable.
Assignment Branch Condition size for derive_url_for_rss is too high. [51.98/15] Open
def derive_url_for_rss(options = {})
replace_page_with_rss = !options[:replace_page_with_rss].nil? ? options[:replace_page_with_rss] : false
page = !options.blank? && !options[:page].blank? ? options[:page] : nil
- Read upRead up
- Exclude checks
This cop checks that the ABC size of methods is not higher than the configured maximum. The ABC size is based on assignments, branches (method calls), and conditions. See http://c2.com/cgi/wiki?AbcMetric
Assignment Branch Condition size for link_related is too high. [43.98/15] Open
def link_related
@related_to_item = params[:relate_to_type].constantize.find(params[:relate_to_item])
unless params[:item].blank?
for id in params[:item].reject { |k, v| v != 'true' }.collect { |k, v| k }
- Read upRead up
- Exclude checks
This cop checks that the ABC size of methods is not higher than the configured maximum. The ABC size is based on assignments, branches (method calls), and conditions. See http://c2.com/cgi/wiki?AbcMetric
Assignment Branch Condition size for prepare_item_and_vars is too high. [39.64/15] Open
def prepare_item_and_vars
zoom_class = zoom_class_from_controller(params[:controller])
if !ZOOM_CLASSES.member?(zoom_class)
raise(ArgumentError, "zoom_class name expected. #{zoom_class} is not registered in #{ZOOM_CLASSES}.")
end
- Read upRead up
- Exclude checks
This cop checks that the ABC size of methods is not higher than the configured maximum. The ABC size is based on assignments, branches (method calls), and conditions. See http://c2.com/cgi/wiki?AbcMetric
Cyclomatic complexity for setup_related_topic_and_zoom_and_redirect is too high. [29/6] Open
def setup_related_topic_and_zoom_and_redirect(item, commented_item = nil, options = {})
where_to_redirect = 'show_self'
if !commented_item.nil? && @successful
update_zoom_and_related_caches_for(commented_item)
where_to_redirect = 'commentable'
- Read upRead up
- Exclude checks
This cop checks that the cyclomatic complexity of methods is not higher than the configured maximum. The cyclomatic complexity is the number of linearly independent paths through a method. The algorithm counts decision points and adds one.
An if statement (or unless or ?:) increases the complexity by one. An else branch does not, since it doesn't add a decision point. The && operator (or keyword and) can be converted to a nested if statement, and ||/or is shorthand for a sequence of ifs, so they also add one. Loops can be said to have an exit condition, so they add one.
Method has too many lines. [32/10] Open
def derive_url_for_rss(options = {})
replace_page_with_rss = !options[:replace_page_with_rss].nil? ? options[:replace_page_with_rss] : false
page = !options.blank? && !options[:page].blank? ? options[:page] : nil
- Read upRead up
- Exclude checks
This cop checks if the length of a method exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable.
Perceived complexity for setup_related_topic_and_zoom_and_redirect is too high. [29/7] Open
def setup_related_topic_and_zoom_and_redirect(item, commented_item = nil, options = {})
where_to_redirect = 'show_self'
if !commented_item.nil? && @successful
update_zoom_and_related_caches_for(commented_item)
where_to_redirect = 'commentable'
- Read upRead up
- Exclude checks
This cop tries to produce a complexity score that's a measure of the
complexity the reader experiences when looking at a method. For that
reason it considers when
nodes as something that doesn't add as much
complexity as an if
or a &&
. Except if it's one of those special
case
/when
constructs where there's no expression after case
. Then
the cop treats it as an if
/elsif
/elsif
... and lets all the when
nodes count. In contrast to the CyclomaticComplexity cop, this cop
considers else
nodes as adding complexity.
Example:
def my_method # 1
if cond # 1
case var # 2 (0.8 + 4 * 0.2, rounded)
when 1 then func_one
when 2 then func_two
when 3 then func_three
when 4..10 then func_other
end
else # 1
do_something until a && b # 2
end # ===
end # 7 complexity points
Assignment Branch Condition size for render_full_width_content_wrapper? is too high. [37/15] Open
def render_full_width_content_wrapper?
if @displaying_error
false
elsif (params[:controller] == 'baskets') && ['edit', 'update', 'homepage_options', 'appearance'].include?(params[:action])
false
- Read upRead up
- Exclude checks
This cop checks that the ABC size of methods is not higher than the configured maximum. The ABC size is based on assignments, branches (method calls), and conditions. See http://c2.com/cgi/wiki?AbcMetric
Method has too many lines. [27/10] Open
def rescue_action_in_public(exception)
@displaying_error = true
# when an exception occurs, before filters arn't called, so we have to manually call them here
# only call the ones absolutely nessesary (required settings, themes, permissions etc)
- Read upRead up
- Exclude checks
This cop checks if the length of a method exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable.
Method has too many lines. [27/10] Open
def load_standard_baskets
# could DRY this up with one query for all the baskets
@site_basket ||= Basket.site_basket
@help_basket ||= Basket.help_basket
@about_basket ||= Basket.about_basket
- Read upRead up
- Exclude checks
This cop checks if the length of a method exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable.
Method has too many lines. [27/10] Open
def prepare_item_and_vars
zoom_class = zoom_class_from_controller(params[:controller])
if !ZOOM_CLASSES.member?(zoom_class)
raise(ArgumentError, "zoom_class name expected. #{zoom_class} is not registered in #{ZOOM_CLASSES}.")
end
- Read upRead up
- Exclude checks
This cop checks if the length of a method exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable.
Assignment Branch Condition size for after_successful_zoom_item_update is too high. [29.02/15] Open
def after_successful_zoom_item_update(item, version_after_update)
version_created = version_after_update ? item.versions.exists?(version: version_after_update) : false
# if we need to add a contributor (sometimes, a version isn't
# created if only timestamps were updated. In that case. we
- Read upRead up
- Exclude checks
This cop checks that the ABC size of methods is not higher than the configured maximum. The ABC size is based on assignments, branches (method calls), and conditions. See http://c2.com/cgi/wiki?AbcMetric
Assignment Branch Condition size for unlink_related is too high. [28.35/15] Open
def unlink_related
@related_to_item = params[:relate_to_type].constantize.find(params[:relate_to_item])
unless params[:item].blank?
for id in params[:item].reject { |k, v| v != 'true' }.collect { |k, v| k }
- Read upRead up
- Exclude checks
This cop checks that the ABC size of methods is not higher than the configured maximum. The ABC size is based on assignments, branches (method calls), and conditions. See http://c2.com/cgi/wiki?AbcMetric
Assignment Branch Condition size for load_standard_baskets is too high. [28.67/15] Open
def load_standard_baskets
# could DRY this up with one query for all the baskets
@site_basket ||= Basket.site_basket
@help_basket ||= Basket.help_basket
@about_basket ||= Basket.about_basket
- Read upRead up
- Exclude checks
This cop checks that the ABC size of methods is not higher than the configured maximum. The ABC size is based on assignments, branches (method calls), and conditions. See http://c2.com/cgi/wiki?AbcMetric
Method has too many lines. [21/10] Open
def link_related
@related_to_item = params[:relate_to_type].constantize.find(params[:relate_to_item])
unless params[:item].blank?
for id in params[:item].reject { |k, v| v != 'true' }.collect { |k, v| k }
- Read upRead up
- Exclude checks
This cop checks if the length of a method exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable.
Assignment Branch Condition size for set_locale is too high. [26.4/15] Open
def set_locale
available_locales = I18n.available_locales_with_labels
if params[:locale] && available_locales.key?(params[:locale])
I18n.locale = params[:locale]
elsif session[:locale] && available_locales.key?(session[:locale])
- Read upRead up
- Exclude checks
This cop checks that the ABC size of methods is not higher than the configured maximum. The ABC size is based on assignments, branches (method calls), and conditions. See http://c2.com/cgi/wiki?AbcMetric
Method setup_related_topic_and_zoom_and_redirect
has a Cognitive Complexity of 21 (exceeds 5 allowed). Consider refactoring. Open
def setup_related_topic_and_zoom_and_redirect(item, commented_item = nil, options = {})
where_to_redirect = 'show_self'
if !commented_item.nil? && @successful
update_zoom_and_related_caches_for(commented_item)
where_to_redirect = 'commentable'
- Read upRead up
Cognitive Complexity
Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.
A method's cognitive complexity is based on a few simple rules:
- Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
- Code is considered more complex for each "break in the linear flow of the code"
- Code is considered more complex when "flow breaking structures are nested"
Further reading
Method has too many lines. [20/10] Open
def stats_by_type_for(basket)
# prepare a hash of all the stats, so it's nice and easy to pass to partial
@basket_stats_hash = {}
# special case: site basket contains everything
# all contents of site basket plus all other baskets' contents
- Read upRead up
- Exclude checks
This cop checks if the length of a method exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable.
Method derive_url_for_rss
has a Cognitive Complexity of 20 (exceeds 5 allowed). Consider refactoring. Open
def derive_url_for_rss(options = {})
replace_page_with_rss = !options[:replace_page_with_rss].nil? ? options[:replace_page_with_rss] : false
page = !options.blank? && !options[:page].blank? ? options[:page] : nil
- Read upRead up
Cognitive Complexity
Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.
A method's cognitive complexity is based on a few simple rules:
- Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
- Code is considered more complex for each "break in the linear flow of the code"
- Code is considered more complex when "flow breaking structures are nested"
Further reading
Method has too many lines. [19/10] Open
def render_full_width_content_wrapper?
if @displaying_error
false
elsif (params[:controller] == 'baskets') && ['edit', 'update', 'homepage_options', 'appearance'].include?(params[:action])
false
- Read upRead up
- Exclude checks
This cop checks if the length of a method exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable.
Method has too many lines. [18/10] Open
def path_to_show_for(item, options = {})
# By default, assume redirect to public version.
options = {
private: false
}.merge(options)
- Read upRead up
- Exclude checks
This cop checks if the length of a method exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable.
Cyclomatic complexity for derive_url_for_rss is too high. [14/6] Open
def derive_url_for_rss(options = {})
replace_page_with_rss = !options[:replace_page_with_rss].nil? ? options[:replace_page_with_rss] : false
page = !options.blank? && !options[:page].blank? ? options[:page] : nil
- Read upRead up
- Exclude checks
This cop checks that the cyclomatic complexity of methods is not higher than the configured maximum. The cyclomatic complexity is the number of linearly independent paths through a method. The algorithm counts decision points and adds one.
An if statement (or unless or ?:) increases the complexity by one. An else branch does not, since it doesn't add a decision point. The && operator (or keyword and) can be converted to a nested if statement, and ||/or is shorthand for a sequence of ifs, so they also add one. Loops can be said to have an exit condition, so they add one.
Method has too many lines. [18/10] Open
def correct_url_for(item, version = nil)
correct_action = version.nil? ? 'show' : 'preview'
options = { action: correct_action, id: item }
options[:version] = version if correct_action == 'preview'
- Read upRead up
- Exclude checks
This cop checks if the length of a method exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable.
Perceived complexity for derive_url_for_rss is too high. [14/7] Open
def derive_url_for_rss(options = {})
replace_page_with_rss = !options[:replace_page_with_rss].nil? ? options[:replace_page_with_rss] : false
page = !options.blank? && !options[:page].blank? ? options[:page] : nil
- Read upRead up
- Exclude checks
This cop tries to produce a complexity score that's a measure of the
complexity the reader experiences when looking at a method. For that
reason it considers when
nodes as something that doesn't add as much
complexity as an if
or a &&
. Except if it's one of those special
case
/when
constructs where there's no expression after case
. Then
the cop treats it as an if
/elsif
/elsif
... and lets all the when
nodes count. In contrast to the CyclomaticComplexity cop, this cop
considers else
nodes as adding complexity.
Example:
def my_method # 1
if cond # 1
case var # 2 (0.8 + 4 * 0.2, rounded)
when 1 then func_one
when 2 then func_two
when 3 then func_three
when 4..10 then func_other
end
else # 1
do_something until a && b # 2
end # ===
end # 7 complexity points
Perceived complexity for render_full_width_content_wrapper? is too high. [14/7] Open
def render_full_width_content_wrapper?
if @displaying_error
false
elsif (params[:controller] == 'baskets') && ['edit', 'update', 'homepage_options', 'appearance'].include?(params[:action])
false
- Read upRead up
- Exclude checks
This cop tries to produce a complexity score that's a measure of the
complexity the reader experiences when looking at a method. For that
reason it considers when
nodes as something that doesn't add as much
complexity as an if
or a &&
. Except if it's one of those special
case
/when
constructs where there's no expression after case
. Then
the cop treats it as an if
/elsif
/elsif
... and lets all the when
nodes count. In contrast to the CyclomaticComplexity cop, this cop
considers else
nodes as adding complexity.
Example:
def my_method # 1
if cond # 1
case var # 2 (0.8 + 4 * 0.2, rounded)
when 1 then func_one
when 2 then func_two
when 3 then func_three
when 4..10 then func_other
end
else # 1
do_something until a && b # 2
end # ===
end # 7 complexity points
Cyclomatic complexity for render_full_width_content_wrapper? is too high. [13/6] Open
def render_full_width_content_wrapper?
if @displaying_error
false
elsif (params[:controller] == 'baskets') && ['edit', 'update', 'homepage_options', 'appearance'].include?(params[:action])
false
- Read upRead up
- Exclude checks
This cop checks that the cyclomatic complexity of methods is not higher than the configured maximum. The cyclomatic complexity is the number of linearly independent paths through a method. The algorithm counts decision points and adds one.
An if statement (or unless or ?:) increases the complexity by one. An else branch does not, since it doesn't add a decision point. The && operator (or keyword and) can be converted to a nested if statement, and ||/or is shorthand for a sequence of ifs, so they also add one. Loops can be said to have an exit condition, so they add one.
Assignment Branch Condition size for rescue_action_in_public is too high. [22.38/15] Open
def rescue_action_in_public(exception)
@displaying_error = true
# when an exception occurs, before filters arn't called, so we have to manually call them here
# only call the ones absolutely nessesary (required settings, themes, permissions etc)
- Read upRead up
- Exclude checks
This cop checks that the ABC size of methods is not higher than the configured maximum. The ABC size is based on assignments, branches (method calls), and conditions. See http://c2.com/cgi/wiki?AbcMetric
Cyclomatic complexity for prepare_item_and_vars is too high. [12/6] Open
def prepare_item_and_vars
zoom_class = zoom_class_from_controller(params[:controller])
if !ZOOM_CLASSES.member?(zoom_class)
raise(ArgumentError, "zoom_class name expected. #{zoom_class} is not registered in #{ZOOM_CLASSES}.")
end
- Read upRead up
- Exclude checks
This cop checks that the cyclomatic complexity of methods is not higher than the configured maximum. The cyclomatic complexity is the number of linearly independent paths through a method. The algorithm counts decision points and adds one.
An if statement (or unless or ?:) increases the complexity by one. An else branch does not, since it doesn't add a decision point. The && operator (or keyword and) can be converted to a nested if statement, and ||/or is shorthand for a sequence of ifs, so they also add one. Loops can be said to have an exit condition, so they add one.
Perceived complexity for prepare_item_and_vars is too high. [13/7] Open
def prepare_item_and_vars
zoom_class = zoom_class_from_controller(params[:controller])
if !ZOOM_CLASSES.member?(zoom_class)
raise(ArgumentError, "zoom_class name expected. #{zoom_class} is not registered in #{ZOOM_CLASSES}.")
end
- Read upRead up
- Exclude checks
This cop tries to produce a complexity score that's a measure of the
complexity the reader experiences when looking at a method. For that
reason it considers when
nodes as something that doesn't add as much
complexity as an if
or a &&
. Except if it's one of those special
case
/when
constructs where there's no expression after case
. Then
the cop treats it as an if
/elsif
/elsif
... and lets all the when
nodes count. In contrast to the CyclomaticComplexity cop, this cop
considers else
nodes as adding complexity.
Example:
def my_method # 1
if cond # 1
case var # 2 (0.8 + 4 * 0.2, rounded)
when 1 then func_one
when 2 then func_two
when 3 then func_three
when 4..10 then func_other
end
else # 1
do_something until a && b # 2
end # ===
end # 7 complexity points
Assignment Branch Condition size for correct_url_for is too high. [19.21/15] Open
def correct_url_for(item, version = nil)
correct_action = version.nil? ? 'show' : 'preview'
options = { action: correct_action, id: item }
options[:version] = version if correct_action == 'preview'
- Read upRead up
- Exclude checks
This cop checks that the ABC size of methods is not higher than the configured maximum. The ABC size is based on assignments, branches (method calls), and conditions. See http://c2.com/cgi/wiki?AbcMetric
Assignment Branch Condition size for stats_by_type_for is too high. [19.82/15] Open
def stats_by_type_for(basket)
# prepare a hash of all the stats, so it's nice and easy to pass to partial
@basket_stats_hash = {}
# special case: site basket contains everything
# all contents of site basket plus all other baskets' contents
- Read upRead up
- Exclude checks
This cop checks that the ABC size of methods is not higher than the configured maximum. The ABC size is based on assignments, branches (method calls), and conditions. See http://c2.com/cgi/wiki?AbcMetric
Method link_related
has a Cognitive Complexity of 16 (exceeds 5 allowed). Consider refactoring. Open
def link_related
@related_to_item = params[:relate_to_type].constantize.find(params[:relate_to_item])
unless params[:item].blank?
for id in params[:item].reject { |k, v| v != 'true' }.collect { |k, v| k }
- Read upRead up
Cognitive Complexity
Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.
A method's cognitive complexity is based on a few simple rules:
- Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
- Code is considered more complex for each "break in the linear flow of the code"
- Code is considered more complex when "flow breaking structures are nested"
Further reading
Method setup_related_topic_and_zoom_and_redirect
has 52 lines of code (exceeds 25 allowed). Consider refactoring. Open
def setup_related_topic_and_zoom_and_redirect(item, commented_item = nil, options = {})
where_to_redirect = 'show_self'
if !commented_item.nil? && @successful
update_zoom_and_related_caches_for(commented_item)
where_to_redirect = 'commentable'
Method has too many lines. [13/10] Open
def after_successful_zoom_item_update(item, version_after_update)
version_created = version_after_update ? item.versions.exists?(version: version_after_update) : false
# if we need to add a contributor (sometimes, a version isn't
# created if only timestamps were updated. In that case. we
- Read upRead up
- Exclude checks
This cop checks if the length of a method exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable.
Method prepare_item_and_vars
has a Cognitive Complexity of 15 (exceeds 5 allowed). Consider refactoring. Open
def prepare_item_and_vars
zoom_class = zoom_class_from_controller(params[:controller])
if !ZOOM_CLASSES.member?(zoom_class)
raise(ArgumentError, "zoom_class name expected. #{zoom_class} is not registered in #{ZOOM_CLASSES}.")
end
- Read upRead up
Cognitive Complexity
Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.
A method's cognitive complexity is based on a few simple rules:
- Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
- Code is considered more complex for each "break in the linear flow of the code"
- Code is considered more complex when "flow breaking structures are nested"
Further reading
Cyclomatic complexity for after_successful_zoom_item_update is too high. [8/6] Open
def after_successful_zoom_item_update(item, version_after_update)
version_created = version_after_update ? item.versions.exists?(version: version_after_update) : false
# if we need to add a contributor (sometimes, a version isn't
# created if only timestamps were updated. In that case. we
- Read upRead up
- Exclude checks
This cop checks that the cyclomatic complexity of methods is not higher than the configured maximum. The cyclomatic complexity is the number of linearly independent paths through a method. The algorithm counts decision points and adds one.
An if statement (or unless or ?:) increases the complexity by one. An else branch does not, since it doesn't add a decision point. The && operator (or keyword and) can be converted to a nested if statement, and ||/or is shorthand for a sequence of ifs, so they also add one. Loops can be said to have an exit condition, so they add one.
Method has too many lines. [12/10] Open
def update_comments_basket_for(item, original_basket)
if item.class.name != 'Comment'
new_basket = item.basket
if new_basket != original_basket
item.comments.each do |comment|
- Read upRead up
- Exclude checks
This cop checks if the length of a method exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable.
Cyclomatic complexity for load_standard_baskets is too high. [8/6] Open
def load_standard_baskets
# could DRY this up with one query for all the baskets
@site_basket ||= Basket.site_basket
@help_basket ||= Basket.help_basket
@about_basket ||= Basket.about_basket
- Read upRead up
- Exclude checks
This cop checks that the cyclomatic complexity of methods is not higher than the configured maximum. The cyclomatic complexity is the number of linearly independent paths through a method. The algorithm counts decision points and adds one.
An if statement (or unless or ?:) increases the complexity by one. An else branch does not, since it doesn't add a decision point. The && operator (or keyword and) can be converted to a nested if statement, and ||/or is shorthand for a sequence of ifs, so they also add one. Loops can be said to have an exit condition, so they add one.
Cyclomatic complexity for set_locale is too high. [7/6] Open
def set_locale
available_locales = I18n.available_locales_with_labels
if params[:locale] && available_locales.key?(params[:locale])
I18n.locale = params[:locale]
elsif session[:locale] && available_locales.key?(session[:locale])
- Read upRead up
- Exclude checks
This cop checks that the cyclomatic complexity of methods is not higher than the configured maximum. The cyclomatic complexity is the number of linearly independent paths through a method. The algorithm counts decision points and adds one.
An if statement (or unless or ?:) increases the complexity by one. An else branch does not, since it doesn't add a decision point. The && operator (or keyword and) can be converted to a nested if statement, and ||/or is shorthand for a sequence of ifs, so they also add one. Loops can be said to have an exit condition, so they add one.
Method has too many lines. [11/10] Open
def unlink_related
@related_to_item = params[:relate_to_type].constantize.find(params[:relate_to_item])
unless params[:item].blank?
for id in params[:item].reject { |k, v| v != 'true' }.collect { |k, v| k }
- Read upRead up
- Exclude checks
This cop checks if the length of a method exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable.
Perceived complexity for after_successful_zoom_item_update is too high. [8/7] Open
def after_successful_zoom_item_update(item, version_after_update)
version_created = version_after_update ? item.versions.exists?(version: version_after_update) : false
# if we need to add a contributor (sometimes, a version isn't
# created if only timestamps were updated. In that case. we
- Read upRead up
- Exclude checks
This cop tries to produce a complexity score that's a measure of the
complexity the reader experiences when looking at a method. For that
reason it considers when
nodes as something that doesn't add as much
complexity as an if
or a &&
. Except if it's one of those special
case
/when
constructs where there's no expression after case
. Then
the cop treats it as an if
/elsif
/elsif
... and lets all the when
nodes count. In contrast to the CyclomaticComplexity cop, this cop
considers else
nodes as adding complexity.
Example:
def my_method # 1
if cond # 1
case var # 2 (0.8 + 4 * 0.2, rounded)
when 1 then func_one
when 2 then func_two
when 3 then func_three
when 4..10 then func_other
end
else # 1
do_something until a && b # 2
end # ===
end # 7 complexity points
Perceived complexity for link_related is too high. [8/7] Open
def link_related
@related_to_item = params[:relate_to_type].constantize.find(params[:relate_to_item])
unless params[:item].blank?
for id in params[:item].reject { |k, v| v != 'true' }.collect { |k, v| k }
- Read upRead up
- Exclude checks
This cop tries to produce a complexity score that's a measure of the
complexity the reader experiences when looking at a method. For that
reason it considers when
nodes as something that doesn't add as much
complexity as an if
or a &&
. Except if it's one of those special
case
/when
constructs where there's no expression after case
. Then
the cop treats it as an if
/elsif
/elsif
... and lets all the when
nodes count. In contrast to the CyclomaticComplexity cop, this cop
considers else
nodes as adding complexity.
Example:
def my_method # 1
if cond # 1
case var # 2 (0.8 + 4 * 0.2, rounded)
when 1 then func_one
when 2 then func_two
when 3 then func_three
when 4..10 then func_other
end
else # 1
do_something until a && b # 2
end # ===
end # 7 complexity points
Perceived complexity for set_locale is too high. [8/7] Open
def set_locale
available_locales = I18n.available_locales_with_labels
if params[:locale] && available_locales.key?(params[:locale])
I18n.locale = params[:locale]
elsif session[:locale] && available_locales.key?(session[:locale])
- Read upRead up
- Exclude checks
This cop tries to produce a complexity score that's a measure of the
complexity the reader experiences when looking at a method. For that
reason it considers when
nodes as something that doesn't add as much
complexity as an if
or a &&
. Except if it's one of those special
case
/when
constructs where there's no expression after case
. Then
the cop treats it as an if
/elsif
/elsif
... and lets all the when
nodes count. In contrast to the CyclomaticComplexity cop, this cop
considers else
nodes as adding complexity.
Example:
def my_method # 1
if cond # 1
case var # 2 (0.8 + 4 * 0.2, rounded)
when 1 then func_one
when 2 then func_two
when 3 then func_three
when 4..10 then func_other
end
else # 1
do_something until a && b # 2
end # ===
end # 7 complexity points
Method has too many lines. [11/10] Open
def set_locale
available_locales = I18n.available_locales_with_labels
if params[:locale] && available_locales.key?(params[:locale])
I18n.locale = params[:locale]
elsif session[:locale] && available_locales.key?(session[:locale])
- Read upRead up
- Exclude checks
This cop checks if the length of a method exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable.
Cyclomatic complexity for link_related is too high. [7/6] Open
def link_related
@related_to_item = params[:relate_to_type].constantize.find(params[:relate_to_item])
unless params[:item].blank?
for id in params[:item].reject { |k, v| v != 'true' }.collect { |k, v| k }
- Read upRead up
- Exclude checks
This cop checks that the cyclomatic complexity of methods is not higher than the configured maximum. The cyclomatic complexity is the number of linearly independent paths through a method. The algorithm counts decision points and adds one.
An if statement (or unless or ?:) increases the complexity by one. An else branch does not, since it doesn't add a decision point. The && operator (or keyword and) can be converted to a nested if statement, and ||/or is shorthand for a sequence of ifs, so they also add one. Loops can be said to have an exit condition, so they add one.
Cyclomatic complexity for current_item is too high. [7/6] Open
def current_item
@current_item ||= @audio_recording || @document || @still_image || @topic || @video || @web_link || nil
end
- Read upRead up
- Exclude checks
This cop checks that the cyclomatic complexity of methods is not higher than the configured maximum. The cyclomatic complexity is the number of linearly independent paths through a method. The algorithm counts decision points and adds one.
An if statement (or unless or ?:) increases the complexity by one. An else branch does not, since it doesn't add a decision point. The && operator (or keyword and) can be converted to a nested if statement, and ||/or is shorthand for a sequence of ifs, so they also add one. Loops can be said to have an exit condition, so they add one.
Assignment Branch Condition size for item_from_controller_and_id is too high. [15.03/15] Open
def item_from_controller_and_id(and_basket = true)
if and_basket
@current_basket.send(zoom_class_from_controller(params[:controller]).tableize).find(params[:id])
else
Module.class_eval(zoom_class_from_controller(params[:controller])).find(params[:id])
- Read upRead up
- Exclude checks
This cop checks that the ABC size of methods is not higher than the configured maximum. The ABC size is based on assignments, branches (method calls), and conditions. See http://c2.com/cgi/wiki?AbcMetric
Method load_standard_baskets
has a Cognitive Complexity of 13 (exceeds 5 allowed). Consider refactoring. Open
def load_standard_baskets
# could DRY this up with one query for all the baskets
@site_basket ||= Basket.site_basket
@help_basket ||= Basket.help_basket
@about_basket ||= Basket.about_basket
- Read upRead up
Cognitive Complexity
Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.
A method's cognitive complexity is based on a few simple rules:
- Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
- Code is considered more complex for each "break in the linear flow of the code"
- Code is considered more complex when "flow breaking structures are nested"
Further reading
Method derive_url_for_rss
has 32 lines of code (exceeds 25 allowed). Consider refactoring. Open
def derive_url_for_rss(options = {})
replace_page_with_rss = !options[:replace_page_with_rss].nil? ? options[:replace_page_with_rss] : false
page = !options.blank? && !options[:page].blank? ? options[:page] : nil
Method render_full_width_content_wrapper?
has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring. Open
def render_full_width_content_wrapper?
if @displaying_error
false
elsif (params[:controller] == 'baskets') && ['edit', 'update', 'homepage_options', 'appearance'].include?(params[:action])
false
- Read upRead up
Cognitive Complexity
Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.
A method's cognitive complexity is based on a few simple rules:
- Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
- Code is considered more complex for each "break in the linear flow of the code"
- Code is considered more complex when "flow breaking structures are nested"
Further reading
Method rescue_action_in_public
has 27 lines of code (exceeds 25 allowed). Consider refactoring. Open
def rescue_action_in_public(exception)
@displaying_error = true
# when an exception occurs, before filters arn't called, so we have to manually call them here
# only call the ones absolutely nessesary (required settings, themes, permissions etc)
Method load_standard_baskets
has 27 lines of code (exceeds 25 allowed). Consider refactoring. Open
def load_standard_baskets
# could DRY this up with one query for all the baskets
@site_basket ||= Basket.site_basket
@help_basket ||= Basket.help_basket
@about_basket ||= Basket.about_basket
Method prepare_item_and_vars
has 27 lines of code (exceeds 25 allowed). Consider refactoring. Open
def prepare_item_and_vars
zoom_class = zoom_class_from_controller(params[:controller])
if !ZOOM_CLASSES.member?(zoom_class)
raise(ArgumentError, "zoom_class name expected. #{zoom_class} is not registered in #{ZOOM_CLASSES}.")
end
Method stats_by_type_for
has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. Open
def stats_by_type_for(basket)
# prepare a hash of all the stats, so it's nice and easy to pass to partial
@basket_stats_hash = {}
# special case: site basket contains everything
# all contents of site basket plus all other baskets' contents
- Read upRead up
Cognitive Complexity
Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.
A method's cognitive complexity is based on a few simple rules:
- Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
- Code is considered more complex for each "break in the linear flow of the code"
- Code is considered more complex when "flow breaking structures are nested"
Further reading
Method after_successful_zoom_item_update
has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. Open
def after_successful_zoom_item_update(item, version_after_update)
version_created = version_after_update ? item.versions.exists?(version: version_after_update) : false
# if we need to add a contributor (sometimes, a version isn't
# created if only timestamps were updated. In that case. we
- Read upRead up
Cognitive Complexity
Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.
A method's cognitive complexity is based on a few simple rules:
- Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
- Code is considered more complex for each "break in the linear flow of the code"
- Code is considered more complex when "flow breaking structures are nested"
Further reading
Method update_comments_basket_for
has a Cognitive Complexity of 7 (exceeds 5 allowed). Consider refactoring. Open
def update_comments_basket_for(item, original_basket)
if item.class.name != 'Comment'
new_basket = item.basket
if new_basket != original_basket
item.comments.each do |comment|
- Read upRead up
Cognitive Complexity
Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.
A method's cognitive complexity is based on a few simple rules:
- Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
- Code is considered more complex for each "break in the linear flow of the code"
- Code is considered more complex when "flow breaking structures are nested"
Further reading
Method add_relation_and_update_zoom_and_related_caches_for
has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring. Open
def add_relation_and_update_zoom_and_related_caches_for(item1, item2)
raise 'ERROR: Neither item 1 or 2 was a Topic' unless item1.is_a?(Topic) || item2.is_a?(Topic)
topic, related = (item1.is_a?(Topic) ? [item1, item2] : [item2, item1])
# clear out old zoom records before we change the items
- Read upRead up
Cognitive Complexity
Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.
A method's cognitive complexity is based on a few simple rules:
- Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
- Code is considered more complex for each "break in the linear flow of the code"
- Code is considered more complex when "flow breaking structures are nested"
Further reading
Method correct_url_for
has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring. Open
def correct_url_for(item, version = nil)
correct_action = version.nil? ? 'show' : 'preview'
options = { action: correct_action, id: item }
options[:version] = version if correct_action == 'preview'
- Read upRead up
Cognitive Complexity
Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.
A method's cognitive complexity is based on a few simple rules:
- Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
- Code is considered more complex for each "break in the linear flow of the code"
- Code is considered more complex when "flow breaking structures are nested"
Further reading
Method rss_tag
has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring. Open
def rss_tag(options = {})
auto_detect = !options[:auto_detect].nil? ? options[:auto_detect] : true
tag = ''
tag += auto_detect ? '<link rel="alternate" type="application/rss+xml" title="RSS" ' : '<a '
- Read upRead up
Cognitive Complexity
Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.
A method's cognitive complexity is based on a few simple rules:
- Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
- Code is considered more complex for each "break in the linear flow of the code"
- Code is considered more complex when "flow breaking structures are nested"
Further reading
Method set_locale
has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring. Open
def set_locale
available_locales = I18n.available_locales_with_labels
if params[:locale] && available_locales.key?(params[:locale])
I18n.locale = params[:locale]
elsif session[:locale] && available_locales.key?(session[:locale])
- Read upRead up
Cognitive Complexity
Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.
A method's cognitive complexity is based on a few simple rules:
- Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
- Code is considered more complex for each "break in the linear flow of the code"
- Code is considered more complex when "flow breaking structures are nested"
Further reading
Avoid more than 3 levels of block nesting. Open
if @successful
# in this context, the item being related needs updating, too
update_zoom_and_related_caches_for(item)
flash[:notice] = t('application_controller.link_related.added_relation')
- Read upRead up
- Exclude checks
This cop checks for excessive nesting of conditional and looping constructs.
You can configure if blocks are considered using the CountBlocks
option. When set to false
(the default) blocks are not counted
towards the nesting level. Set to true
to count blocks as well.
The maximum level of nesting allowed is configurable.
TODO found Open
# TODO: NOT USED, delete code here and in lib/zoom_controller_helpers.rb
- Exclude checks
TODO found Open
# TODO: allow current_user whom is at least moderator to pick another user
- Exclude checks
TODO found Open
# TODO: replace with translation stuff when we get globalize going
- Exclude checks
TODO found Open
# TODO: cache in memcache
- Exclude checks
TODO found Open
# TODO: we will want to change this to match browsing of private items in site basket later
- Exclude checks
TODO found Open
# TODO: this needs to be updated to store location for newer actions
- Exclude checks
TODO found Open
# TODO: this can likely be elimenated!
- Exclude checks
Unused block argument - k
. If it's necessary, use _
or _k
as an argument name to indicate that it won't be used. Open
for id in params[:item].reject { |k, v| v != 'true' }.collect { |k, v| k }
- Read upRead up
- Exclude checks
This cop checks for unused block arguments.
Example:
# bad
do_something do |used, unused|
puts used
end
do_something do |bar|
puts :foo
end
define_method(:foo) do |bar|
puts :baz
end
Example:
#good
do_something do |used, _unused|
puts used
end
do_something do
puts :foo
end
define_method(:foo) do |_bar|
puts :baz
end
Closing array brace must be on the line after the last array element when opening brace is on a separate line from the first array element. Open
join]
- Read upRead up
- Exclude checks
This cop checks that the closing brace in an array literal is either on the same line as the last array element, or a new line.
When using the symmetrical
(default) style:
If an array's opening brace is on the same line as the first element of the array, then the closing brace should be on the same line as the last element of the array.
If an array's opening brace is on the line above the first element of the array, then the closing brace should be on the line below the last element of the array.
When using the new_line
style:
The closing brace of a multi-line array literal must be on the line after the last element of the array.
When using the same_line
style:
The closing brace of a multi-line array literal must be on the same line as the last element of the array.
Example: EnforcedStyle: symmetrical (default)
# bad
[ :a,
:b
]
# bad
[
:a,
:b ]
# good
[ :a,
:b ]
# good
[
:a,
:b
]
Example: EnforcedStyle: new_line
# bad
[
:a,
:b ]
# bad
[ :a,
:b ]
# good
[ :a,
:b
]
# good
[
:a,
:b
]
Example: EnforcedStyle: same_line
# bad
[ :a,
:b
]
# bad
[
:a,
:b
]
# good
[
:a,
:b ]
# good
[ :a,
:b ]
Unused method argument - controller
. If it's necessary, use _
or _controller
as an argument name to indicate that it won't be used. Open
def update_zoom_and_related_caches_for(item, controller = nil)
- Read upRead up
- Exclude checks
This cop checks for unused method arguments.
Example:
# bad
def some_method(used, unused, _unused_but_allowed)
puts used
end
Example:
# good
def some_method(used, _unused, _unused_but_allowed)
puts used
end
Unused block argument - k
. If it's necessary, use _
or _k
as an argument name to indicate that it won't be used. Open
for id in params[:item].reject { |k, v| v != 'true' }.collect { |k, v| k }
- Read upRead up
- Exclude checks
This cop checks for unused block arguments.
Example:
# bad
do_something do |used, unused|
puts used
end
do_something do |bar|
puts :foo
end
define_method(:foo) do |bar|
puts :baz
end
Example:
#good
do_something do |used, _unused|
puts used
end
do_something do
puts :foo
end
define_method(:foo) do |_bar|
puts :baz
end
Symbol with a boolean name - you probably meant to use false
. Open
elsif current_user != :false && available_locales.key?(current_user.locale)
- Read upRead up
- Exclude checks
This cop checks for :true
and :false
symbols.
In most cases it would be a typo.
Example:
# bad
:true
# good
true
Example:
# bad
:false
# good
false
Unused block argument - v
. If it's necessary, use _
or _v
as an argument name to indicate that it won't be used. Open
for id in params[:item].reject { |k, v| v != 'true' }.collect { |k, v| k }
- Read upRead up
- Exclude checks
This cop checks for unused block arguments.
Example:
# bad
do_something do |used, unused|
puts used
end
do_something do |bar|
puts :foo
end
define_method(:foo) do |bar|
puts :baz
end
Example:
#good
do_something do |used, _unused|
puts used
end
do_something do
puts :foo
end
define_method(:foo) do |_bar|
puts :baz
end
Closing array brace must be on the line after the last array element when opening brace is on a separate line from the first array element. Open
show_captcha]
- Read upRead up
- Exclude checks
This cop checks that the closing brace in an array literal is either on the same line as the last array element, or a new line.
When using the symmetrical
(default) style:
If an array's opening brace is on the same line as the first element of the array, then the closing brace should be on the same line as the last element of the array.
If an array's opening brace is on the line above the first element of the array, then the closing brace should be on the line below the last element of the array.
When using the new_line
style:
The closing brace of a multi-line array literal must be on the line after the last element of the array.
When using the same_line
style:
The closing brace of a multi-line array literal must be on the same line as the last element of the array.
Example: EnforcedStyle: symmetrical (default)
# bad
[ :a,
:b
]
# bad
[
:a,
:b ]
# good
[ :a,
:b ]
# good
[
:a,
:b
]
Example: EnforcedStyle: new_line
# bad
[
:a,
:b ]
# bad
[ :a,
:b ]
# good
[ :a,
:b
]
# good
[
:a,
:b
]
Example: EnforcedStyle: same_line
# bad
[ :a,
:b
]
# bad
[
:a,
:b
]
# good
[
:a,
:b ]
# good
[ :a,
:b ]
Unused block argument - v
. If it's necessary, use _
or _v
as an argument name to indicate that it won't be used. Open
for id in params[:item].reject { |k, v| v != 'true' }.collect { |k, v| k }
- Read upRead up
- Exclude checks
This cop checks for unused block arguments.
Example:
# bad
do_something do |used, unused|
puts used
end
do_something do |bar|
puts :foo
end
define_method(:foo) do |bar|
puts :baz
end
Example:
#good
do_something do |used, _unused|
puts used
end
do_something do
puts :foo
end
define_method(:foo) do |_bar|
puts :baz
end
Prefer each
over for
. Open
for id in params[:item].reject { |k, v| v != 'true' }.collect { |k, v| k }
- Read upRead up
- Exclude checks
This cop looks for uses of the for keyword, or each method. The preferred alternative is set in the EnforcedStyle configuration parameter. An each call with a block on a single line is always allowed, however.
Convert if
nested inside else
to elsif
. Open
if params[:format] == 'xml'
- Read upRead up
- Exclude checks
If the else
branch of a conditional consists solely of an if
node,
it can be combined with the else
to become an elsif
.
This helps to keep the nesting level from getting too deep.
Example:
# bad
if condition_a
action_a
else
if condition_b
action_b
else
action_c
end
end
# good
if condition_a
action_a
elsif condition_b
action_b
else
action_c
end
Favor modifier if
usage when having a single-line body. Another good alternative is the usage of control flow &&
/||
. Open
if options[:private]
- Read upRead up
- Exclude checks
Checks for if and unless statements that would fit on one line
if written as a modifier if/unless. The maximum line length is
configured in the Metrics/LineLength
cop.
Example:
# bad
if condition
do_stuff(bar)
end
unless qux.empty?
Foo.do_something
end
# good
do_stuff(bar) if condition
Foo.do_something unless qux.empty?
%w
-literals should be delimited by [
and ]
. Open
%w(number_of_results_per_page tabindex sort_type sort_direction).each do |not_relevant|
- Read upRead up
- Exclude checks
This cop enforces the consistent usage of %
-literal delimiters.
Specify the 'default' key to set all preferred delimiters at once. You can continue to specify individual preferred delimiters to override the default.
Example:
# Style/PercentLiteralDelimiters:
# PreferredDelimiters:
# default: '[]'
# '%i': '()'
# good
%w[alpha beta] + %i(gamma delta)
# bad
%W(alpha #{beta})
# bad
%I(alpha beta)
Do not use unless
with else
. Rewrite these with the positive case first. Open
unless redirect_registration
@displaying_error = true
@title = t('application_controller.rescue_404.title')
render template: 'errors/error404', layout: 'application', status: '404'
else
- Read upRead up
- Exclude checks
This cop looks for unless expressions with else clauses.
Example:
# bad
unless foo_bar.nil?
# do something...
else
# do a different thing...
end
# good
if foo_bar.present?
# do something...
else
# do a different thing...
end
Use the return of the conditional for variable assignment and comparison. Open
if basket == @site_basket
@basket_stats_hash["#{zoom_class}_public"] = Module.class_eval(zoom_class).count(conditions: local_public_conditions)
else
@basket_stats_hash["#{zoom_class}_public"] = basket.send(zoom_class.tableize).count(conditions: local_public_conditions)
end
- Exclude checks
%w
-literals should be delimited by [
and ]
. Open
elsif %w(tags search).include?(params[:controller])
- Read upRead up
- Exclude checks
This cop enforces the consistent usage of %
-literal delimiters.
Specify the 'default' key to set all preferred delimiters at once. You can continue to specify individual preferred delimiters to override the default.
Example:
# Style/PercentLiteralDelimiters:
# PreferredDelimiters:
# default: '[]'
# '%i': '()'
# good
%w[alpha beta] + %i(gamma delta)
# bad
%W(alpha #{beta})
# bad
%I(alpha beta)
Use %w
or %W
for an array of words. Open
elsif ['moderate', 'members', 'importers'].include?(params[:controller]) && ['list', 'create', 'new', 'new_related_set_from_archive_file', 'potential_new_members'].include?(params[:action])
- Read upRead up
- Exclude checks
This cop can check for array literals made up of word-like strings, that are not using the %w() syntax.
Alternatively, it can check for uses of the %w() syntax, in projects which do not want to include that syntax.
Configuration option: MinSize
If set, arrays with fewer elements than this value will not trigger the
cop. For example, a MinSize
of 3
will not enforce a style on an
array of 2 or fewer elements.
Example: EnforcedStyle: percent (default)
# good
%w[foo bar baz]
# bad
['foo', 'bar', 'baz']
Example: EnforcedStyle: brackets
# good
['foo', 'bar', 'baz']
# bad
%w[foo bar baz]
Use the return of the conditional for variable assignment and comparison. Open
if params[:relate_to_type] == 'Topic' && params[:related_class] == 'Topic'
@existing_relation = @related_to_item.related_topics.include?(item)
else
@existing_relation = @related_to_item.send(params[:related_class].tableize).include?(item)
end
- Exclude checks
Favor modifier if
usage when having a single-line body. Another good alternative is the usage of control flow &&
/||
. Open
if !anonymous_ok_for?(request.path)
- Read upRead up
- Exclude checks
Checks for if and unless statements that would fit on one line
if written as a modifier if/unless. The maximum line length is
configured in the Metrics/LineLength
cop.
Example:
# bad
if condition
do_stuff(bar)
end
unless qux.empty?
Foo.do_something
end
# good
do_stuff(bar) if condition
Foo.do_something unless qux.empty?
Favor unless
over if
for negative conditions. Open
update_search_record_for(item) if !item.already_at_blank_version?
- Read upRead up
- Exclude checks
Checks for uses of if with a negated condition. Only ifs without else are considered. There are three different styles:
- both
- prefix
- postfix
Example: EnforcedStyle: both (default)
# enforces `unless` for `prefix` and `postfix` conditionals
# bad
if !foo
bar
end
# good
unless foo
bar
end
# bad
bar if !foo
# good
bar unless foo
Example: EnforcedStyle: prefix
# enforces `unless` for just `prefix` conditionals
# bad
if !foo
bar
end
# good
unless foo
bar
end
# good
bar if !foo
Example: EnforcedStyle: postfix
# enforces `unless` for just `postfix` conditionals
# bad
bar if !foo
# good
bar unless foo
# good
if !foo
bar
end
Favor unless
over if
for negative conditions. Open
if !anonymous_ok_for?(request.path)
logout_anonymous
end
- Read upRead up
- Exclude checks
Checks for uses of if with a negated condition. Only ifs without else are considered. There are three different styles:
- both
- prefix
- postfix
Example: EnforcedStyle: both (default)
# enforces `unless` for `prefix` and `postfix` conditionals
# bad
if !foo
bar
end
# good
unless foo
bar
end
# bad
bar if !foo
# good
bar unless foo
Example: EnforcedStyle: prefix
# enforces `unless` for just `prefix` conditionals
# bad
if !foo
bar
end
# good
unless foo
bar
end
# good
bar if !foo
Example: EnforcedStyle: postfix
# enforces `unless` for just `postfix` conditionals
# bad
bar if !foo
# good
bar unless foo
# good
if !foo
bar
end
Use next
to skip iteration. Open
if !@existing_relation
- Read upRead up
- Exclude checks
Use next
to skip iteration instead of a condition at the end.
Example: EnforcedStyle: skipmodifierifs (default)
# bad
[1, 2].each do |a|
if a == 1
puts a
end
end
# good
[1, 2].each do |a|
next unless a == 1
puts a
end
# good
[1, 2].each do |o|
puts o unless o == 1
end
Example: EnforcedStyle: always
# With `always` all conditions at the end of an iteration needs to be
# replaced by next - with `skip_modifier_ifs` the modifier if like
# this one are ignored: `[1, 2].each { |a| return 'yes' if a == 1 }`
# bad
[1, 2].each do |o|
puts o unless o == 1
end
# bad
[1, 2].each do |a|
if a == 1
puts a
end
end
# good
[1, 2].each do |a|
next unless a == 1
puts a
end
Unused method argument - controller
. If it's necessary, use _
or _controller
as an argument name to indicate that it won't be used. You can also write as redirect_to_all_for(*)
if you want the method to accept any arguments but don't care about them. Open
def redirect_to_all_for(controller)
- Read upRead up
- Exclude checks
This cop checks for unused method arguments.
Example:
# bad
def some_method(used, unused, _unused_but_allowed)
puts used
end
Example:
# good
def some_method(used, _unused, _unused_but_allowed)
puts used
end
Use a guard clause instead of wrapping the code inside a conditional expression. Open
if ZOOM_CLASSES.include?(zoom_class)
- Read upRead up
- Exclude checks
Use a guard clause instead of wrapping the code inside a conditional expression
Example:
# bad
def test
if something
work
end
end
# good
def test
return unless something
work
end
# also good
def test
work if something
end
# bad
if something
raise 'exception'
else
ok
end
# good
raise 'exception' if something
ok
Use a guard clause instead of wrapping the code inside a conditional expression. Open
if item.class.name != 'Comment'
- Read upRead up
- Exclude checks
Use a guard clause instead of wrapping the code inside a conditional expression
Example:
# bad
def test
if something
work
end
end
# good
def test
return unless something
work
end
# also good
def test
work if something
end
# bad
if something
raise 'exception'
else
ok
end
# good
raise 'exception' if something
ok
Use a guard clause instead of wrapping the code inside a conditional expression. Open
if !skipped_actions.include?(params[:action]) && params[item.class_as_key][:private] == 'true'
- Read upRead up
- Exclude checks
Use a guard clause instead of wrapping the code inside a conditional expression
Example:
# bad
def test
if something
work
end
end
# good
def test
return unless something
work
end
# also good
def test
work if something
end
# bad
if something
raise 'exception'
else
ok
end
# good
raise 'exception' if something
ok
Prefer each
over for
. Open
for id in params[:item].reject { |k, v| v != 'true' }.collect { |k, v| k }
- Read upRead up
- Exclude checks
This cop looks for uses of the for keyword, or each method. The preferred alternative is set in the EnforcedStyle configuration parameter. An each call with a block on a single line is always allowed, however.
Use a guard clause instead of wrapping the code inside a conditional expression. Open
if ZOOM_CLASSES.include?(zoom_class) && (zoom_class != 'Comment')
- Read upRead up
- Exclude checks
Use a guard clause instead of wrapping the code inside a conditional expression
Example:
# bad
def test
if something
work
end
end
# good
def test
return unless something
work
end
# also good
def test
work if something
end
# bad
if something
raise 'exception'
else
ok
end
# good
raise 'exception' if something
ok
Use a guard clause instead of wrapping the code inside a conditional expression. Open
if @current_basket.status != 'approved' && !@site_admin && !@basket_admin
- Read upRead up
- Exclude checks
Use a guard clause instead of wrapping the code inside a conditional expression
Example:
# bad
def test
if something
work
end
end
# good
def test
return unless something
work
end
# also good
def test
work if something
end
# bad
if something
raise 'exception'
else
ok
end
# good
raise 'exception' if something
ok
Use a guard clause instead of wrapping the code inside a conditional expression. Open
if !anonymous_ok_for?(request.path)
- Read upRead up
- Exclude checks
Use a guard clause instead of wrapping the code inside a conditional expression
Example:
# bad
def test
if something
work
end
end
# good
def test
return unless something
work
end
# also good
def test
work if something
end
# bad
if something
raise 'exception'
else
ok
end
# good
raise 'exception' if something
ok
Use the return of the conditional for variable assignment and comparison. Open
if params[:locale] && available_locales.key?(params[:locale])
I18n.locale = params[:locale]
elsif session[:locale] && available_locales.key?(session[:locale])
I18n.locale = session[:locale]
elsif current_user != :false && available_locales.key?(current_user.locale)
- Exclude checks
Favor modifier if
usage when having a single-line body. Another good alternative is the usage of control flow &&
/||
. Open
if options[:anchor]
- Read upRead up
- Exclude checks
Checks for if and unless statements that would fit on one line
if written as a modifier if/unless. The maximum line length is
configured in the Metrics/LineLength
cop.
Example:
# bad
if condition
do_stuff(bar)
end
unless qux.empty?
Foo.do_something
end
# good
do_stuff(bar) if condition
Foo.do_something unless qux.empty?
Use a guard clause instead of wrapping the code inside a conditional expression. Open
unless SITE_LOCKDOWN.blank?
- Read upRead up
- Exclude checks
Use a guard clause instead of wrapping the code inside a conditional expression
Example:
# bad
def test
if something
work
end
end
# good
def test
return unless something
work
end
# also good
def test
work if something
end
# bad
if something
raise 'exception'
else
ok
end
# good
raise 'exception' if something
ok
Useless assignment to variable - privacy
. Open
privacy = get_acceptable_privacy_type_for(@current_item)
- Read upRead up
- Exclude checks
This cop checks for every useless assignment to local variable in every
scope.
The basic idea for this cop was from the warning of ruby -cw
:
assigned but unused variable - foo
Currently this cop has advanced logic that detects unreferenced reassignments and properly handles varied cases such as branch, loop, rescue, ensure, etc.
Example:
# bad
def some_method
some_var = 1
do_something
end
Example:
# good
def some_method
some_var = 1
do_something(some_var)
end
Use the return of the conditional for variable assignment and comparison. Open
case params[:urlified_name]
when @site_basket.urlified_name
@current_basket = @site_basket
when @about_basket.urlified_name
@current_basket = @about_basket
- Exclude checks
Favor modifier if
usage when having a single-line body. Another good alternative is the usage of control flow &&
/||
. Open
if params[:format] == 'xml'
- Read upRead up
- Exclude checks
Checks for if and unless statements that would fit on one line
if written as a modifier if/unless. The maximum line length is
configured in the Metrics/LineLength
cop.
Example:
# bad
if condition
do_stuff(bar)
end
unless qux.empty?
Foo.do_something
end
# good
do_stuff(bar) if condition
Foo.do_something unless qux.empty?
Favor unless
over if
for negative conditions. Open
if !@existing_relation
@successful = add_relation_and_update_zoom_and_related_caches_for(item, @related_to_item)
if @successful
# in this context, the item being related needs updating, too
- Read upRead up
- Exclude checks
Checks for uses of if with a negated condition. Only ifs without else are considered. There are three different styles:
- both
- prefix
- postfix
Example: EnforcedStyle: both (default)
# enforces `unless` for `prefix` and `postfix` conditionals
# bad
if !foo
bar
end
# good
unless foo
bar
end
# bad
bar if !foo
# good
bar unless foo
Example: EnforcedStyle: prefix
# enforces `unless` for just `prefix` conditionals
# bad
if !foo
bar
end
# good
unless foo
bar
end
# good
bar if !foo
Example: EnforcedStyle: postfix
# enforces `unless` for just `postfix` conditionals
# bad
bar if !foo
# good
bar unless foo
# good
if !foo
bar
end
Favor unless
over if
for negative conditions. Open
if !ZOOM_CLASSES.member?(zoom_class)
raise(ArgumentError, "zoom_class name expected. #{zoom_class} is not registered in #{ZOOM_CLASSES}.")
end
- Read upRead up
- Exclude checks
Checks for uses of if with a negated condition. Only ifs without else are considered. There are three different styles:
- both
- prefix
- postfix
Example: EnforcedStyle: both (default)
# enforces `unless` for `prefix` and `postfix` conditionals
# bad
if !foo
bar
end
# good
unless foo
bar
end
# bad
bar if !foo
# good
bar unless foo
Example: EnforcedStyle: prefix
# enforces `unless` for just `prefix` conditionals
# bad
if !foo
bar
end
# good
unless foo
bar
end
# good
bar if !foo
Example: EnforcedStyle: postfix
# enforces `unless` for just `postfix` conditionals
# bad
bar if !foo
# good
bar unless foo
# good
if !foo
bar
end
Redundant curly braces around a hash parameter. Open
redirect_to_related_item(@relate_to_item, { private: (params[:related_item_private] && params[:related_item_private] == 'true' && permitted_to_view_private_items?) })
- Read upRead up
- Exclude checks
This cop checks for braces around the last parameter in a method call
if the last parameter is a hash.
It supports braces
, no_braces
and context_dependent
styles.
Example: EnforcedStyle: braces
# The `braces` style enforces braces around all method
# parameters that are hashes.
# bad
some_method(x, y, a: 1, b: 2)
# good
some_method(x, y, {a: 1, b: 2})
Example: EnforcedStyle: no_braces (default)
# The `no_braces` style checks that the last parameter doesn't
# have braces around it.
# bad
some_method(x, y, {a: 1, b: 2})
# good
some_method(x, y, a: 1, b: 2)
Example: EnforcedStyle: context_dependent
# The `context_dependent` style checks that the last parameter
# doesn't have braces around it, but requires braces if the
# second to last parameter is also a hash literal.
# bad
some_method(x, y, {a: 1, b: 2})
some_method(x, y, {a: 1, b: 2}, a: 1, b: 2)
# good
some_method(x, y, a: 1, b: 2)
some_method(x, y, {a: 1, b: 2}, {a: 1, b: 2})
Use a guard clause instead of wrapping the code inside a conditional expression. Open
if @current_basket.nil?
- Read upRead up
- Exclude checks
Use a guard clause instead of wrapping the code inside a conditional expression
Example:
# bad
def test
if something
work
end
end
# good
def test
return unless something
work
end
# also good
def test
work if something
end
# bad
if something
raise 'exception'
else
ok
end
# good
raise 'exception' if something
ok