rubyruby-2.4

Conditional passing of parameters when creating an instance of a class


I'm refactoring my code and I want to have some logic passed to a parameter when creating an instance of a class. To best describe the problem, I will share some code.

I have this method that takes in an object as an argument.

def common_attributes(klass)
  klass.new(id: some_id, name: some_name, role_id: some_role.id)
end

I want to be able to use this to do something like:

def common_attributes(klass)
  klass.new(id: some_id,
            name: some_name
            role_id: some_role.id unless Module::class)
end

This is because I have several classes inside my module. Two of these classes take the same three arguments i.e id and name, role_id. The other class takes two arguments id and name. Please note these are example values and the implementation may not make sense problem I but what is important is to understand the problem I have.

This is how I would use the function:

common_attributes(MyModule::Myclass)

common_attributes(MyModule::DifferentClass)

common_attributes(MyModule::AnotherDifferentClass)

How will I ensure that the other class that takes fewer arguments receives the required parameters and leaves out what it does not need?

NB I can not edit the classes to include optional parameters.


Solution

  • You should test for the class of klass inside your method. If, for example, the class that only accepts two attributes is MyModule::Myclass, and everything else accepts tree attributes, then either of these solutions should work:

    def common_attributes(klass)
      case klass
      when MyModule::Myclass
        klass.new(id: some_id, name: some_name)
      else
        klass.new(id: some_id, name: some_name, role_id: some_role.id)
      end
    end
    

    or:

    def common_attributes(klass)
      options = { id: some_id, name: some_name }
    
      if klass.is_a?(MyModule::Myclass)
        options[:role_id] = some_role.id
      end
    
      klass.new(**options)
    end
    

    The checks can grow to cover more special cases as appropriate.