Alexander, In your last example, I think `require` would actually work fine as-is, i.e., params.require(:one).require(:one) would check the presence of the root and the specified child node.
That said, I think you have a good point that `require` may be a little too strongly opinionated and lacks consistency with `permit`. I don't think making a breaking change to `require` is the answer though, not at this point at least. I know the core team must constantly fight against API bloat, but I'm wondering if simply adding another method is the best compromise here. I threw together a params.ensure method<https://github.com/Alric/strong_parameters/commit/401d61a2802fd028e20ba74fd093048686b2b37d>- not a perfect name, I know - that I think provides the flexibility you want, specifically chaining and allowing multiple/nested keys in single call, similar to though not as robust as `permit`. (If you look at my sample, focus on API, not specifics of implementation.) I personally have no problem with `require` as I tend to follow the root element pattern, but I definitely get how it could be cumbersome to work with if you don't. -Al On Thu, May 1, 2014 at 8:11 PM, Alexander Trauzzi <[email protected]>wrote: > That's a really good question, but I don't know if presenting a new > problem necessarily invalidates the original issue which is that by > returning the "required" value, the API is basically saying strong params > has no way of enforcing more than one required value. What if one of the > values contained within the returned structure was itself also required? > > one: (index, required) > one: (scalar, required) > two: (scalar, not required) > > > I think that rather than trying to accommodate all these legitimate - but > complex - edge cases, it'd be smarter to just remove the complexity and > push nested validation to somewhere else. I'd be willing to bet there are > quite a few people out there misusing the API as it is currently such that > at the very least, the name `require` isn't really helping. And again, I'm > not even using nested structures. If the idea is to move away from > validations coupled with the model (something I agree with), params is > going to have to pick up a lot more slack. > > > > On Thursday, 1 May 2014 16:36:25 UTC-5, Matt jones wrote: > >> >> On Apr 30, 2014, at 10:00 PM, Alexander Trauzzi <[email protected]> >> wrote: >> >> I've just been getting re-acquainted with Rails 4 after spending the past >> year working in some other frameworks. >> >> One thing I noticed are strong parameters which I see as a really great >> addition! One flaw I've noticed however is in the behaviour of >> `params.require` which I don't think is 100% user friendly yet. The two >> major issues I can see are: >> >> - It returns a value, when really what it should be doing is returning >> params to continue with a fluent API >> - It doesn't accept multiple values (an array) >> >> It's been observed in the strong params github issue tracker by several >> others that this violates the principle of least astonishment by coupling >> unrelated functionality (returning nested keys) with the enforcement of >> parameter presence. It also could be argued that people might expect to be >> able to use it as follows: >> >> my_params = params.require(:one, :two, :three).permit(:one, :two, >> :three, :four) >> >> >> What would this specify the expected format *as*? Doing the more usual: >> >> params.require(:one).permit(:one, :two, :three, :four) >> >> is saying that you expect params like: >> >> one: >> one: (scalar) >> two: (scalar) >> three: (scalar) >> four: (scalar) >> >> In the case where `require` takes multiple keys, is it expecting the sub >> keys in *each* of those? Any of them? >> >> >> This basically sets up a simple request-specific schema for parameter >> presence as it begins to travel further into the application's layers. I >> think the feature of params.require being able to verify the presence of a >> key and then returning it's contents for nested attributes needlessly couples >> two pieces of functionality. I typically store all attributes for a >> request at the root of my `params` and so I never have any nested object >> data to dereference. It's all at the top, and this results in me having to >> make multiple separate calls to `params.require` just to verify each one. >> Which as I'm sure you can guess gets very ugly, very quickly: >> >> params.require :one >> params.require :two >> params.require :three >> my_params = params.permit :one, :two, :three, :four >> >> >> Does this actually work? I swear I've gotten into trouble with calling >> `permit` on the top-level params hash, since there's other stuff >> (:controller, :action, :format, etc) in there... >> >> --Matt Jones >> >> -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Core" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To post to this group, send email to [email protected]. > Visit this group at http://groups.google.com/group/rubyonrails-core. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/rubyonrails-core. For more options, visit https://groups.google.com/d/optout.
