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

Require filter definition for each input #482

Open
nvanoorschot opened this issue Jun 5, 2020 · 2 comments
Open

Require filter definition for each input #482

nvanoorschot opened this issue Jun 5, 2020 · 2 comments

Comments

@nvanoorschot
Copy link

nvanoorschot commented Jun 5, 2020

We sometimes use AI to manually perform certain custom actions. This exposes us to human errors in the naming of optional arguments. Is it possible to have AI fail if arguments are passed for which no filter has been defined?

Example

class ObjectInteraction < ActiveInteraction::Base
  boolean :commit, default: true

  def execute
    commit_transaction if commit?
  end
end

This command will unintentionally commit the transaction since the argument is misspelled.

ObjectInteraction.run!(comit: false)

Solution?

Introduce a class method and/or global option that changes the default behavior.

class ObjectInteraction < ActiveInteraction::Base
  enforce_filters!
end
ObjectInteraction.run!(comit: false)
# => ActiveInteraction::MissingFilterError: no filter defined for argument `comit`
@antulik
Copy link
Contributor

antulik commented Jun 13, 2020

I think that might be useful to have, in the meantime it's possible with a simple module

module EnforceFilters
  extend ActiveSupport::Concern

  MissingFilterError = Class.new(StandardError)

  included do
    class_attribute :enforce_filters
  end

  def populate_reader(key, value)
    if enforce_filters && !respond_to?(key)
      raise MissingFilterError, "no filter defined for argument `#{key}`"
    end
    super
  end

  class_methods do
    def enforce_filters!
      self.enforce_filters = true
    end
  end
end

class ObjectInteraction < ActiveInteraction::Base
  include EnforceFilters

  boolean :commit, default: true

  enforce_filters!

  def execute
    commit
  end
end

ObjectInteraction.run!(comit: false)
# => no filter defined for argument `comit` (EnforceFilters::MissingFilterError)

@MathijsK93
Copy link

I rewrote the example from @antulik so it works for 4.0.5

module EnforceFilters
  extend ActiveSupport::Concern

  MissingFilterError = Class.new(StandardError)

  included do
    class_attribute :enforce_filters
  end

  def populate_filters_and_inputs(inputs)
    validate_arguments(inputs.keys) if enforce_filters

    super
  end

  def validate_arguments(arguments)
    arguments.each do |argument|
      raise MissingFilterError, "no filter defined for argument `#{argument}`" unless respond_to?(argument)
    end
  end

  class_methods do
    def enforce_filters!
      self.enforce_filters = true
    end
  end
end

class ObjectInteraction < ActiveInteraction::Base
  include EnforceFilters

  boolean :commit, default: true

  enforce_filters!

  def execute
    commit
  end
end

ObjectInteraction.run!(comit: false)
# => no filter defined for argument `comit` (EnforceFilters::MissingFilterError)

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

No branches or pull requests

4 participants