objects-on-rails/display-case — pull request #51 by pdobb (2014-09-04 16:59:34+00:00)
Title: Add DisplayCase::Exhibit#reexhibit method.

The need for this isn't easy to explain... and this pull request isn't necessarily what's needed (maybe there's an opportunity to automatically "reexhibiting" objects). But this pull request is at least one way to present the issue I've run into along with the quick/easy solution that's been working for me for the past 6 months each time I run into it: the *DisplayCase::Exhibit#reexhibit* method.

By code example:

```ruby
# Given:
class MyExhibit1 < DisplayCase::Exhibit
def self.applicable_to?(*); true end

def foo; "foo" end

def do_render_from_my_exhibit(context)
context.render "my_partial", my_local_var: self
end
end

class MyExhibit2 < DisplayCase::Exhibit
def self.applicable_to?(*); true end

def bar; "bar" end
end

# When executed from console, works as expected:
ex_obj = DisplayCase::Exhibit(my_obj)
ex_obj.foo # => "foo"
ex_obj.bar # => "bar"

# When executed through a render:
# 1) From within a view template
@ex_obj.do_render_from_my_exhibit(self)

# 2) From within "my_partial" view template
my_local_var.foo # => "foo"
my_local_var.bar # => Undefined method `#bar`!
# `my_local_var` seems to be "frozen" as a MyExhibit1

# HOWEVER

# If we send a "reexhibited" version of self as a local var:
class MyExhibit1 < DisplayCase::Exhibit
def do_render_from_my_exhibit(context)
context.render "my_partial", my_local_var: reexhibit
end
end

# Then:
# When executed through a render:
# 1) From within a view template
@ex_obj.do_render_from_my_exhibit(self)

# 2) From within "my_partial" view template
my_local_var.foo # => "foo"
my_local_var.bar # => "bar"
# This works! my_local_var is now able to act like a regular exhibit again.
```

I hope this makes sense. The essence of it is that after performing a [`render`](http://api.rubyonrails.org/classes/ActionView/Helpers/RenderingHelper.html#method-i-render) call, the objects being passed through on the locals hash no longer behave as exhibits should. That is, normally exhibited objects find the first exhibited object that can respond to a method. But after going through a render they only respond to methods on the exhibited object that was passed in, unless reexhibited first.

Also, I was trying to write tests for this example and was having trouble again. Trying to get an exhibited object to go through a `render` call seems like it would require adding a development dependency on Rails and I wasn't sure how to approach it even. And mocking didn't seem able to reproduce the issue.

It desired, I'll try to set up a simplest case working code example... let me know.

I also started a CHANGELONG.md file for the project, so if nothing else maybe you'd like to take that part away from this :).