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

Draper::QueryMethods does not preserve context #864

Closed
synth opened this issue Sep 28, 2019 · 3 comments
Closed

Draper::QueryMethods does not preserve context #864

synth opened this issue Sep 28, 2019 · 3 comments

Comments

@synth
Copy link

synth commented Sep 28, 2019

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)
@synth
Copy link
Author

synth commented Sep 28, 2019

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

@synth
Copy link
Author

synth commented Sep 28, 2019

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

@codebycliff
Copy link
Collaborator

Fixed by: #868

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

No branches or pull requests

2 participants