Decorate scoped associations #128

javierv opened this Issue Feb 10, 2012 · 7 comments


None yet

6 participants

javierv commented Feb 10, 2012

I've started experimenting with Draper, and looks great. Thanks!

I've just seen automatically decorate associations has been added, and it works great. For example, this works as expected:

unscoped_comments = PostDecorator.find(1).comments

However, it doesn't work if we use some scopes:

scoped_comments = PostDecorator.find(1).comments.order("created_at DESC")

The reason apparently is:

unscoped_comments.class   => Draper::DecoratedEnumerableProxy
scoped_comments.class     => ActiveRecord::Relation

My feature request would be the second case to automatically work, although I don't know if that's out of the scope of this project.



I'm not sure there's a great way to do this (but hopefully I'm wrong).

Compare PostDecorator.find(1).comments.size and PostDecorator.find(1).comments.order("created_at DESC"). In once instance, we want draper to give you the result of calling the method on the decorated class, and in the other we want draper to re-decorate the result.

Draper would need a mechanism (decorates_scope :order perhaps) for it be told that all calls to order should be redecorated. And then it need to have that called on it for all ActiveRecord::Relation methods, and any custom scopes.

An option for how you can deal with this without waiting for a change to draper (this is roughly what the hypothetical decorates_scope would do):

# In CommentDecorator
def order(*args)

I have the same problem: Decorator doesn't work 100% with associations.

 => UserDecorator

@posts = PostDecorator.decorate(Post.public.lastest)
> @post.first.user.class
 => UserDecorator

But @posts.first.summary don't work (for example)

class UserDecorator < ApplicationDecorator
  decorates :user
  def name

class PostDecorator < ApplicationDecorator
  decorates :post
  decorates_association :user

  def summary # ERROR! mode.user is not an UserDecorator :-(

@linuxonrails, if you do instead of, it should work. model is the underlying model, so it has no knowledge of any of the decorator related stuff.


Very thanks michaelfairley! It works!!!


Also, calling scopes on the decorator class directly returns undecorated results.

class User < ActiveRecord::Base
  scope :admins, where(:admin => true)

class UserDecorator < ApplicationDecorator
  decorates :users
  decorates_association :admins

UserDecorator.admins.first.class #=> User

I'm assuming that this is because decorates_association is decorating instance methods but not class methods.

@rboyd rboyd pushed a commit to rboyd/draper that referenced this issue Jun 15, 2012
Robert Boyd decorate scoped associations #128 eb27430
rboyd commented Jun 15, 2012

I have a small one-liner patch to lib/draper/base.rb that would allow decorates_association to take a :scope option. Pull request for consideration to follow.

Contrived example: decorate a Company that has-many associated Employees and we'd like to order them by birthdate:

class CompanyDecorator < Draper::Base
  decorates_association :employees, scope: :by_birthdate

in Employee:
scope :by_birthdate, order('birthdate')

This should be closed by #223, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment