-
Notifications
You must be signed in to change notification settings - Fork 89
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
Refactor of the coercion and validation logic #62
Conversation
TODO - Add in validation change from `c80485d05a0431dacdc91d36ac7e196aa04b8548`
Validator unit specs
Thank you @ifellinaholeonce, this work is impressive! And very much welcome 👏! I want to take the proper time to review this and decide what to do as I think it may deserve a major version shipping. May I ask what triggered you on doing this refactoring 😮? |
That's really exciting to hear @iMacTia. Looking forward to hearing your thoughts on it. Honestly, the refactor started by digging into what I thought was a bug at the time and then it continued on as an opportunity to learn and practice some skills. I had a great time doing it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ifellinaholeonce thanks again for the massive contribution 👏!
Overall I'm impressed with the refactoring you've been doing on the gem and I very much like the result!
After careful consideration, I'd be inclined to make this a v1.0 release.
That means we'd not be restricted in keeping the gem fully backwards-compatible, although we want to minimise disruptions in order to make life easier for those upgrading 😄
We'd also need to list all breaking changes into a new UPGRADING.md
document we can add to the root of the repo. I'd suggest to add it in this PR and fill it while implementing the braking changes.
If you also like that idea, I've left a few comments that I understand were not an option before this decision, and I hope you'll have the time and will to make these changes.
If that's not the case, then I completely understand that. You've already spent extensive time on this PR, so I'll be happy to take over for you if you prefer to focus your attention elsewhere.
lib/rails_param/param.rb
Outdated
|
||
# validate | ||
validate!(params[name], name, options) | ||
validate!(parameter) | ||
|
||
if block_given? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could forward the &block
to the parameter
initialiser and then rely on the ArrayParameter
and HashParameter
classes to take care of nested attributes
That's really exciting to hear! 😃 Thanks @iMacTia. I'm happy to carry on with this. I'll address your comments on this PR. Likely in the next day or two. |
* Use ParamEvaluator class for recursion
Hey @iMacTia Just following up here. It took me a little longer than expected, it was a bit of a tough nut to crack but I managed to address your thoughts on the This is the commit where that is introduced: 44d875c I haven't added a Looking forward to your thoughts on this approach and where we can go from here. |
Thank you so much @ifellinaholeonce! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great and the important comments were all addressed.
Assuming tests will be green, I feel like we can get this merged, and then it will be just a bit of polishing before we release v1.0 👍
|
||
def validate!(param) | ||
param.validate | ||
ParamEvaluator.new(params).param!(name, type, options, &block) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is simply beautiful ❤️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: this file can now be removed and this method can live in rails_param.rb
expect { get :index, prepare_params(page: ["a", "b", "c"]) }.to raise_error( | ||
RailsParam::Param::InvalidParameterError, %q('["a", "b", "c"]' is not a valid Integer)) | ||
expect { get :index, **prepare_params(page: ["a", "b", "c"]) }.to raise_error( | ||
RailsParam::InvalidParameterError, %q('["a", "b", "c"]' is not a valid Integer)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: This will be a backwards-incompatible change, as users of this gem will currently be rescuing the old namespace for this exception.
We could either mark this is as a breaking change in the UPGRADING.md
file, or being more accommodating and alias the exception with the old namespace 🤔
if block_given? | ||
if parameter.type == Array | ||
parameter.value.each_with_index do |element, i| | ||
if element.is_a?(Hash) || element.is_a?(ActionController::Parameters) | ||
recurse element, &block | ||
else | ||
parameter.value[i] = recurse({ i => element }, i, &block) # supply index as key unless value is hash | ||
end | ||
end | ||
else | ||
recurse parameter.value, &block | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still feel like this bit should be delegated to the Array and Hash validators, but this can be done on a follow-up PR 👍
Tests green, I'm merging this in 🎉 ! Actually I was wondering if you'd be considering becoming a maintainer of this gem? |
Hey @iMacTia I'm interested in learning a bit more about becoming a maintainer for the gem😄 Would you be open to a bit of back and forth about it? Happy to do email, or open an issue in this repo or anything really if you have a preference. |
Absolutely! We can start having a quick chat on the next steps and in the meantime I'll try reaching out to @nicolasblanco. |
haha yes I struggled with that same problem. You can find me on Gitter in the |
Description
Hey there 👋 !
First off, thanks a lot for this gem!
I've written a refactor of the code here in the hopes of making it a little easier to maintain. I know this is a lot of changes coming all at once. I'm wondering if this is something you'd be interested in? Happy to make changes and address any concerns you might have.
Thanks a lot for your time. Looking forward to hearing from you and getting these changes to a place that you'd be interested in merging them in.
Highlights
Parameter
class was introduced to represent the current param being processed. It takes inname
,value
,type
andoptions
. It knows how to check for defaults, transform and call a newValidator
on itself.Validator
class acts as a factory for creating subclasses with validation logic.Coercion
class also acts as a factory for coercing values based on the provided type. The logic for the different types of coercion live in subclasses, ie.Coercion::ArrayParam
.Todos
Additional Notes
Special thanks to @ClaytonPassmore for the help