Created
March 22, 2012 17:41
-
-
Save jcasimir/2160696 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ApplicationController < ActionController::Base | |
extend AttributeViewable | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module AttributeViewer | |
def attr_viewable(*names) | |
names.each do |name| | |
attr_accessor name | |
helper_method name | |
private "#{name}=".to_sym | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<table> | |
<% messages.each do |message| %> | |
<tr> | |
<td><%= message.subject %></td> | |
<td><%= message.body %></td> | |
<td><%= link_to 'Show', message %></td> | |
<td><%= link_to 'Edit', edit_message_path(message) %></td> | |
<td><%= link_to 'Destroy', message, confirm: 'Are you sure?', method: :delete %></td> | |
</tr> | |
<% end %> | |
</table> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MessagesController < ApplicationController | |
attr_viewable :message, :messages | |
def index | |
self.messages = Message.all | |
end | |
end |
Ah, I see now.
How hard would it be to mixin the context methods so messages
will work without the context.
? I cannot currently think of an easy way to achieve that.
@myobie you could mix in a module on each request. So something like:
class MessagesController < ApplicationController
def index
extend Module.new {
attr_accessor :messages
}
self.messages = IndexContainer.new(Message.all)
end
end
But I strongly advise against doing that. It breaks method caches which will slow method lookup on every request, and couples your code with the fact that the controller is a new instance on every request.
Usage of a context (or container, or presenter, or whatever you want to call it) object allows you to:
- test behavior of the container outside of your controller (you don't need to write a functional test to test the Container)
- decouple the view from the controller (you could test the view without instantiating a controller)
- get NoMethodErrors raised exactly at the point where the error occurred (rather than waiting for the
nil
to be used)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@scottburton11 I would add a
messages
method to the context object. So in your view, you'd sayctx.messages.each { ... }
. The context object would be constructed in each action, like this:Then if you accidentally call
context.message
in the view of your index, you'll get an exception. Or if you callcontext.messages
from your show view, you get an exception.