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
Add wrap_with to Relation; simplify decorator / presenter / etc. code #7520
Conversation
|
cc @jonleighton |
|
I don't think this should be handled by Active Record. I'm |
|
Hey @al2o3cr, I particularly don't think it's AR's responsibility (or Relation) to handle wrapping to another objects. When one instantiate an Active Record object, ie with So, my 2 cents are that there's no real gain baking this into Rails, when we can be explicit about the wrapping whenever necessary, with your example: User.where(:name => 'Bob').wrap_with(UserWrapper).first.magic_thing
#vs
UserWrapper.new(User.where(:name => 'Bob').first).magic_thing
User.where(:name => 'Bob').wrap_with(UserWrapper)
# vs
User.where(:name => 'Bob').map { |u| UserWrapper.new(u) }Thanks! |
|
@carlosantoniodasilva It's only practical to perform the transformation you've described when the code using objects from the relation and the code setting up the relation are together - otherwise, you wind up with the wrapping code sprinkled everywhere. In my app, the code that built the relation needed to conditionally wrap the returned objects for callers that might either paginate the relation or call A more concrete example would be functionality like Draper's /cc @steveklabnik - would love to hear your thoughts, as (presumably) a strong proponent of decorators. |
|
Well, yes, I am, but I don't see what this feature gives us over That said, AR stuff to make my life maintaining Draper is nice, as you've noted, wrapping can be hard at times. |
|
I understand it may make some use cases easier to deal with, but I still don't think, as @steveklabnik commented, that's AR's job to handle wrapping itself. I'd rather stick with Anyway, lets wait for some more people to give feedback. Thanks @al2o3cr! |
|
I agree with @steveklabnik that this is unnecessary when it is just a |
|
This is just another example of Rails re-implementing Ruby with weird syntax. It’s depressing. Specifically, two problems:
|
|
I have a question, and I'm not sure this is the appropriate place to ask, but I'd really like to know the answer (or at least have a better understanding). Why do we wind up with things like this being suggested (and often added) to Rails? Do people not understand Ruby, OO, good design? What is the benefit of divorcing Rails from Ruby? Do people find Ruby a difficult programming language? Is the goal here to get more non-programmers writing Rails? (I'm genuinely curious, because I feel that I have to understand the cause problem before I can help stop it.) |
|
@srbaker that kind of question would be an appropriate post to the rails-core mailing list. |
|
It probably is. I'm having second thoughts about whether I care to hear the "answers" or not. |
|
Personally I don't think AR should be responsable to handle it. Specially when all you need to do is use some map/collect to handle it. |
|
Agree with @carlosantoniodasilva that ActiveRecord should return ActiveRecord instances and with @steveklabnik et al that collect() works fine as is for iterating and wrapping. |
|
I agree with the rest of the comments here that this is outside the responsibility of AR, and probably outside the responsibility of Rails in general. As a pattern, I feel that @evanphx's concept of having the decorator be in charge (instead of the finder) is cleaner and more appropriate. The fact that Evan's would work across ORM's is probably a signal of this. |
|
|
|
Seems like almost everyone agrees that this isn't a good idea. If someone on core feels differently, please re-open and merge. |
The attached code adds a
wrap_withmethod to Relation that wraps objects retrieved from the relation in the specified class. A trivial example:A short test is included - suggestions for additional testing (or more meaningful testing) are welcome.
There are also a number of additional features that could be included here, if they make sense:
wrap_withcall overwrites the value set in the first one. This would be a simple change, given the existing plumbing for dealing with multi-valued data on Relation.some_relation.wrap_with(SomeClass, :foo, :bar, :baz)would pass the additional arguments on to the constructor, so each record insome_relationwould be wrapped viaSomeClass.new(record, :foo, :bar, :baz). Again, a fairly trivial modification.Here,
wrap_withis just calling the block with the record directly.wrap_withsolely for read-only views. I'm not certain what the desirable behavior is here.