Does this Rails 3 Controller method make me look fat?
This is a new application, and I have an index method on a Search controller. This also serves as the home page for the application, and I'm trying to decide if I am headed down the wrong path from a design pattern perspective.
The method is already 35 lines long. Here is what the method does:
3 lines of setting variables to determine what "level" of hierarchical data is being searched.
Another 10 lines to populate some view variables based on whether a subdomain was in the request or not.
A 10 line section to redirect to one of two pages based on:
1) If the user does not have access, and is signed in, and has not yet requested access开发者_如何学编程, tell them "click here to request access to this brand".
2) If the user does not have access, is signed in, and has already requested access, tell them "so and so is reviewing your request".
Another 10 lines to build the dynamic arel.
I can't get it straight in my head how to separate these concerns, or even if they should be separated. I appreciate any help you can offer!
Summarizing what you've said in something codelike (sorry, don't know ruby; consider it pseudocode):
void index() {
establishHierarchyLevel();
if (requestIncludedSubdomain())
fillSubdomainFields();
else
fillNonsubdomainFields();
if (user.isSignedIn() && !user.hasAccess()) {
if (user.hasRequestedAccess())
letUserIn();
else
adviseUserOfRequestUnderReview();
}
buildDynamicArelWhateverThatIs();
}
14 lines instead of 35 (of course, the bodies of the extracted methods will lengthen the overall code, but you can look at this and know what it's doing). Is it worth doing? That really depends on whether it's clearer to you or subsequent programmers. My guess is it's worth doing, that splitting out little code blocks into their own method will make the code easier to maintain.
That's a lot of variables being set. Maybe this is a good opportunity for a module of some kind? Perhaps your module can make a lot of these decisions for you, as well as acting as a wrapper for a lot of these variables. Sorry I don't have a more specific answer.
Without your code it's somewhat difficult to suggest actual fixes, but it definitely sounds like a really wrong approach and that you're making things much harder than they need to be:
3 lines of setting variables to determine what "level" of hierarchical data is being searched
if there is a search form, I would think you would want to pass those straight from the params hash into scopes or Model.where() calls. Setup scopes on your model as appropriate.
Another 10 lines to populate some view variables based on whether a subdomain was in the request or not.
This seems to me like it should be at most 1 line. or that in your view, you should use if statements to change what you'd like your output to be depending on your subdomain.
A 10 line section to redirect to one of two pages based on:
the only thing different in your explanation of the 2 views is "whether the user has requested access" surely this is just a boolean variable? You only need 1 view. Wrap the differences into 2 partials and then in your view and write one if statement to choose between them.
Another 10 lines to build the dynamic arel.
It might be necessary to go into Arel, but I highly highly doubt it. Your actual search call can in most cases (and should aim to be) 1 line, done through the standard ActiveRecord query interface. You want to setup strong scopes in your models that take care of joining to other models/narrowing conditions, etc. through the ActiveRecord Query interface.
精彩评论