Created
March 9, 2012 17:31
-
-
Save mudge/2007669 to your computer and use it in GitHub Desktop.
Are filters abused in Rails?
This file contains hidden or 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 MyController < ApplicationController | |
def show | |
@model = load_model | |
end | |
def edit | |
@model = load_model | |
end | |
private | |
def load_model | |
Model.find(params[:id]) | |
end | |
end |
This file contains hidden or 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 MyController < ApplicationController | |
before_filter :load_model, :only => [:show, :edit, :update, :destroy] | |
def show | |
end | |
def edit | |
end | |
private | |
def load_model | |
@model = Model.find(params[:id]) | |
end | |
end |
This file contains hidden or 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 MyController < ApplicationController | |
helper_method :model | |
def show | |
# Use +model+ freely | |
end | |
def edit | |
# Use +model+ freely | |
end | |
private | |
def model | |
@model ||= Model.find(params[:id]) | |
end | |
end |
This file contains hidden or 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 MyController < ApplicationController | |
def show | |
load_model | |
end | |
def edit | |
load_model | |
end | |
private | |
def load_model | |
@model = Model.find(params[:id]) | |
end | |
end |
The issue is how would you deal with global data. Like menu/cart etc if not using before filter
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In the common quest of a more better approach, the helper methods are a quite a interesting approach.
The helper methods though, as intended by Rails, break the encapsulation.
They also represent a problem for the single responsibility, because their presence is not always required by the controller instance, but dictated by the needs of the template.
As "cross object" instance variables which belong to 2 different objects at the same time, they are somehow pseudo-global entities instead of being injected.
When it comes to testing, they still need to be stubbed out as part of the context.
Also, if they assign instance variables, the latter will be again available in the view, representing a further temptation that only the developer's discipline can prevent :-)
Unfortunately all this is due to the very nature of how Rails works.
Furthermore, it's also related to the legacy of the original ERB implementation from the standard library. An ERB object only accepts a Binding object, and raises an error if the argument is of a different type. That probably encouraged this historical instance variable based approach in Rails.
Erubis (the default ERB engine as of Rails 3.0) does better in this respect, because you can also pass a Hash to the
result
.This allows to decide to rely on only one simple context object for the view, and this encourages to build that object as dumb as possible, probably a presenter on top of a database-backed model in the Rails common scenario.
This approach seems closer to the one we find in the Javascript templating systems. For me it has the advantage that I can easily stub it out not as pseudo-global context (difficult) but as a parameter to pass to the subject under test (easy).
It's also interesting that in we can get something similar in Rails making explicit use of the
:locals
optionrender :template => "my/template", :locals => {omg: "ZOMG!", message: "different kind of template"}