lib/workers/past_perfect4_importer_worker.rb

Summary

Maintainability
F
5 days
Test Coverage

Possible SQL injection
Open

                  conditions: "extended_content like \'%<user_reference xml_element_name=\"dc:identifier\">#{cleaned_up_accessno}</user_reference>%\' AND topic_type_id = #{@related_topic_type.id}"

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 SQL injection
Open

                conditions: "filename = \'#{File.basename(path_to_file_to_grab)}\' and extended_content like \'%<user_reference xml_element_name=\"dc:identifier\">#{objectid}</user_reference>%\'"

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.

Model attribute used in file name
Open

      @import_accessions_xml = REXML::Document.new File.open(@path_to_trimmed_accessions)

Using user input when accessing files (local or remote) will raise a warning in Brakeman.

For example

File.open("/tmp/#{cookie[:file]}")

will raise an error like

Cookie value used in file name near line 4: File.open("/tmp/#{cookie[:file]}")

This type of vulnerability can be used to access arbitrary files on a server (including /etc/passwd.

Possible SQL injection
Open

            conditions: "extended_content like \'%<user_reference xml_element_name=\"dc:identifier\">#{related_topic_pp4_objectid}</user_reference>%\' AND topic_type_id = #{@related_topic_type.id}"

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.

Model attribute used in file name
Open

      @import_photos_xml = REXML::Document.new File.open(@path_to_trimmed_photos)

Using user input when accessing files (local or remote) will raise a warning in Brakeman.

For example

File.open("/tmp/#{cookie[:file]}")

will raise an error like

Cookie value used in file name near line 4: File.open("/tmp/#{cookie[:file]}")

This type of vulnerability can be used to access arbitrary files on a server (including /etc/passwd.

Assignment Branch Condition size for create_new_item_from_record is too high. [217.7/15]
Open

  def create_new_item_from_record(record, zoom_class, options = {})
    zoom_class_for_params = zoom_class.tableize.singularize

    params = options[:params]

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

Class has too many lines. [343/100]
Open

class PastPerfect4ImporterWorker < BackgrounDRb::MetaWorker
  set_worker_name :past_perfect4_importer_worker
  set_no_auto_load true

  # importer has the version of methods that will work in the context

This cop checks if the length a class exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable.

Method has too many lines. [154/10]
Open

  def create_new_item_from_record(record, zoom_class, options = {})
    zoom_class_for_params = zoom_class.tableize.singularize

    params = options[:params]

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 importer_process is too high. [139.6/15]
Open

  def importer_process(record, params)
    current_record = @results[:records_processed] + 1
    logger.info("starting record #{current_record}")

    # clear this out so last related_topic

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. [120/10]
Open

  def importer_process(record, params)
    current_record = @results[:records_processed] + 1
    logger.info("starting record #{current_record}")

    # clear this out so last related_topic

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 create_new_item_from_record has a Cognitive Complexity of 80 (exceeds 5 allowed). Consider refactoring.
Open

  def create_new_item_from_record(record, zoom_class, options = {})
    zoom_class_for_params = zoom_class.tableize.singularize

    params = options[:params]

Severity: Minor
Found in lib/workers/past_perfect4_importer_worker.rb - About 1 day to fix

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 importer_process has a Cognitive Complexity of 73 (exceeds 5 allowed). Consider refactoring.
Open

  def importer_process(record, params)
    current_record = @results[:records_processed] + 1
    logger.info("starting record #{current_record}")

    # clear this out so last related_topic
Severity: Minor
Found in lib/workers/past_perfect4_importer_worker.rb - About 1 day to fix

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

Perceived complexity for create_new_item_from_record is too high. [51/7]
Open

  def create_new_item_from_record(record, zoom_class, options = {})
    zoom_class_for_params = zoom_class.tableize.singularize

    params = options[:params]

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 do_work is too high. [55.98/15]
Open

  def do_work(args = nil)
    logger.info('in worker')
    begin
      @zoom_class = args[:zoom_class]
      @import = Import.find(args[:import])

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 create_new_item_from_record has 154 lines of code (exceeds 25 allowed). Consider refactoring.
Open

  def create_new_item_from_record(record, zoom_class, options = {})
    zoom_class_for_params = zoom_class.tableize.singularize

    params = options[:params]

Severity: Major
Found in lib/workers/past_perfect4_importer_worker.rb - About 6 hrs to fix

    Cyclomatic complexity for create_new_item_from_record is too high. [43/6]
    Open

      def create_new_item_from_record(record, zoom_class, options = {})
        zoom_class_for_params = zoom_class.tableize.singularize
    
        params = options[:params]
    
    

    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. [42/10]
    Open

      def do_work(args = nil)
        logger.info('in worker')
        begin
          @zoom_class = args[:zoom_class]
          @import = Import.find(args[:import])

    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 importer_process has 120 lines of code (exceeds 25 allowed). Consider refactoring.
    Open

      def importer_process(record, params)
        current_record = @results[:records_processed] + 1
        logger.info("starting record #{current_record}")
    
        # clear this out so last related_topic
    Severity: Major
    Found in lib/workers/past_perfect4_importer_worker.rb - About 4 hrs to fix

      Perceived complexity for importer_process is too high. [33/7]
      Open

        def importer_process(record, params)
          current_record = @results[:records_processed] + 1
          logger.info("starting record #{current_record}")
      
          # clear this out so last related_topic

      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

      File past_perfect4_importer_worker.rb has 348 lines of code (exceeds 250 allowed). Consider refactoring.
      Open

      require 'rexml/document'
      require 'redcloth'
      require 'importer'
      # past perfect 4 xml output importer
      # only handling photos for the moment
      Severity: Minor
      Found in lib/workers/past_perfect4_importer_worker.rb - About 4 hrs to fix

        Cyclomatic complexity for importer_process is too high. [28/6]
        Open

          def importer_process(record, params)
            current_record = @results[:records_processed] + 1
            logger.info("starting record #{current_record}")
        
            # clear this out so last related_topic

        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.

        Block has too many lines. [55/25]
        Open

            record_hash.keys.each do |record_field|
              value = record_hash[record_field]
              if !value.nil?
                value = value.strip
                # replace \r with \n

        This cop checks if the length of a block exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable. The cop can be configured to ignore blocks passed to certain methods.

        Method has too many lines. [11/10]
        Open

          def determine_elements_used(in_file)
            # assume original style root element and paths
            @root_element_name = 'Root'
            @record_element_path = 'Information/Record'
            # this should tell us what we need to know by around the second line

        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 do_work has 42 lines of code (exceeds 25 allowed). Consider refactoring.
        Open

          def do_work(args = nil)
            logger.info('in worker')
            begin
              @zoom_class = args[:zoom_class]
              @import = Import.find(args[:import])
        Severity: Minor
        Found in lib/workers/past_perfect4_importer_worker.rb - About 1 hr to fix

          Avoid deeply nested control flow statements.
          Open

                      if !related_accession_record.blank? && related_topic.nil?
                        accession_record_hash = importer_xml_record_to_hash(related_accession_record, true)
          
                        # create a new topic from related_accession_record
                        # prepare user_reference for extended_content
          Severity: Major
          Found in lib/workers/past_perfect4_importer_worker.rb - About 45 mins to fix

            Avoid deeply nested control flow statements.
            Open

                        if related_accession_record.blank?
                          cleaned_accessno_array = related_topic_pp4_objectid.split('.')
                          cleaned_up_accessno = cleaned_accessno_array[0] + '.' + cleaned_accessno_array[1]
            
                          logger.info('looking for cleaned up accession: ' + cleaned_up_accessno)
            Severity: Major
            Found in lib/workers/past_perfect4_importer_worker.rb - About 45 mins to fix

              Avoid more than 3 levels of block nesting.
              Open

                          description_end_template = text if !image_objectid.scan(pattern).blank?

              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.

              Avoid more than 3 levels of block nesting.
              Open

                        if @last_related_topic.nil? || (related_topic.id != @last_related_topic.id)
                          # update the last topic, since we are done adding things to it for now
                          related_topic.prepare_and_save_to_zoom
                        end

              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.

              Avoid more than 3 levels of block nesting.
              Open

                          if params[zoom_class_for_params][:description].nil?
                            params[zoom_class_for_params][:description] = value
                          else
                            params[zoom_class_for_params][:description] += "\n" + value
                          end

              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.

              Avoid more than 3 levels of block nesting.
              Open

                        if !@collections_to_skip.include?(record_hash['COLLECTION'])
                          # file may time out
                          related_accession_record = nil
              
                          related_accession_record = @import_accessions_xml_root.elements["#{@record_element_path}[@ACCESSNO=\'#{related_topic_pp4_objectid}\']"]

              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.

              Avoid more than 3 levels of block nesting.
              Open

                            if !names_array[1].nil?
                              first_names = names_array[1].split('(')[0].strip
                            end

              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.

              Use each_key instead of keys.each.
              Open

                    record_hash.keys.each do |record_field|

              This cop checks for uses of each_key and each_value Hash methods.

              Note: If you have an array of two-element arrays, you can put parentheses around the block arguments to indicate that you're not working with a hash, and suppress RuboCop offenses.

              Example:

              # bad
              hash.keys.each { |k| p k }
              hash.values.each { |v| p v }
              hash.each { |k, _v| p k }
              hash.each { |_k, v| p v }
              
              # good
              hash.each_key { |k| p k }
              hash.each_value { |v| p v }

              Use each_key instead of keys.each.
              Open

                  record_hash.keys.each do |record_field|

              This cop checks for uses of each_key and each_value Hash methods.

              Note: If you have an array of two-element arrays, you can put parentheses around the block arguments to indicate that you're not working with a hash, and suppress RuboCop offenses.

              Example:

              # bad
              hash.keys.each { |k| p k }
              hash.values.each { |v| p v }
              hash.each { |k, _v| p k }
              hash.each { |_k, v| p v }
              
              # good
              hash.each_key { |k| p k }
              hash.each_value { |v| p v }

              HACK found
              Open

                    # HACK: to go down one more level

              TODO found
              Open

                    # TODO: test what happens when there isn't an accessions.xml file

              TODO found
              Open

                    # TODO: if there is an object with a matching exactly user_reference,

              TODO found
              Open

                    # TODO: add check to see if image_file has a, b, c, versions associated with it

              Identical blocks of code found in 2 locations. Consider refactoring.
              Open

                  if !@import.description_beginning_template.blank?
                    # append the citation to the description field
                    if !params[zoom_class_for_params][:description].nil?
                      params[zoom_class_for_params][:description] = @import.description_beginning_template + "\n\n" + params[zoom_class_for_params][:description]
                    else
              Severity: Major
              Found in lib/workers/past_perfect4_importer_worker.rb and 1 other location - About 1 hr to fix
              lib/importer.rb on lines 921..934

              Duplicated Code

              Duplicated code can lead to software that is hard to understand and difficult to change. The Don't Repeat Yourself (DRY) principle states:

              Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

              When you violate DRY, bugs and maintenance problems are sure to follow. Duplicated code has a tendency to both continue to replicate and also to diverge (leaving bugs as two similar implementations differ in subtle ways).

              Tuning

              This issue has a mass of 70.

              We set useful threshold defaults for the languages we support but you may want to adjust these settings based on your project guidelines.

              The threshold configuration represents the minimum mass a code block must have to be analyzed for duplication. The lower the threshold, the more fine-grained the comparison.

              If the engine is too easily reporting duplication, try raising the threshold. If you suspect that the engine isn't catching enough duplication, try lowering the threshold. The best setting tends to differ from language to language.

              See codeclimate-duplication's documentation for more information about tuning the mass threshold in your .codeclimate.yml.

              Refactorings

              Further Reading

              Similar blocks of code found in 2 locations. Consider refactoring.
              Open

                  if zoom_class == 'Topic'
                    params[zoom_class_for_params][:topic_type_id] = @related_topic_type.id
              
                    @fields = @related_topic_type.topic_type_to_field_mappings
              
              
              Severity: Minor
              Found in lib/workers/past_perfect4_importer_worker.rb and 1 other location - About 50 mins to fix
              lib/importer.rb on lines 971..985

              Duplicated Code

              Duplicated code can lead to software that is hard to understand and difficult to change. The Don't Repeat Yourself (DRY) principle states:

              Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

              When you violate DRY, bugs and maintenance problems are sure to follow. Duplicated code has a tendency to both continue to replicate and also to diverge (leaving bugs as two similar implementations differ in subtle ways).

              Tuning

              This issue has a mass of 42.

              We set useful threshold defaults for the languages we support but you may want to adjust these settings based on your project guidelines.

              The threshold configuration represents the minimum mass a code block must have to be analyzed for duplication. The lower the threshold, the more fine-grained the comparison.

              If the engine is too easily reporting duplication, try raising the threshold. If you suspect that the engine isn't catching enough duplication, try lowering the threshold. The best setting tends to differ from language to language.

              See codeclimate-duplication's documentation for more information about tuning the mass threshold in your .codeclimate.yml.

              Refactorings

              Further Reading

              Identical blocks of code found in 2 locations. Consider refactoring.
              Open

                  if !options[:description_end_template].nil?
                    # append the description_end_template to the description field
                    if !params[zoom_class_for_params][:description].nil?
                      params[zoom_class_for_params][:description] += "\n\n" + options[:description_end_template]
                    else
              Severity: Minor
              Found in lib/workers/past_perfect4_importer_worker.rb and 1 other location - About 30 mins to fix
              lib/importer.rb on lines 936..941

              Duplicated Code

              Duplicated code can lead to software that is hard to understand and difficult to change. The Don't Repeat Yourself (DRY) principle states:

              Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

              When you violate DRY, bugs and maintenance problems are sure to follow. Duplicated code has a tendency to both continue to replicate and also to diverge (leaving bugs as two similar implementations differ in subtle ways).

              Tuning

              This issue has a mass of 33.

              We set useful threshold defaults for the languages we support but you may want to adjust these settings based on your project guidelines.

              The threshold configuration represents the minimum mass a code block must have to be analyzed for duplication. The lower the threshold, the more fine-grained the comparison.

              If the engine is too easily reporting duplication, try raising the threshold. If you suspect that the engine isn't catching enough duplication, try lowering the threshold. The best setting tends to differ from language to language.

              See codeclimate-duplication's documentation for more information about tuning the mass threshold in your .codeclimate.yml.

              Refactorings

              Further Reading

              Useless assignment to variable - record.
              Open

                  record = nil

              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

              Redundant curly braces around a hash parameter.
              Open

                      new_record = create_new_item_from_record(record, @zoom_class, { params: params, record_hash: record_hash, description_end_template: description_end_template })

              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})

              Favor unless over if for negative conditions.
              Open

                  if !params[zoom_class_for_params][:description].nil?
                    description = RedCloth.new params[zoom_class_for_params][:description]
                    params[zoom_class_for_params][:description] = description.to_html
                  end

              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 !description.blank?
                      params[zoom_class_for_params][:short_summary] = importer_prepare_short_summary(description)
                    end

              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 @record_interval.positive? instead of @record_interval > 0.
              Open

                      sleep(@record_interval) if @record_interval > 0

              This cop checks for usage of comparison operators (==, >, <) to test numbers as zero, positive, or negative. These can be replaced by their respective predicate methods. The cop can also be configured to do the reverse.

              The cop disregards #nonzero? as it its value is truthy or falsey, but not true and false, and thus not always interchangeable with != 0.

              The cop ignores comparisons to global variables, since they are often populated with objects which can be compared with integers, but are not themselves Interger polymorphic.

              Example: EnforcedStyle: predicate (default)

              # bad
              
              foo == 0
              0 > foo
              bar.baz > 0
              
              # good
              
              foo.zero?
              foo.negative?
              bar.baz.positive?

              Example: EnforcedStyle: comparison

              # bad
              
              foo.zero?
              foo.negative?
              bar.baz.positive?
              
              # good
              
              foo == 0
              0 > foo
              bar.baz > 0

              Use safe navigation (&.) instead of checking if an object exists before calling the method.
              Open

                    new_image_file.destroy unless new_image_file.nil?

              This cop transforms usages of a method call safeguarded by a non nil check for the variable whose method is being called to safe navigation (&.).

              Configuration option: ConvertCodeThatCanStartToReturnNil The default for this is false. When configured to true, this will check for code in the format !foo.nil? && foo.bar. As it is written, the return of this code is limited to false and whatever the return of the method is. If this is converted to safe navigation, foo&.bar can start returning nil as well as what the method returns.

              Example:

              # bad
              foo.bar if foo
              foo.bar(param1, param2) if foo
              foo.bar { |e| e.something } if foo
              foo.bar(param) { |e| e.something } if foo
              
              foo.bar if !foo.nil?
              foo.bar unless !foo
              foo.bar unless foo.nil?
              
              foo && foo.bar
              foo && foo.bar(param1, param2)
              foo && foo.bar { |e| e.something }
              foo && foo.bar(param) { |e| e.something }
              
              # good
              foo&.bar
              foo&.bar(param1, param2)
              foo&.bar { |e| e.something }
              foo&.bar(param) { |e| e.something }
              
              foo.nil? || foo.bar
              !foo || foo.bar
              
              # Methods that `nil` will `respond_to?` should not be converted to
              # use safe navigation
              foo.to_i if foo

              Convert if nested inside else to elsif.
              Open

                          if params[zoom_class_for_params][:description].nil?

              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

              Use !empty? instead of size > 0.
              Open

                  if @fields.size > 0

              This cop checks for numeric comparisons that can be replaced by a predicate method, such as receiver.length == 0, receiver.length > 0, receiver.length != 0, receiver.length < 1 and receiver.size == 0 that can be replaced by receiver.empty? and !receiver.empty.

              Example:

              # bad
              [1, 2, 3].length == 0
              0 == "foobar".length
              array.length < 1
              {a: 1, b: 2}.length != 0
              string.length > 0
              hash.size > 0
              
              # good
              [1, 2, 3].empty?
              "foobar".empty?
              array.empty?
              !{a: 1, b: 2}.empty?
              !string.empty?
              !hash.empty?

              Useless assignment to variable - related_accession_record.
              Open

                          related_accession_record = nil

              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

                    if !params[zoom_class_for_params][:description].nil?
                      params[zoom_class_for_params][:description] = SystemSetting.description_template + "\n\n" + params[zoom_class_for_params][:description]
                    else
                      params[zoom_class_for_params][:description] = SystemSetting.description_template
                    end

              Favor unless over if for negative conditions.
              Open

                  if !options[:description_end_template].nil?
                    # append the description_end_template to the description field
                    if !params[zoom_class_for_params][:description].nil?
                      params[zoom_class_for_params][:description] += "\n\n" + options[:description_end_template]
                    else

              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 @record_interval.positive? instead of @record_interval > 0.
              Open

                  sleep(@record_interval) if @record_interval > 0

              This cop checks for usage of comparison operators (==, >, <) to test numbers as zero, positive, or negative. These can be replaced by their respective predicate methods. The cop can also be configured to do the reverse.

              The cop disregards #nonzero? as it its value is truthy or falsey, but not true and false, and thus not always interchangeable with != 0.

              The cop ignores comparisons to global variables, since they are often populated with objects which can be compared with integers, but are not themselves Interger polymorphic.

              Example: EnforcedStyle: predicate (default)

              # bad
              
              foo == 0
              0 > foo
              bar.baz > 0
              
              # good
              
              foo.zero?
              foo.negative?
              bar.baz.positive?

              Example: EnforcedStyle: comparison

              # bad
              
              foo.zero?
              foo.negative?
              bar.baz.positive?
              
              # good
              
              foo == 0
              0 > foo
              bar.baz > 0

              Do not use unless with else. Rewrite these with the positive case first.
              Open

                  unless zoom_class == 'StillImage'
                    new_record_added = new_record.save
                  else
                    new_record_added = new_record.save unless new_image_file.nil?
                  end

              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 !@last_related_topic_pp4_objectid.nil? && (related_topic_pp4_objectid == @last_related_topic_pp4_objectid)
                        related_topic = @last_related_topic
                      else
                        related_topic = Topic.find(
                          :first,

              Avoid rescuing without specifying an error class.
              Open

                  rescue

              This cop checks for rescuing StandardError. There are two supported styles implicit and explicit. This cop will not register an offense if any error other than StandardError is specified.

              Example: EnforcedStyle: implicit

              # `implicit` will enforce using `rescue` instead of
              # `rescue StandardError`.
              
              # bad
              begin
                foo
              rescue StandardError
                bar
              end
              
              # good
              begin
                foo
              rescue
                bar
              end
              
              # good
              begin
                foo
              rescue OtherError
                bar
              end
              
              # good
              begin
                foo
              rescue StandardError, SecurityError
                bar
              end

              Example: EnforcedStyle: explicit (default)

              # `explicit` will enforce using `rescue StandardError`
              # instead of `rescue`.
              
              # bad
              begin
                foo
              rescue
                bar
              end
              
              # good
              begin
                foo
              rescue StandardError
                bar
              end
              
              # good
              begin
                foo
              rescue OtherError
                bar
              end
              
              # good
              begin
                foo
              rescue StandardError, SecurityError
                bar
              end

              Use self-assignment shorthand +=.
              Open

                        @fields = @fields + ancestor.topic_type_to_field_mappings

              This cop enforces the use the shorthand for self-assignment.

              Example:

              # bad
              x = x + 1
              
              # good
              x += 1

              Non-local exit from iterator, without return value. next, break, Array#find, Array#any?, etc. is preferred.
              Open

                      return if line.include?('<Record>')

              This cop checks for non-local exits from iterators without a return value. It registers an offense under these conditions:

              • No value is returned,
              • the block is preceded by a method chain,
              • the block has arguments,
              • the method which receives the block is not define_method or define_singleton_method,
              • the return is not contained in an inner scope, e.g. a lambda or a method definition.

              Example:

              class ItemApi
                rescue_from ValidationError do |e| # non-iteration block with arg
                  return { message: 'validation error' } unless e.errors # allowed
                  error_array = e.errors.map do |error| # block with method chain
                    return if error.suppress? # warned
                    return "#{error.param}: invalid" unless error.message # allowed
                    "#{error.param}: #{error.message}"
                  end
                  { message: 'validation error', errors: error_array }
                end
              
                def update_items
                  transaction do # block without arguments
                    return unless update_necessary? # allowed
                    find_each do |item| # block without method chain
                      return if item.stock == 0 # false-negative...
                      item.update!(foobar: true)
                    end
                  end
                end
              end

              Favor unless over if for negative conditions.
              Open

                        if !@collections_to_skip.include?(record_hash['COLLECTION'])
                          # file may time out
                          related_accession_record = nil
              
                          related_accession_record = @import_accessions_xml_root.elements["#{@record_element_path}[@ACCESSNO=\'#{related_topic_pp4_objectid}\']"]

              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 @fields.size.positive? instead of @fields.size > 0.
              Open

                  if @fields.size > 0

              This cop checks for usage of comparison operators (==, >, <) to test numbers as zero, positive, or negative. These can be replaced by their respective predicate methods. The cop can also be configured to do the reverse.

              The cop disregards #nonzero? as it its value is truthy or falsey, but not true and false, and thus not always interchangeable with != 0.

              The cop ignores comparisons to global variables, since they are often populated with objects which can be compared with integers, but are not themselves Interger polymorphic.

              Example: EnforcedStyle: predicate (default)

              # bad
              
              foo == 0
              0 > foo
              bar.baz > 0
              
              # good
              
              foo.zero?
              foo.negative?
              bar.baz.positive?

              Example: EnforcedStyle: comparison

              # bad
              
              foo.zero?
              foo.negative?
              bar.baz.positive?
              
              # good
              
              foo == 0
              0 > foo
              bar.baz > 0

              Favor modifier if usage when having a single-line body. Another good alternative is the usage of control flow &&/||.
              Open

                        if zoom_class == 'Topic'

              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?

              Unused method argument - args. If it's necessary, use _ or _args as an argument name to indicate that it won't be used. You can also write as create(*) if you want the method to accept any arguments but don't care about them.
              Open

                def create(args = nil)

              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

              Convert if nested inside else to elsif.
              Open

                      return if line.include?('<Record>')

              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

              Non-local exit from iterator, without return value. next, break, Array#find, Array#any?, etc. is preferred.
              Open

                      return

              This cop checks for non-local exits from iterators without a return value. It registers an offense under these conditions:

              • No value is returned,
              • the block is preceded by a method chain,
              • the block has arguments,
              • the method which receives the block is not define_method or define_singleton_method,
              • the return is not contained in an inner scope, e.g. a lambda or a method definition.

              Example:

              class ItemApi
                rescue_from ValidationError do |e| # non-iteration block with arg
                  return { message: 'validation error' } unless e.errors # allowed
                  error_array = e.errors.map do |error| # block with method chain
                    return if error.suppress? # warned
                    return "#{error.param}: invalid" unless error.message # allowed
                    "#{error.param}: #{error.message}"
                  end
                  { message: 'validation error', errors: error_array }
                end
              
                def update_items
                  transaction do # block without arguments
                    return unless update_necessary? # allowed
                    find_each do |item| # block without method chain
                      return if item.stock == 0 # false-negative...
                      item.update!(foobar: true)
                    end
                  end
                end
              end

              Favor unless over if for negative conditions.
              Open

                  params[zoom_class_for_params][:license_id] = @import.license.id if !@import.license.blank?

              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 the return of the conditional for variable assignment and comparison.
              Open

                    if !params[zoom_class_for_params][:description].nil?
                      params[zoom_class_for_params][:description] = @import.description_beginning_template + "\n\n" + params[zoom_class_for_params][:description]
                    else
                      params[zoom_class_for_params][:description] = @import.description_beginning_template
                    end

              Useless assignment to variable - objectid. Did you mean objectid_parts?
              Open

                  objectid = nil

              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

              Favor unless over if for negative conditions.
              Open

                    if !@import_request[:host].scan('horowhenua').blank?
                      @description_end_templates['default'] = 'Any use of this image must be accompanied by the credit "Horowhenua Historical Society Inc."'
                      @description_end_templates[/^f\d/] = 'Any use of this image must be accompanied by the credit "Foxton Historical Society"'
                      @description_end_templates["2000\.000\."] = 'Any use of this image must be accompanied by the credit "Horowhenua District Council"'
              
              

              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 !reason_skipped.blank?
                    importer_log_to_skipped_records(image_file, reason_skipped)
                  end

              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

              Useless assignment to variable - image_file.
              Open

                  image_file = nil

              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

              Favor unless over if for negative conditions.
              Open

                    if !value.blank?
              
                      case record_field
                      when 'TITLE'
                        params[zoom_class_for_params][:title] = value

              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

                          description_end_template = text if !image_objectid.scan(pattern).blank?

              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 !value.nil?
                      value = value.strip
                      # replace \r with \n
                      value.tr("\r", "\n")
                    end

              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 !names_array[1].nil?
                              first_names = names_array[1].split('(')[0].strip
                            end

              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

                  tag_list_array = @import.base_tags.split(',') if !@import.base_tags.blank?

              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

              There are no issues that match your filters.

              Category
              Status