TracksApp/tracks

View on GitHub
app/controllers/todos/todo_create_params_helper.rb

Summary

Maintainability
A
2 hrs
Test Coverage

Class TodoCreateParamsHelper has 24 methods (exceeds 20 allowed). Consider refactoring.
Open

  class TodoCreateParamsHelper
    attr_reader :new_project_created, :new_context_created, :attributes

    def initialize(params, user)
      set_params(params)
Severity: Minor
Found in app/controllers/todos/todo_create_params_helper.rb - About 2 hrs to fix

    Todos::TodoCreateParamsHelper#set_id_by_name refers to 'group' more than self (maybe move it to another class?)
    Open

          group_is_new = group.new_record?
          group.save if group_is_new
          @attributes["#{group_type}_id"] = group.id

    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.

    Todos::TodoCreateParamsHelper has at least 6 instance variables
    Open

      class TodoCreateParamsHelper

    Too Many Instance Variables is a special case of LargeClass.

    Example

    Given this configuration

    TooManyInstanceVariables:
      max_instance_variables: 3

    and this code:

    class TooManyInstanceVariables
      def initialize
        @arg_1 = :dummy
        @arg_2 = :dummy
        @arg_3 = :dummy
        @arg_4 = :dummy
      end
    end

    Reek would emit the following warning:

    test.rb -- 5 warnings:
      [1]:TooManyInstanceVariables has at least 4 instance variables (TooManyInstanceVariables)

    Todos::TodoCreateParamsHelper has at least 24 methods
    Open

      class TodoCreateParamsHelper

    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)

    Todos::TodoCreateParamsHelper#add_errors refers to 'e' more than self (maybe move it to another class?)
    Open

          @errors.each { |e| model.errors.add(e[:attribute], e[:message]) }

    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.

    Todos::TodoCreateParamsHelper#parse_dates calls '@user.prefs' 2 times
    Open

          @attributes['show_from'] = @user.prefs.parse_date(show_from)
          @attributes['due'] = @user.prefs.parse_date(due)

    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.

    Todos::TodoCreateParamsHelper assumes too much for instance variable '@attributes'
    Open

      class TodoCreateParamsHelper

    Classes should not assume that instance variables are set or present outside of the current class definition.

    Good:

    class Foo
      def initialize
        @bar = :foo
      end
    
      def foo?
        @bar == :foo
      end
    end

    Good as well:

    class Foo
      def foo?
        bar == :foo
      end
    
      def bar
        @bar ||= :foo
      end
    end

    Bad:

    class Foo
      def go_foo!
        @bar = :foo
      end
    
      def foo?
        @bar == :foo
      end
    end

    Example

    Running Reek on:

    class Dummy
      def test
        @ivar
      end
    end

    would report:

    [1]:InstanceVariableAssumption: Dummy assumes too much for instance variable @ivar

    Note that this example would trigger this smell warning as well:

    class Parent
      def initialize(omg)
        @omg = omg
      end
    end
    
    class Child < Parent
      def foo
        @omg
      end
    end

    The way to address the smell warning is that you should create an attr_reader to use @omg in the subclass and not access @omg directly like this:

    class Parent
      attr_reader :omg
    
      def initialize(omg)
        @omg = omg
      end
    end
    
    class Child < Parent
      def foo
        omg
      end
    end

    Directly accessing instance variables is considered a smell because it breaks encapsulation and makes it harder to reason about code.

    If you don't want to expose those methods as public API just make them private like this:

    class Parent
      def initialize(omg)
        @omg = omg
      end
    
      private
      attr_reader :omg
    end
    
    class Child < Parent
      def foo
        omg
      end
    end

    Current Support in Reek

    An instance variable must:

    • be set in the constructor
    • or be accessed through a method with lazy initialization / memoization.

    If not, Instance Variable Assumption will be reported.

    Todos::TodoCreateParamsHelper#sequential? calls '@params[:todos_sequential]' 2 times
    Open

          return @params[:todos_sequential].present? && @params[:todos_sequential] == 'true'

    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.

    Todos::TodoCreateParamsHelper#todo_params calls 'params[:todo]' 3 times
    Open

          if params[:todo][:predecessor_dependencies]
            deps = params[:todo][:predecessor_dependencies][:predecessor]
          end
    
          # accept empty :todo hash

    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.

    Todos::TodoCreateParamsHelper#context_name calls '@params['context_name']' 2 times
    Open

          @params['context_name'].strip unless @params['context_name'].nil?

    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.

    Todos::TodoCreateParamsHelper#filter_starred calls '@params[:new_todo_starred]' 2 times
    Open

          if @params[:new_todo_starred]
            @attributes["starred"] = (@params[:new_todo_starred] || "").include? "true"

    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.

    Todos::TodoCreateParamsHelper assumes too much for instance variable '@params'
    Open

      class TodoCreateParamsHelper

    Classes should not assume that instance variables are set or present outside of the current class definition.

    Good:

    class Foo
      def initialize
        @bar = :foo
      end
    
      def foo?
        @bar == :foo
      end
    end

    Good as well:

    class Foo
      def foo?
        bar == :foo
      end
    
      def bar
        @bar ||= :foo
      end
    end

    Bad:

    class Foo
      def go_foo!
        @bar = :foo
      end
    
      def foo?
        @bar == :foo
      end
    end

    Example

    Running Reek on:

    class Dummy
      def test
        @ivar
      end
    end

    would report:

    [1]:InstanceVariableAssumption: Dummy assumes too much for instance variable @ivar

    Note that this example would trigger this smell warning as well:

    class Parent
      def initialize(omg)
        @omg = omg
      end
    end
    
    class Child < Parent
      def foo
        @omg
      end
    end

    The way to address the smell warning is that you should create an attr_reader to use @omg in the subclass and not access @omg directly like this:

    class Parent
      attr_reader :omg
    
      def initialize(omg)
        @omg = omg
      end
    end
    
    class Child < Parent
      def foo
        omg
      end
    end

    Directly accessing instance variables is considered a smell because it breaks encapsulation and makes it harder to reason about code.

    If you don't want to expose those methods as public API just make them private like this:

    class Parent
      def initialize(omg)
        @omg = omg
      end
    
      private
      attr_reader :omg
    end
    
    class Child < Parent
      def foo
        omg
      end
    end

    Current Support in Reek

    An instance variable must:

    • be set in the constructor
    • or be accessed through a method with lazy initialization / memoization.

    If not, Instance Variable Assumption will be reported.

    Todos::TodoCreateParamsHelper#todo_params calls 'params[:todo][:predecessor_dependencies]' 2 times
    Open

          if params[:todo][:predecessor_dependencies]
            deps = params[:todo][:predecessor_dependencies][:predecessor]

    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.

    Todos::TodoCreateParamsHelper#filter_tags calls '@attributes[:tags][:tag]' 2 times
    Open

            @attributes[:tags][:tag] = [@attributes[:tags][:tag]] unless @attributes[:tags][:tag].class == Array

    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.

    Todos::TodoCreateParamsHelper has no descriptive comment
    Open

      class TodoCreateParamsHelper

    Classes and modules are the units of reuse and release. It is therefore considered good practice to annotate every class and module with a brief comment outlining its responsibilities.

    Example

    Given

    class Dummy
      # Do things...
    end

    Reek would emit the following warning:

    test.rb -- 1 warning:
      [1]:Dummy has no descriptive comment (IrresponsibleModule)

    Fixing this is simple - just an explaining comment:

    # The Dummy class is responsible for ...
    class Dummy
      # Do things...
    end

    Todos::TodoCreateParamsHelper#project_name calls '@params['project_name']' 2 times
    Open

          @params['project_name'].strip unless @params['project_name'].nil?

    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.

    Todos::TodoCreateParamsHelper#filter_attributes calls 'params[:request]' 2 times
    Open

          if params[:request]
            @attributes = todo_params(params[:request])

    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.

    Todos::TodoCreateParamsHelper#filter_tags calls '@attributes[:tags]' 5 times
    Open

          if @attributes[:tags]
            # for single tags, @attributed[:tags] returns a hash. For multiple tags,
            # it with return an array of hashes. Make sure it is always an array of hashes
            @attributes[:tags][:tag] = [@attributes[:tags][:tag]] unless @attributes[:tags][:tag].class == Array
            # the REST api may use <tags> which will collide with tags association, so rename tags to add_tags

    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.

    Todos::TodoCreateParamsHelper#filter_attributes performs a nil-check
    Open

          @attributes = {} if @attributes.nil?

    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)

    Todos::TodoCreateParamsHelper#context_name performs a nil-check
    Open

          @params['context_name'].strip unless @params['context_name'].nil?

    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)

    Todos::TodoCreateParamsHelper#todo_params performs a nil-check
    Open

          filtered[:predecessor_dependencies] = { :predecessor => deps } unless deps.nil?

    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)

    Todos::TodoCreateParamsHelper#todo_params doesn't depend on instance state (maybe move it to another class?)
    Open

        def todo_params(params)

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

    Todos::TodoCreateParamsHelper takes parameters ['group_type', 'set'] to 3 methods
    Open

        def find_or_create_group(group_type, set, name)
          return set_id_by_name(group_type, set, name) if specified_by_name?(group_type)
          return set_id_by_id_string(group_type, set, @attributes["#{group_type}_id"]) if specified_by_id?(group_type)
        end
    
    

    In general, a Data Clump occurs when the same two or three items frequently appear together in classes and parameter lists, or when a group of instance variable names start or end with similar substrings.

    The recurrence of the items often means there is duplicate code spread around to handle them. There may be an abstraction missing from the code, making the system harder to understand.

    Example

    Given

    class Dummy
      def x(y1,y2); end
      def y(y1,y2); end
      def z(y1,y2); end
    end

    Reek would emit the following warning:

    test.rb -- 1 warning:
      [2, 3, 4]:Dummy takes parameters [y1, y2] to 3 methods (DataClump)

    A possible way to fix this problem (quoting from Martin Fowler):

    The first step is to replace data clumps with objects and use the objects whenever you see them. An immediate benefit is that you'll shrink some parameter lists. The interesting stuff happens as you begin to look for behavior to move into the new objects.

    Todos::TodoCreateParamsHelper#project_name performs a nil-check
    Open

          @params['project_name'].strip unless @params['project_name'].nil?

    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)

    Todos::TodoCreateParamsHelper#add_errors has the variable name 'e'
    Open

          @errors.each { |e| model.errors.add(e[:attribute], e[:message]) }

    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.

    Missing magic comment # frozen_string_literal: true.
    Open

    module Todos

    This cop is designed to help upgrade to Ruby 3.0. It will add the comment # frozen_string_literal: true to the top of files to enable frozen string literals. Frozen string literals may be default in Ruby 3.0. The comment will be added below a shebang and encoding comment. The frozen string literal comment is only valid in Ruby 2.3+.

    Example: EnforcedStyle: when_needed (default)

    # The `when_needed` style will add the frozen string literal comment
    # to files only when the `TargetRubyVersion` is set to 2.3+.
    # bad
    module Foo
      # ...
    end
    
    # good
    # frozen_string_literal: true
    
    module Foo
      # ...
    end

    Example: EnforcedStyle: always

    # The `always` style will always add the frozen string literal comment
    # to a file, regardless of the Ruby version or if `freeze` or `<<` are
    # called on a string literal.
    # bad
    module Bar
      # ...
    end
    
    # good
    # frozen_string_literal: true
    
    module Bar
      # ...
    end

    Example: EnforcedStyle: never

    # The `never` will enforce that the frozen string literal comment does
    # not exist in a file.
    # bad
    # frozen_string_literal: true
    
    module Baz
      # ...
    end
    
    # good
    module Baz
      # ...
    end

    Closing method call brace must be on the line after the last argument when opening brace is on a separate line from the first argument.
    Open

            :project => [:name])

    This cop checks that the closing brace in a method call is either on the same line as the last method argument, or a new line.

    When using the symmetrical (default) style:

    If a method call's opening brace is on the same line as the first argument of the call, then the closing brace should be on the same line as the last argument of the call.

    If an method call's opening brace is on the line above the first argument of the call, then the closing brace should be on the line below the last argument of the call.

    When using the new_line style:

    The closing brace of a multi-line method call must be on the line after the last argument of the call.

    When using the same_line style:

    The closing brace of a multi-line method call must be on the same line as the last argument of the call.

    Example:

    # symmetrical: bad
      # new_line: good
      # same_line: bad
      foo(a,
        b
      )
    
      # symmetrical: bad
      # new_line: bad
      # same_line: good
      foo(
        a,
        b)
    
      # symmetrical: good
      # new_line: bad
      # same_line: good
      foo(a,
        b)
    
      # symmetrical: good
      # new_line: good
      # same_line: bad
      foo(
        a,
        b
      )

    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 a guard clause instead of wrapping the code inside a conditional expression.
    Open

          if @params[:new_todo_starred]

    Use a guard clause instead of wrapping the code inside a conditional expression

    Example:

    # bad
    def test
      if something
        work
      end
    end
    
    # good
    def test
      return unless something
      work
    end
    
    # also good
    def test
      work if something
    end
    
    # bad
    if something
      raise 'exception'
    else
      ok
    end
    
    # good
    raise 'exception' if something
    ok

    Use a guard clause instead of wrapping the code inside a conditional expression.
    Open

          if @attributes[:tags]

    Use a guard clause instead of wrapping the code inside a conditional expression

    Example:

    # bad
    def test
      if something
        work
      end
    end
    
    # good
    def test
      return unless something
      work
    end
    
    # also good
    def test
      work if something
    end
    
    # bad
    if something
      raise 'exception'
    else
      ok
    end
    
    # good
    raise 'exception' if something
    ok

    Redundant return detected.
    Open

          return @params[:todos_sequential].present? && @params[:todos_sequential] == 'true'

    This cop checks for redundant return expressions.

    Example:

    def test
      return something
    end
    
    def test
      one
      two
      three
      return something
    end

    It should be extended to handle methods whose body is if/else or a case expression with a default branch.

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

          if @params[:new_todo_starred]

    Checks for if and unless statements that would fit on one line if written as a modifier if/unless. The maximum line length is configured in the Metrics/LineLength cop.

    Example:

    # bad
    if condition
      do_stuff(bar)
    end
    
    unless qux.empty?
      Foo.do_something
    end
    
    # good
    do_stuff(bar) if condition
    Foo.do_something unless qux.empty?

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

          @params['project_name'].strip unless @params['project_name'].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

    Do not prefix writer method names with set_.
    Open

        def set_params(params)

    This cop makes sure that accessor methods are named properly.

    Example:

    # bad
    def set_attribute(value)
    end
    
    # good
    def attribute=(value)
    end
    
    # bad
    def get_attribute
    end
    
    # good
    def attribute
    end

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

          if params[:todo].empty?

    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?

    rescue at 160, 6 is not aligned with end at 162, 4.
    Open

          rescue

    This cop checks whether the rescue and ensure keywords are aligned properly.

    Example:

    # bad
    begin
      something
      rescue
      puts 'error'
    end
    
    # good
    begin
      something
    rescue
      puts 'error'
    end

    Redundant return detected.
    Open

          return send("#{group_type}_specified_by_name?")

    This cop checks for redundant return expressions.

    Example:

    def test
      return something
    end
    
    def test
      one
      two
      three
      return something
    end

    It should be extended to handle methods whose body is if/else or a case expression with a default branch.

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

          if params[:todo][:predecessor_dependencies]

    Checks for if and unless statements that would fit on one line if written as a modifier if/unless. The maximum line length is configured in the Metrics/LineLength cop.

    Example:

    # bad
    if condition
      do_stuff(bar)
    end
    
    unless qux.empty?
      Foo.do_something
    end
    
    # good
    do_stuff(bar) if condition
    Foo.do_something unless qux.empty?

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

          @params['context_name'].strip unless @params['context_name'].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

    There are no issues that match your filters.

    Category
    Status