sanger/sequencescape

View on GitHub
app/models/bulk_submission.rb

Summary

Maintainability
D
2 days
Test Coverage
A
93%

Complex method BulkSubmission#prepare_order (141.2)
Open

  def prepare_order(details) # rubocop:todo Metrics/CyclomaticComplexity
    # Retrieve common attributes
    study = Study.find_by_id_or_name!(details['study id'], details['study name'])
    project = Project.find_by_id_or_name!(details['project id'], details['project name'])
    user = User.find_by(login: details['user login']) or
Severity: Minor
Found in app/models/bulk_submission.rb by flog

Flog calculates the ABC score for methods. The ABC score is based on assignments, branches (method calls), and conditions.

You can read more about ABC metrics or the flog tool

Complex method BulkSubmission#process (89.1)
Open

  def process # rubocop:todo Metrics/CyclomaticComplexity
    # Store the details of the successful submissions so the user can be presented with a summary
    @submission_ids = []
    @completed_submissions = {}

Severity: Minor
Found in app/models/bulk_submission.rb by flog

Flog calculates the ABC score for methods. The ABC score is based on assignments, branches (method calls), and conditions.

You can read more about ABC metrics or the flog tool

Complex method BulkSubmission#submission_structure (64.7)
Open

  def submission_structure # rubocop:todo Metrics/CyclomaticComplexity
    Hash
      .new { |h, i| h[i] = Array.new }
      .tap do |submission|
        csv_data_rows.each_with_index do |row, index|
Severity: Minor
Found in app/models/bulk_submission.rb by flog

Flog calculates the ABC score for methods. The ABC score is based on assignments, branches (method calls), and conditions.

You can read more about ABC metrics or the flog tool

File bulk_submission.rb has 325 lines of code (exceeds 250 allowed). Consider refactoring.
Open

module ArrayWithFieldList
  refine Array do
    def comma_separate_field_list_for_display(*fields)
      field_list(*fields).join(', ')
    end
