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

Support for pattern-matched rules #678

Open
solnic opened this issue Dec 16, 2020 · 10 comments
Open

Support for pattern-matched rules #678

solnic opened this issue Dec 16, 2020 · 10 comments

Comments

@solnic
Copy link
Member

solnic commented Dec 16, 2020

In order to make defining rules that depend on additional conditions nicer, we can have something like this:

params do
  optional(:per_page).value(:integer)
end

rule(:per_page).if(:key?).validate(gt?: 0, lteq?: 20)

See the original conversation: #540 (comment)

@musaffa
Copy link

musaffa commented Dec 16, 2020

Above code won't work. For optional, we will need :key?. What is going to check for maybe? Unlike optional which is related to key, maybe is related to its value.

@solnic
Copy link
Member Author

solnic commented Dec 17, 2020

@musaffa right, thanks - just updated the example. The actual part that needs to be implemented is the if method. The underlying predicates (like key?) will be available OOTB, so we can add value? like you suggested in a separate PR, because essentially it's going to be a separate, new feature as well 🙂

@solnic solnic self-assigned this Jan 12, 2021
@musaffa
Copy link

musaffa commented Apr 25, 2021

@solnic Hi, Is there any update about this feature?

@solnic
Copy link
Member Author

solnic commented Apr 26, 2021

@musaffa hey there, no, nobody has had the time to work on this yet. There's a lot of more important things to do in validation/schema so this needs to wait.

@musaffa
Copy link

musaffa commented Apr 26, 2021

@solnic I can help with implementing this feature. For that, I'll need some guidance from you.

@solnic
Copy link
Member Author

solnic commented Apr 27, 2021

@musaffa that's cool! Feel free to grab this issue. I don't really have any specific idea how to implement this so you need to experiment a bit. Rules are captured via Contract.rule so I think something similar can be done as we have in case of Rule#each. The trick is that each overrides rule's block, and with this if method it should most likely create a rule-like object that would just serve as a guard. Maybe something like this:

# inside rule.rb
def if(*args)
  Guard.new(self, args: args)
end

This Guard thingie would have to quack like a rule, using a decorator should work better than inheriting from Rule. You also need to figure out how to replace the rule with the guard because Contract.rule adds rule instances to the internal rules array. This can be a bit difficult though so...another option is to use a different top-level DSL method for this, like guard(:key?).rule(:foo).validate(:good?).

Yeah...this needs some experimentation to see what makes more sense 🙂

@musaffa
Copy link

musaffa commented Apr 27, 2021

Thanks. I'll look into it.

@solnic
Copy link
Member Author

solnic commented Apr 28, 2021

@musaffa I'd start with this additional top-level method, actually 🙂

@musaffa
Copy link

musaffa commented Apr 28, 2021

Noted.

@solnic solnic removed this from the 1.7.0 milestone Feb 19, 2022
@ssoulless
Copy link

Any news on this? would this also be covering rules that has more than one key?

rule(:key1, :key2) do
    ...
 end

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

3 participants