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

Remove .decorates method and all class method proxying #311

Merged
merged 3 commits into from Oct 31, 2012
Merged

Remove .decorates method and all class method proxying #311

merged 3 commits into from Oct 31, 2012

Conversation

haines
Copy link
Contributor

@haines haines commented Oct 14, 2012

I thought I'd throw this out there and see what people thought.

@steveklabnik has mentioned a few times about removing .decorates, and letting one decorator decorate multiple models. I like the idea of decoupling the decorator from the model class as much as possible.

An important consequence of this is that it would no longer be possible to proxy class methods, in particular ProductDecorator.all, ProductDecorator.find and friends.

Personally I think this is a good thing, I've never been very comfortable with that syntax and have preferred ProductDecorator.decorate(Product.all) because, conceptually, the idea of "finding a ProductDecorator" doesn't sit well with me compared to "finding a Product and decorating it".

Thoughts?

@steveklabnik
Copy link
Member

Well.....

So there's a big schism here. One is 'pretend to be like AR as much as possible.' The other is 'follow good OO design.' ;)

What I'd like for 2.0 (yes, I know we're not at 1.0 yet ;) ) is to build a core of 'good oo' stuff and then add a layer of 'ar compatible stuff' on top. So that people can do both.

@haines
Copy link
Contributor Author

haines commented Oct 16, 2012

Hmmm yes fair enough. How about something like

class ProductDecorator < Draper::Decorator
  # inferred model
  add_finders

  # explicit model
  add_finders for: :widget
end

Then the AR stuff could be moved into a module that was extended on demand? Then it would be possible to write some decorators that could deal with multiple classes, and some that were tightly bound to one.

Edit In fact, going back to composition over inheritance, I could imagine add_finder creating a Finder object that the decorator could delegate to :)

@steveklabnik
Copy link
Member

Hmmmmm. I kinda like that, actually. Sounds pretty reasonable.

@haines
Copy link
Contributor Author

haines commented Oct 16, 2012

Awesome! I'll have a crack at this tomorrow (I'm on UK time).

@haines
Copy link
Contributor Author

haines commented Oct 17, 2012

See what you think, I ended up not creating a new object on the basis that the methods we are dynamically adding are already simple delegates to another object.

@steveklabnik
Copy link
Member

This looks great. I only want to have one more bikeshed: I'm not sure that add_finders is a great name. Rails' class macros are all declarative based, and even though it's literally adding the finders, it feels odd to me since it's not a declarative style name.

I'm not sure what it should be, though.

@stevenharman
Copy link
Contributor

Just spitballing here...

class ProductDecorator < Draper::Decorator
  can_find :product

  finds :product

  finds_model :product

  findable :product
end

Not sure I love any of them.

@collin
Copy link

collin commented Oct 18, 2012

Just gonna toss something at the wall cause I walked in here from twitter and 🍷

class MyFancyUserDecorator < UserDecorator
  scope User.fancy
end

@steveklabnik
Copy link
Member

Hmmmmmmmmmm

@lest
Copy link

lest commented Oct 18, 2012

👍 to removing .decorates, 👎 to coupling finders into draper

@haines
Copy link
Contributor Author

haines commented Oct 18, 2012

@steveklabnik No worries, I didn't like it much either but couldn't come up with anything better. And we're going to have to live with our bikesheds once this goes 1.0 - let's paint them properly :)

@stevenharman My favourite of those is finds :product, except I don't think that simply writing finds looks right when you want the model to be inferred. We could just make the model name required for the sake of nicer syntax, since decorates doesn't infer models either. finds_model is my pick of the rest, and looks ok without an explicit model.

Let me put another one up for consideration too: has_finders / has_finders for: :product

@lest At the moment they are right there in the Decorator, like 'em or not. This decouples them and results in a nice compromise - users can delete decorates and forget the finders ever existed, or replace decorates with [whatever we decide to call it] and keep on like nothing changed.

@steveklabnik
Copy link
Member

@lest yeah, @haines is correct, this code is already included everywhere by default, there's no extra coupling going on here.

@haines
Copy link
Contributor Author

haines commented Oct 31, 2012

Hey @steveklabnik, I went with has_finders, how does that look?

When I went to rebase, the specs were a bit of a nightmare, as there were a lot of methods on CollectionDecorator in the specs for Decorator. I've gone through and had a bit of a clean up. I moved some stuff round and reconciled some of the syntax - different authors have been using context and describe in different ways, eq vs ==, and so on.

steveklabnik added a commit that referenced this pull request Oct 31, 2012
Remove .decorates method and all class method proxying
@steveklabnik steveklabnik merged commit bc630f1 into drapergem:master Oct 31, 2012
@steveklabnik
Copy link
Member

Looks good, thanks. I'd rather have the feature than continue the bikeshed. :) And that name is 'good enough'!

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

Successfully merging this pull request may close these issues.

None yet

5 participants