Severity: Minor
Found in app/models/bulk_submission.rb - About 3 hrs to fix

    Method prepare_order has a Cognitive Complexity of 26 (exceeds 5 allowed). Consider refactoring.
    Open

      def prepare_order(details) # rubocop:todo Metrics/CyclomaticComplexity
        # Retrieve common attributes
        study = Study.find_by_id_or_name!(details['study id'], details['study name'])
        project = Project.find_by_id_or_name!(details['project id'], details['project name'])
        user = User.find_by(login: details['user login']) or
    Severity: Minor
    Found in app/models/bulk_submission.rb - About 3 hrs 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 process has a Cognitive Complexity of 24 (exceeds 5 allowed). Consider refactoring.
    Open

      def process # rubocop:todo Metrics/CyclomaticComplexity
        # Store the details of the successful submissions so the user can be presented with a summary
        @submission_ids = []
        @completed_submissions = {}
    
    
    Severity: Minor
    Found in app/models/bulk_submission.rb - About 3 hrs 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 prepare_order has 65 lines of code (exceeds 25 allowed). Consider refactoring.
    Open

      def prepare_order(details) # rubocop:todo Metrics/CyclomaticComplexity
        # Retrieve common attributes
        study = Study.find_by_id_or_name!(details['study id'], details['study name'])
        project = Project.find_by_id_or_name!(details['project id'], details['project name'])
        user = User.find_by(login: details['user login']) or
    Severity: Major
    Found in app/models/bulk_submission.rb - About 2 hrs to fix

      Class BulkSubmission has 23 methods (exceeds 20 allowed). Consider refactoring.
      Open

      class BulkSubmission # rubocop:todo Metrics/ClassLength
        # Activates the ArrayWithFieldList refinements for this class
        using ArrayWithFieldList
      
        # This is the default output from excel
      Severity: Minor
      Found in app/models/bulk_submission.rb - About 2 hrs to fix

        Method process has 43 lines of code (exceeds 25 allowed). Consider refactoring.
        Open

          def process # rubocop:todo Metrics/CyclomaticComplexity
            # Store the details of the successful submissions so the user can be presented with a summary
            @submission_ids = []
            @completed_submissions = {}
        
        
        Severity: Minor
        Found in app/models/bulk_submission.rb - About 1 hr to fix

          Method submission_structure has 32 lines of code (exceeds 25 allowed). Consider refactoring.
          Open

            def submission_structure # rubocop:todo Metrics/CyclomaticComplexity
              Hash
                .new { |h, i| h[i] = Array.new }
                .tap do |submission|
                  csv_data_rows.each_with_index do |row, index|
          Severity: Minor
          Found in app/models/bulk_submission.rb - About 1 hr to fix

            Array#field_list contains iterators nested 2 deep
            Open

                  map { |row| fields.map { |field| row[field] } }.flatten.delete_if(&:blank?)
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            A Nested Iterator occurs when a block contains another block.

            Example

            Given

            class Duck
              class << self
                def duck_names
                  %i!tick trick track!.each do |surname|
                    %i!duck!.each do |last_name|
                      puts "full name is #{surname} #{last_name}"
                    end
                  end
                end
              end
            end

            Reek would report the following warning:

            test.rb -- 1 warning:
              [5]:Duck#duck_names contains iterators nested 2 deep (NestedIterators)

            BulkSubmission#assign_value_if_source_present has 4 parameters
            Open

              def assign_value_if_source_present(source_obj, source_key, target_obj, target_key)
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            A Long Parameter List occurs when a method has a lot of parameters.

            Example

            Given

            class Dummy
              def long_list(foo,bar,baz,fling,flung)
                puts foo,bar,baz,fling,flung
              end
            end

            Reek would report the following warning:

            test.rb -- 1 warning:
              [2]:Dummy#long_list has 5 parameters (LongParameterList)

            A common solution to this problem would be the introduction of parameter objects.

            BulkSubmission#submission_structure has approx 17 statements
            Open

              def submission_structure # rubocop:todo Metrics/CyclomaticComplexity
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            A method with Too Many Statements is any method that has a large number of lines.

            Too Many Statements warns about any method that has more than 5 statements. Reek's smell detector for Too Many Statements counts +1 for every simple statement in a method and +1 for every statement within a control structure (if, else, case, when, for, while, until, begin, rescue) but it doesn't count the control structure itself.

            So the following method would score +6 in Reek's statement-counting algorithm:

            def parse(arg, argv, &error)
              if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0]))
                return nil, block, nil                                         # +1
              end
              opt = (val = parse_arg(val, &error))[1]                          # +2
              val = conv_arg(*val)                                             # +3
              if opt and !arg
                argv.shift                                                     # +4
              else
                val[0] = nil                                                   # +5
              end
              val                                                              # +6
            end

            (You might argue that the two assigments within the first @if@ should count as statements, and that perhaps the nested assignment should count as +2.)

            BulkSubmission#shared_options! has approx 6 statements
            Open

              def shared_options!(rows) # rubocop:todo Metrics/MethodLength
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            A method with Too Many Statements is any method that has a large number of lines.

            Too Many Statements warns about any method that has more than 5 statements. Reek's smell detector for Too Many Statements counts +1 for every simple statement in a method and +1 for every statement within a control structure (if, else, case, when, for, while, until, begin, rescue) but it doesn't count the control structure itself.

            So the following method would score +6 in Reek's statement-counting algorithm:

            def parse(arg, argv, &error)
              if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0]))
                return nil, block, nil                                         # +1
              end
              opt = (val = parse_arg(val, &error))[1]                          # +2
              val = conv_arg(*val)                                             # +3
              if opt and !arg
                argv.shift                                                     # +4
              else
                val[0] = nil                                                   # +5
              end
              val                                                              # +6
            end

            (You might argue that the two assigments within the first @if@ should count as statements, and that perhaps the nested assignment should count as +2.)

            BulkSubmission#submission_structure contains iterators nested 2 deep
            Open

            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            A Nested Iterator occurs when a block contains another block.

            Example

            Given

            class Duck
              class << self
                def duck_names
                  %i!tick trick track!.each do |surname|
                    %i!duck!.each do |last_name|
                      puts "full name is #{surname} #{last_name}"
                    end
                  end
                end
              end
            end

            Reek would report the following warning:

            test.rb -- 1 warning:
              [5]:Duck#duck_names contains iterators nested 2 deep (NestedIterators)

            BulkSubmission#shared_options! contains iterators nested 2 deep
            Open

                    provided_values = option.map { |o| "'#{o}'" }.to_sentence
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            A Nested Iterator occurs when a block contains another block.

            Example

            Given

            class Duck
              class << self
                def duck_names
                  %i!tick trick track!.each do |surname|
                    %i!duck!.each do |last_name|
                      puts "full name is #{surname} #{last_name}"
                    end
                  end
                end
              end
            end

            Reek would report the following warning:

            test.rb -- 1 warning:
              [5]:Duck#duck_names contains iterators nested 2 deep (NestedIterators)

            BulkSubmission#prepare_order has approx 31 statements
            Open

              def prepare_order(details) # rubocop:todo Metrics/CyclomaticComplexity
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            A method with Too Many Statements is any method that has a large number of lines.

            Too Many Statements warns about any method that has more than 5 statements. Reek's smell detector for Too Many Statements counts +1 for every simple statement in a method and +1 for every statement within a control structure (if, else, case, when, for, while, until, begin, rescue) but it doesn't count the control structure itself.

            So the following method would score +6 in Reek's statement-counting algorithm:

            def parse(arg, argv, &error)
              if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0]))
                return nil, block, nil                                         # +1
              end
              opt = (val = parse_arg(val, &error))[1]                          # +2
              val = conv_arg(*val)                                             # +3
              if opt and !arg
                argv.shift                                                     # +4
              else
                val[0] = nil                                                   # +5
              end
              val                                                              # +6
            end

            (You might argue that the two assigments within the first @if@ should count as statements, and that perhaps the nested assignment should count as +2.)

            BulkSubmission#process has approx 21 statements
            Open

              def process # rubocop:todo Metrics/CyclomaticComplexity
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            A method with Too Many Statements is any method that has a large number of lines.

            Too Many Statements warns about any method that has more than 5 statements. Reek's smell detector for Too Many Statements counts +1 for every simple statement in a method and +1 for every statement within a control structure (if, else, case, when, for, while, until, begin, rescue) but it doesn't count the control structure itself.

            So the following method would score +6 in Reek's statement-counting algorithm:

            def parse(arg, argv, &error)
              if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0]))
                return nil, block, nil                                         # +1
              end
              opt = (val = parse_arg(val, &error))[1]                          # +2
              val = conv_arg(*val)                                             # +3
              if opt and !arg
                argv.shift                                                     # +4
              else
                val[0] = nil                                                   # +5
              end
              val                                                              # +6
            end

            (You might argue that the two assigments within the first @if@ should count as statements, and that perhaps the nested assignment should count as +2.)

            BulkSubmission#validate_entry has 4 parameters
            Open

              def validate_entry(header, pos, row, index)
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            A Long Parameter List occurs when a method has a lot of parameters.

            Example

            Given

            class Dummy
              def long_list(foo,bar,baz,fling,flung)
                puts foo,bar,baz,fling,flung
              end
            end

            Reek would report the following warning:

            test.rb -- 1 warning:
              [2]:Dummy#long_list has 5 parameters (LongParameterList)

            A common solution to this problem would be the introduction of parameter objects.

            BulkSubmission#shared_options! refers to 'option' more than self (maybe move it to another class?)
            Open

                  if option.count > 1
                    provided_values = option.map { |o| "'#{o}'" }.to_sentence
                    errors.add(
                      :spreadsheet,
                      # rubocop:todo Layout/LineLength
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            Feature Envy occurs when a code fragment references another object more often than it references itself, or when several clients do the same series of manipulations on a particular type of object.

            Feature Envy reduces the code's ability to communicate intent: code that "belongs" on one class but which is located in another can be hard to find, and may upset the "System of Names" in the host class.

            Feature Envy also affects the design's flexibility: A code fragment that is in the wrong class creates couplings that may not be natural within the application's domain, and creates a loss of cohesion in the unwilling host class.

            Feature Envy often arises because it must manipulate other objects (usually its arguments) to get them into a useful form, and one force preventing them (the arguments) doing this themselves is that the common knowledge lives outside the arguments, or the arguments are of too basic a type to justify extending that type. Therefore there must be something which 'knows' about the contents or purposes of the arguments. That thing would have to be more than just a basic type, because the basic types are either containers which don't know about their contents, or they are single objects which can't capture their relationship with their fellows of the same type. So, this thing with the extra knowledge should be reified into a class, and the utility method will most likely belong there.

            Example

            Running Reek on:

            class Warehouse
              def sale_price(item)
                (item.price - item.rebate) * @vat
              end
            end

            would report:

            Warehouse#total_price refers to item more than self (FeatureEnvy)

            since this:

            (item.price - item.rebate)

            belongs to the Item class, not the Warehouse.

            BulkSubmission#prepare_order refers to 'details' more than self (maybe move it to another class?)
            Open

                study = Study.find_by_id_or_name!(details['study id'], details['study name'])
                project = Project.find_by_id_or_name!(details['project id'], details['project name'])
                user = User.find_by(login: details['user login']) or
                  raise StandardError, "Cannot find user #{details['user login'].inspect}"
            
            
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            Feature Envy occurs when a code fragment references another object more often than it references itself, or when several clients do the same series of manipulations on a particular type of object.

            Feature Envy reduces the code's ability to communicate intent: code that "belongs" on one class but which is located in another can be hard to find, and may upset the "System of Names" in the host class.

            Feature Envy also affects the design's flexibility: A code fragment that is in the wrong class creates couplings that may not be natural within the application's domain, and creates a loss of cohesion in the unwilling host class.

            Feature Envy often arises because it must manipulate other objects (usually its arguments) to get them into a useful form, and one force preventing them (the arguments) doing this themselves is that the common knowledge lives outside the arguments, or the arguments are of too basic a type to justify extending that type. Therefore there must be something which 'knows' about the contents or purposes of the arguments. That thing would have to be more than just a basic type, because the basic types are either containers which don't know about their contents, or they are single objects which can't capture their relationship with their fellows of the same type. So, this thing with the extra knowledge should be reified into a class, and the utility method will most likely belong there.

            Example

            Running Reek on:

            class Warehouse
              def sale_price(item)
                (item.price - item.rebate) * @vat
              end
            end

            would report:

            Warehouse#total_price refers to item more than self (FeatureEnvy)

            since this:

            (item.price - item.rebate)

            belongs to the Item class, not the Warehouse.

            BulkSubmission has at least 23 methods
            Open

            class BulkSubmission # rubocop:todo Metrics/ClassLength
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            Too Many Methods is a special case of LargeClass.

            Example

            Given this configuration

            TooManyMethods:
              max_methods: 3

            and this code:

            class TooManyMethods
              def one; end
              def two; end
              def three; end
              def four; end
            end

            Reek would emit the following warning:

            test.rb -- 1 warning:
              [1]:TooManyMethods has at least 4 methods (TooManyMethods)

            BulkSubmission#process contains iterators nested 2 deep
            Open

                      submissions.each do |submission_name, orders|
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            A Nested Iterator occurs when a block contains another block.

            Example

            Given

            class Duck
              class << self
                def duck_names
                  %i!tick trick track!.each do |surname|
                    %i!duck!.each do |last_name|
                      puts "full name is #{surname} #{last_name}"
                    end
                  end
                end
              end
            end

            Reek would report the following warning:

            test.rb -- 1 warning:
              [5]:Duck#duck_names contains iterators nested 2 deep (NestedIterators)

            BulkSubmission#submission_structure refers to 'details' more than self (maybe move it to another class?)
            Open

                      submission[details['submission name']] << details
                    end
                  end
                  .map do |submission_name, rows|
                    order =
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            Feature Envy occurs when a code fragment references another object more often than it references itself, or when several clients do the same series of manipulations on a particular type of object.

            Feature Envy reduces the code's ability to communicate intent: code that "belongs" on one class but which is located in another can be hard to find, and may upset the "System of Names" in the host class.

            Feature Envy also affects the design's flexibility: A code fragment that is in the wrong class creates couplings that may not be natural within the application's domain, and creates a loss of cohesion in the unwilling host class.

            Feature Envy often arises because it must manipulate other objects (usually its arguments) to get them into a useful form, and one force preventing them (the arguments) doing this themselves is that the common knowledge lives outside the arguments, or the arguments are of too basic a type to justify extending that type. Therefore there must be something which 'knows' about the contents or purposes of the arguments. That thing would have to be more than just a basic type, because the basic types are either containers which don't know about their contents, or they are single objects which can't capture their relationship with their fellows of the same type. So, this thing with the extra knowledge should be reified into a class, and the utility method will most likely belong there.

            Example

            Running Reek on:

            class Warehouse
              def sale_price(item)
                (item.price - item.rebate) * @vat
              end
            end

            would report:

            Warehouse#total_price refers to item more than self (FeatureEnvy)

            since this:

            (item.price - item.rebate)

            belongs to the Item class, not the Warehouse.

            Complex method BulkSubmission#process_file (25.3)
            Open

              def process_file # rubocop:todo Metrics/AbcSize
                # Slightly inelegant file-type checking
                # TODO (jr) Find a better way of verifying the CSV file?
                if spreadsheet.present?
                  if spreadsheet.size == 0
            Severity: Minor
            Found in app/models/bulk_submission.rb by flog

            Flog calculates the ABC score for methods. The ABC score is based on assignments, branches (method calls), and conditions.

            You can read more about ABC metrics or the flog tool

            Method process_file has a Cognitive Complexity of 8 (exceeds 5 allowed). Consider refactoring.
            Open

              def process_file # rubocop:todo Metrics/AbcSize
                # Slightly inelegant file-type checking
                # TODO (jr) Find a better way of verifying the CSV file?
                if spreadsheet.present?
                  if spreadsheet.size == 0
            Severity: Minor
            Found in app/models/bulk_submission.rb - About 45 mins 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

            BulkSubmission#process calls 'orders.first' 3 times
            Open

                        user = User.find_by(login: orders.first['user login'])
                        if user.nil?
                          errors.add(
                            :spreadsheet,
                            if orders.first['user login'].nil?
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

            Reek implements a check for Duplicate Method Call.

            Example

            Here's a very much simplified and contrived example. The following method will report a warning:

            def double_thing()
              @other.thing + @other.thing
            end

            One quick approach to silence Reek would be to refactor the code thus:

            def double_thing()
              thing = @other.thing
              thing + thing
            end

            A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

            class Other
              def double_thing()
                thing + thing
              end
            end

            The approach you take will depend on balancing other factors in your code.

            BulkSubmission#prepare_order calls 'details['rows']' 3 times
            Open

                    raise StandardError, "Too few assets found for #{details['rows']}: #{assets_found.inspect}"
                  end
                  if assets_found.size > expecting
                    raise StandardError, "Too many assets found for #{details['rows']}: #{assets_found.inspect}"
                  end
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

            Reek implements a check for Duplicate Method Call.

            Example

            Here's a very much simplified and contrived example. The following method will report a warning:

            def double_thing()
              @other.thing + @other.thing
            end

            One quick approach to silence Reek would be to refactor the code thus:

            def double_thing()
              thing = @other.thing
              thing + thing
            end

            A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

            class Other
              def double_thing()
                thing + thing
              end
            end

            The approach you take will depend on balancing other factors in your code.

            BulkSubmission#process calls 'submission.id' 3 times
            Open

                          @submission_ids << submission.id
                          @completed_submissions[submission.id] =
                            "Submission #{submission.id} built (#{submission.orders.count} orders)"
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

            Reek implements a check for Duplicate Method Call.

            Example

            Here's a very much simplified and contrived example. The following method will report a warning:

            def double_thing()
              @other.thing + @other.thing
            end

            One quick approach to silence Reek would be to refactor the code thus:

            def double_thing()
              thing = @other.thing
              thing + thing
            end

            A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

            class Other
              def double_thing()
                thing + thing
              end
            end

            The approach you take will depend on balancing other factors in your code.

            BulkSubmission#prepare_order calls 'request_options['library_type']' 3 times
            Open

                if request_options['library_type'].present?
                  # find is case insensitive but we want the correct case sensitive name for requests or we get issues downstream in
                  # NPG
                  lt = LibraryType.find_by(name: request_options['library_type'])&.name or
                    raise StandardError, "Cannot find library type #{request_options['library_type'].inspect}"
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

            Reek implements a check for Duplicate Method Call.

            Example

            Here's a very much simplified and contrived example. The following method will report a warning:

            def double_thing()
              @other.thing + @other.thing
            end

            One quick approach to silence Reek would be to refactor the code thus:

            def double_thing()
              thing = @other.thing
              thing + thing
            end

            A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

            class Other
              def double_thing()
                thing + thing
              end
            end

            The approach you take will depend on balancing other factors in your code.

            BulkSubmission#submission_structure calls 'index + start_row' 2 times
            Open

                          .filter_map { |header, pos| validate_entry(header, pos, row, index + start_row) }
                          .to_h
                          .merge('row' => index + start_row)
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

            Reek implements a check for Duplicate Method Call.

            Example

            Here's a very much simplified and contrived example. The following method will report a warning:

            def double_thing()
              @other.thing + @other.thing
            end

            One quick approach to silence Reek would be to refactor the code thus:

            def double_thing()
              thing = @other.thing
              thing + thing
            end

            A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

            class Other
              def double_thing()
                thing + thing
              end
            end

            The approach you take will depend on balancing other factors in your code.

            BulkSubmission#assign_value_if_source_present calls 'source_obj[source_key]' 2 times
            Open

                target_obj[target_key] = source_obj[source_key] if source_obj[source_key].present?
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

            Reek implements a check for Duplicate Method Call.

            Example

            Here's a very much simplified and contrived example. The following method will report a warning:

            def double_thing()
              @other.thing + @other.thing
            end

            One quick approach to silence Reek would be to refactor the code thus:

            def double_thing()
              thing = @other.thing
              thing + thing
            end

            A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

            class Other
              def double_thing()
                thing + thing
              end
            end

            The approach you take will depend on balancing other factors in your code.

            BulkSubmission#validate_entry calls 'row[pos]' 2 times
            Open

                return translate(header), row[pos].try(:strip) unless header.nil? && row[pos].present?
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

            Reek implements a check for Duplicate Method Call.

            Example

            Here's a very much simplified and contrived example. The following method will report a warning:

            def double_thing()
              @other.thing + @other.thing
            end

            One quick approach to silence Reek would be to refactor the code thus:

            def double_thing()
              thing = @other.thing
              thing + thing
            end

            A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

            class Other
              def double_thing()
                thing + thing
              end
            end

            The approach you take will depend on balancing other factors in your code.

            BulkSubmission#prepare_order calls 'assets_found.inspect' 2 times
            Open

                    raise StandardError, "Too few assets found for #{details['rows']}: #{assets_found.inspect}"
                  end
                  if assets_found.size > expecting
                    raise StandardError, "Too many assets found for #{details['rows']}: #{assets_found.inspect}"
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

            Reek implements a check for Duplicate Method Call.

            Example

            Here's a very much simplified and contrived example. The following method will report a warning:

            def double_thing()
              @other.thing + @other.thing
            end

            One quick approach to silence Reek would be to refactor the code thus:

            def double_thing()
              thing = @other.thing
              thing + thing
            end

            A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

            class Other
              def double_thing()
                thing + thing
              end
            end

            The approach you take will depend on balancing other factors in your code.

            BulkSubmission#add_study_to_assets calls 'sample.studies' 2 times
            Open

                assets.map(&:samples).flatten.uniq.each { |sample| sample.studies << study unless sample.studies.include?(study) }
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

            Reek implements a check for Duplicate Method Call.

            Example

            Here's a very much simplified and contrived example. The following method will report a warning:

            def double_thing()
              @other.thing + @other.thing
            end

            One quick approach to silence Reek would be to refactor the code thus:

            def double_thing()
              thing = @other.thing
              thing + thing
            end

            A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

            class Other
              def double_thing()
                thing + thing
              end
            end

            The approach you take will depend on balancing other factors in your code.

            BulkSubmission#prepare_order calls 'details['user login']' 2 times
            Open

                user = User.find_by(login: details['user login']) or
                  raise StandardError, "Cannot find user #{details['user login'].inspect}"
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

            Reek implements a check for Duplicate Method Call.

            Example

            Here's a very much simplified and contrived example. The following method will report a warning:

            def double_thing()
              @other.thing + @other.thing
            end

            One quick approach to silence Reek would be to refactor the code thus:

            def double_thing()
              thing = @other.thing
              thing + thing
            end

            A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

            class Other
              def double_thing()
                thing + thing
              end
            end

            The approach you take will depend on balancing other factors in your code.

            BulkSubmission#prepare_order calls 'details['asset group name']' 2 times
            Open

                  study.asset_groups.find_by_id_or_name(details['asset group id'], details['asset group name'])
                attributes[:asset_group_name] = details['asset group name'] if attributes[:asset_group].nil?
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

            Reek implements a check for Duplicate Method Call.

            Example

            Here's a very much simplified and contrived example. The following method will report a warning:

            def double_thing()
              @other.thing + @other.thing
            end

            One quick approach to silence Reek would be to refactor the code thus:

            def double_thing()
              thing = @other.thing
              thing + thing
            end

            A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

            class Other
              def double_thing()
                thing + thing
              end
            end

            The approach you take will depend on balancing other factors in your code.

            BulkSubmission#process calls 'orders.first['user login']' 3 times
            Open

                        user = User.find_by(login: orders.first['user login'])
                        if user.nil?
                          errors.add(
                            :spreadsheet,
                            if orders.first['user login'].nil?
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

            Reek implements a check for Duplicate Method Call.

            Example

            Here's a very much simplified and contrived example. The following method will report a warning:

            def double_thing()
              @other.thing + @other.thing
            end

            One quick approach to silence Reek would be to refactor the code thus:

            def double_thing()
              thing = @other.thing
              thing + thing
            end

            A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

            class Other
              def double_thing()
                thing + thing
              end
            end

            The approach you take will depend on balancing other factors in your code.

            BulkSubmission#prepare_order calls 'assets_found.size' 2 times
            Open

                  if assets_found.size < expecting
                    raise StandardError, "Too few assets found for #{details['rows']}: #{assets_found.inspect}"
                  end
                  if assets_found.size > expecting
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

            Reek implements a check for Duplicate Method Call.

            Example

            Here's a very much simplified and contrived example. The following method will report a warning:

            def double_thing()
              @other.thing + @other.thing
            end

            One quick approach to silence Reek would be to refactor the code thus:

            def double_thing()
              thing = @other.thing
              thing + thing
            end

            A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

            class Other
              def double_thing()
                thing + thing
              end
            end

            The approach you take will depend on balancing other factors in your code.

            BulkSubmission#prepare_order calls 'attributes[:asset_group]' 5 times
            Open

                attributes[:asset_group_name] = details['asset group name'] if attributes[:asset_group].nil?
            
                ##
                # We go ahead and find our assets regardless of whether we have an asset group.
                # While this takes longer, it helps to detect cases where an asset group name has been
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

            Reek implements a check for Duplicate Method Call.

            Example

            Here's a very much simplified and contrived example. The following method will report a warning:

            def double_thing()
              @other.thing + @other.thing
            end

            One quick approach to silence Reek would be to refactor the code thus:

            def double_thing()
              thing = @other.thing
              thing + thing
            end

            A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

            class Other
              def double_thing()
                thing + thing
              end
            end

            The approach you take will depend on balancing other factors in your code.

            BulkSubmission#prepare_order calls 'attributes[:asset_group].nil?' 2 times
            Open

                attributes[:asset_group_name] = details['asset group name'] if attributes[:asset_group].nil?
            
                ##
                # We go ahead and find our assets regardless of whether we have an asset group.
                # While this takes longer, it helps to detect cases where an asset group name has been
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

            Reek implements a check for Duplicate Method Call.

            Example

            Here's a very much simplified and contrived example. The following method will report a warning:

            def double_thing()
              @other.thing + @other.thing
            end

            One quick approach to silence Reek would be to refactor the code thus:

            def double_thing()
              thing = @other.thing
              thing + thing
            end

            A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

            class Other
              def double_thing()
                thing + thing
              end
            end

            The approach you take will depend on balancing other factors in your code.

            BulkSubmission#max_priority calls 'order['priority']' 2 times
            Open

                  priority = Submission::Priorities.priorities.index(order['priority']) || order['priority'].to_i
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

            Reek implements a check for Duplicate Method Call.

            Example

            Here's a very much simplified and contrived example. The following method will report a warning:

            def double_thing()
              @other.thing + @other.thing
            end

            One quick approach to silence Reek would be to refactor the code thus:

            def double_thing()
              thing = @other.thing
              thing + thing
            end

            A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

            class Other
              def double_thing()
                thing + thing
              end
            end

            The approach you take will depend on balancing other factors in your code.

            BulkSubmission has missing safe method 'shared_options!'
            Open

              def shared_options!(rows) # rubocop:todo Metrics/MethodLength
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            A candidate method for the Missing Safe Method smell are methods whose names end with an exclamation mark.

            An exclamation mark in method names means (the explanation below is taken from here ):

            The ! in method names that end with ! means, “This method is dangerous”—or, more precisely, this method is the “dangerous” version of an otherwise equivalent method, with the same name minus the !. “Danger” is relative; the ! doesn’t mean anything at all unless the method name it’s in corresponds to a similar but bang-less method name. So, for example, gsub! is the dangerous version of gsub. exit! is the dangerous version of exit. flatten! is the dangerous version of flatten. And so forth.

            Such a method is called Missing Safe Method if and only if her non-bang version does not exist and this method is reported as a smell.

            Example

            Given

            class C
              def foo; end
              def foo!; end
              def bar!; end
            end

            Reek would report bar! as Missing Safe Method smell but not foo!.

            Reek reports this smell only in a class context, not in a module context in order to allow perfectly legit code like this:

            class Parent
              def foo; end
            end
            
            module Dangerous
              def foo!; end
            end
            
            class Son < Parent
              include Dangerous
            end
            
            class Daughter < Parent
            end

            In this example, Reek would not report the Missing Safe Method smell for the method foo of the Dangerous module.

            BulkSubmission#spreadsheet is a writable attribute
            Open

              attr_accessor :spreadsheet, :encoding
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            A class that publishes a setter for an instance variable invites client classes to become too intimate with its inner workings, and in particular with its representation of state.

            The same holds to a lesser extent for getters, but Reek doesn't flag those.

            Example

            Given:

            class Klass
              attr_accessor :dummy
            end

            Reek would emit the following warning:

            reek test.rb
            
            test.rb -- 1 warning:
              [2]:Klass declares the writable attribute dummy (Attribute)

            BulkSubmission#headers performs a nil-check
            Open

                @headers ||= filter_end_of_header(@csv_rows.fetch(header_index)) unless header_index.nil?
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            A NilCheck is a type check. Failures of NilCheck violate the "tell, don't ask" principle.

            Additionally, type checks often mask bigger problems in your source code like not using OOP and / or polymorphism when you should.

            Example

            Given

            class Klass
              def nil_checker(argument)
                if argument.nil?
                  puts "argument isn't nil!"
                end
              end
            end

            Reek would emit the following warning:

            test.rb -- 1 warning:
              [3]:Klass#nil_checker performs a nil-check. (NilCheck)

            BulkSubmission#validate_entry performs a nil-check
            Open

                return translate(header), row[pos].try(:strip) unless header.nil? && row[pos].present?
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            A NilCheck is a type check. Failures of NilCheck violate the "tell, don't ask" principle.

            Additionally, type checks often mask bigger problems in your source code like not using OOP and / or polymorphism when you should.

            Example

            Given

            class Klass
              def nil_checker(argument)
                if argument.nil?
                  puts "argument isn't nil!"
                end
              end
            end

            Reek would emit the following warning:

            test.rb -- 1 warning:
              [3]:Klass#nil_checker performs a nil-check. (NilCheck)

            BulkSubmission#translate doesn't depend on instance state (maybe move it to another class?)
            Open

              def translate(header)
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            A Utility Function is any instance method that has no dependency on the state of the instance.

            BulkSubmission#valid_header? performs a nil-check
            Open

                return false if headers.nil?
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            A NilCheck is a type check. Failures of NilCheck violate the "tell, don't ask" principle.

            Additionally, type checks often mask bigger problems in your source code like not using OOP and / or polymorphism when you should.

            Example

            Given

            class Klass
              def nil_checker(argument)
                if argument.nil?
                  puts "argument isn't nil!"
                end
              end
            end

            Reek would emit the following warning:

            test.rb -- 1 warning:
              [3]:Klass#nil_checker performs a nil-check. (NilCheck)

            BulkSubmission#header_row? doesn't depend on instance state (maybe move it to another class?)
            Open

              def header_row?(row)
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            A Utility Function is any instance method that has no dependency on the state of the instance.

            BulkSubmission#assign_value_if_source_present doesn't depend on instance state (maybe move it to another class?)
            Open

              def assign_value_if_source_present(source_obj, source_key, target_obj, target_key)
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            A Utility Function is any instance method that has no dependency on the state of the instance.

            BulkSubmission#add_study_to_assets doesn't depend on instance state (maybe move it to another class?)
            Open

              def add_study_to_assets(assets, study)
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            A Utility Function is any instance method that has no dependency on the state of the instance.

            BulkSubmission#max_priority doesn't depend on instance state (maybe move it to another class?)
            Open

              def max_priority(orders)
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            A Utility Function is any instance method that has no dependency on the state of the instance.

            BulkSubmission#process performs a nil-check
            Open

                        if user.nil?
                          errors.add(
                            :spreadsheet,
                            if orders.first['user login'].nil?
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            A NilCheck is a type check. Failures of NilCheck violate the "tell, don't ask" principle.

            Additionally, type checks often mask bigger problems in your source code like not using OOP and / or polymorphism when you should.

            Example

            Given

            class Klass
              def nil_checker(argument)
                if argument.nil?
                  puts "argument isn't nil!"
                end
              end
            end

            Reek would emit the following warning:

            test.rb -- 1 warning:
              [3]:Klass#nil_checker performs a nil-check. (NilCheck)

            BulkSubmission#prepare_order performs a nil-check
            Open

                attributes[:asset_group_name] = details['asset group name'] if attributes[:asset_group].nil?
            
                ##
                # We go ahead and find our assets regardless of whether we have an asset group.
                # While this takes longer, it helps to detect cases where an asset group name has been
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            A NilCheck is a type check. Failures of NilCheck violate the "tell, don't ask" principle.

            Additionally, type checks often mask bigger problems in your source code like not using OOP and / or polymorphism when you should.

            Example

            Given

            class Klass
              def nil_checker(argument)
                if argument.nil?
                  puts "argument isn't nil!"
                end
              end
            end

            Reek would emit the following warning:

            test.rb -- 1 warning:
              [3]:Klass#nil_checker performs a nil-check. (NilCheck)

            BulkSubmission#encoding is a writable attribute
            Open

              attr_accessor :spreadsheet, :encoding
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            A class that publishes a setter for an instance variable invites client classes to become too intimate with its inner workings, and in particular with its representation of state.

            The same holds to a lesser extent for getters, but Reek doesn't flag those.

            Example

            Given:

            class Klass
              attr_accessor :dummy
            end

            Reek would emit the following warning:

            reek test.rb
            
            test.rb -- 1 warning:
              [2]:Klass declares the writable attribute dummy (Attribute)

            BulkSubmission#submission_structure has the variable name 'v'
            Open

                            .delete_if { |_, v| v.blank? }
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            An Uncommunicative Variable Name is a variable name that doesn't communicate its intent well enough.

            Poor names make it hard for the reader to build a mental picture of what's going on in the code. They can also be mis-interpreted; and they hurt the flow of reading, because the reader must slow down to interpret the names.

            BulkSubmission#submission_structure has the variable name 'i'
            Open

                  .new { |h, i| h[i] = Array.new }
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            An Uncommunicative Variable Name is a variable name that doesn't communicate its intent well enough.

            Poor names make it hard for the reader to build a mental picture of what's going on in the code. They can also be mis-interpreted; and they hurt the flow of reading, because the reader must slow down to interpret the names.

            BulkSubmission#prepare_order has the variable name 'e'
            Open

              rescue => e
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            An Uncommunicative Variable Name is a variable name that doesn't communicate its intent well enough.

            Poor names make it hard for the reader to build a mental picture of what's going on in the code. They can also be mis-interpreted; and they hurt the flow of reading, because the reader must slow down to interpret the names.

            BulkSubmission#shared_options! has the variable name 'o'
            Open

                    provided_values = option.map { |o| "'#{o}'" }.to_sentence
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            An Uncommunicative Variable Name is a variable name that doesn't communicate its intent well enough.

            Poor names make it hard for the reader to build a mental picture of what's going on in the code. They can also be mis-interpreted; and they hurt the flow of reading, because the reader must slow down to interpret the names.

            BulkSubmission#submission_structure has the variable name 'h'
            Open

                  .new { |h, i| h[i] = Array.new }
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            An Uncommunicative Variable Name is a variable name that doesn't communicate its intent well enough.

            Poor names make it hard for the reader to build a mental picture of what's going on in the code. They can also be mis-interpreted; and they hurt the flow of reading, because the reader must slow down to interpret the names.

            BulkSubmission#process has the variable name 'e'
            Open

                        rescue Submission::ProjectValidation::Error => e
            Severity: Minor
            Found in app/models/bulk_submission.rb by reek

            An Uncommunicative Variable Name is a variable name that doesn't communicate its intent well enough.

            Poor names make it hard for the reader to build a mental picture of what's going on in the code. They can also be mis-interpreted; and they hurt the flow of reading, because the reader must slow down to interpret the names.

            TODO found
            Open

                # TODO (jr) Find a better way of verifying the CSV file?
            Severity: Minor
            Found in app/models/bulk_submission.rb by fixme

            There are no issues that match your filters.

            Category
            Status