drapergem / draper

Decorators/View-Models for Rails Applications

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Draper::QueryMethods does not preserve context

synth opened this issue · comments

Given: Creation of a Decorator::Collection instance with a context and calling order on that collection to pass database sort ordering through to the ActiveRecord::Association
Expected: The resulting collection should preserve the original context
Actual: It does not preserve the context.

Example code:

class Posts < ActiveRecord::Base
end

class PostDecorator < Draper::Decorator
end

decorated_collection = PostDecorator.decorate_collection(Post.all, context: {user: "foo"})
decorated_collection.context == {user: "foo"} # true

decorated_collection = decorated_collection.order("created_at asc")
decorated_collection.context == {user: "foo"} # false, but should be true

I don't know if this is the proper long term fix for this, but this fix works in Draper::QueryMethods:

def method_missing(method, *args, &block)
return super unless strategy.allowed? method
object.send(method, *args, &block).decorate
end

to:

object.send(method, *args, &block).decorate(context: self.context)

I would imagine that the context should be passed along anytime decorate is called and there is context object available in the current scope

Discovered a workaround until this is fixed which is to use a similar approach to adding Pagination support. In the application specific collection decorator class, you can add the order method and simply tack on the context after calling super

class ApplicationDecorator < Draper::Decorator
  def self.collection_decorator_class
    PaginatingDecorator
  end
end

class PaginatingDecorator < Draper::CollectionDecorator
  # support for will_paginate
  delegate :current_page, :total_entries, :total_pages, :per_page, :offset

  def order(*args)
    collection = super
    collection.context = self.context
    collection
  end

  def paginate(*args)
    object.paginate(*args).decorate(context: self.context)
  end
end

Fixed by: #868