Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] allow_nil, type, and must supported at the same time? #24

Closed
luizfonseca opened this issue May 13, 2020 · 3 comments
Closed

Comments

@luizfonseca
Copy link

First, great work with the gem!

I was wondering: are these attributes supported at the same time?

Why

Given the scenario that I have an interactor that looks like this:

class MyInteractor < Actor

    # weekdays is an Array of strings
    input :weekdays, type: Array, must: { 
      be_valid: ->(weekdays) { weekdays.all?(SomeValidation)  } 
    }, default: DefaultWeekdays, allow_nil: true
end

In this scenario, weekdays is optional. If this input is not sent, it defaults to something else. The issue I am having at the moment is that it can also be nil and that would also trigger the usage of the defaults.

I get a ServiceActor::ArgumentError, because in the must: validation weekdays is nil -- fixing it implies in using weekdays.nil? || ... to allow this optional scenario.

Is that expected or am I missing something here?

Again, thanks for the great work 🙏

@luizfonseca luizfonseca changed the title [Question] Is allow_nil, type, and must supported at the same time? [Question] allow_nil, type, and must supported at the same time? May 13, 2020
@sunny
Copy link
Owner

sunny commented May 13, 2020

Hey @luizfonseca!

Actually the default is applied only if the argument is not given. When given, the default is never applied, even if it's nil.

The reasoning behind this is to be able to actually pass nil as a value. This is similar to the way Ruby methods assign defaults. For example:

def my_method(weekdays: [0, 1])
  weekdays
end

my_method # => [0, 1]
my_method(weekdays: nil) # => nil

If you want nil to fallback to the default, you could do something like the following:

class MyInteractor < Actor
  input :weekdays,
        type: Array,
        must: {
          be_valid: ->(weekdays) {
            weekdays.nil? || weekdays.all?(SomeValidation)
          }
        },
        allow_nil: true

  def call
    # …
  end

  def weekdays
    super || DEFAULT_WEEKDAYS
  end
end

Does that clarify your issue? I'm open to suggestions as to how to make this simpler. Perhaps we could have another option to allow using the given default when the input is nil? For example, calling it fallback instead of default could be an idea.

sunny added a commit that referenced this issue May 13, 2020
@sunny
Copy link
Owner

sunny commented May 18, 2020

Luiz, I added a spec with your use-case in a0df1f7. Hopefully this clarifies a bit more the current behavior.

@luizfonseca
Copy link
Author

@sunny It does! Thanks for the clarifications! 🙏

I am going to close the issue, as my original point has been clarified. Thank you for the great work on the library 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants