Hey there learners,
I have a question regarding the structuring of complex views. I am working on an app and I feel like there are some anti-patterns creeping in, but I am unsure what to do about them.
The app has two kinds of users that interact in a marketplace - publishers and purchasers. The app is built entirely in a Restful style, and there are a number of resources and actions that both kinds of users interact with. This leads to the following kind of branching:
<% if current_user.publisher? %> # do something <% elsif current_user.purchaser? %> # do something else <% end %>
Two good examples are in the dashboard#show, and listing#show views. Both kinds of users interact with these resources however they obviously necessitate a completely different representation of the data. Following on from the above, in the dashboard for one kind of user I might have the following:
# iterate over one collection # iterate over a second collection # iterate over a third collection --> for this third collection, create a partial for each item & populate a modal that allows the user to take some action for the item. --> for each modal, create a form accepting nested attributes for a fourth resource related to this third resource.
So the result in my view code is the following:
- Many conditionals
- Deeply nested partials
Some of my views may have 20 partials.
Some of this branching is even starting to creep into my controllers. For example, in the Dashboard#show resource, I have code such as
<% if current_user.publisher? %> # populate these instance variables <% elsif current_user.purchaser? %> # populate these instance variables <% end %>
I realise I could hide this complexity in the controller by moving to a Presenter pattern, but it sort of seems to just pushing the problem around to another corner of the app.
So my question is - what are my options here? I’m obviously not the first person to have an app with lots of complex, conditional logic in my views, so I’m wondering if there are some recognised solutions. With respect to the examples above, my thinking is this:
The Dashboard for each user type is so fundamentally different that it could be split into its own resource. Eg PublisherDashboard, PurchaserDashboard. Two views, two controllers. There is no Dashboard model, the controller in this case is just pulling in collections of data from other models, so this seems like a reasonable approach.
However this is not the case in every situation. Eg listing#show is always going to be something where both kinds of users access the same kind of data, however the presentation of the data is wildly different. Conceptually I could split this two into two controllers, but then I’d end up with two views, two controllers, one backing model. This doesn’t seem like a good road to go down.
A client-side js framework seems to be where my app is heading, and I feel like it would help to have a clean interface between the presentation layer and the backing app. I’m learning ember.js for this reason.
But I’m guessing there must be an accepted Rails way of handling this kind of situation, or a design pattern I’m missing. If I continue down the path I’m on, my app will soon have 40-50 partials for one view, and this seems crazy. I’ll be getting into sub-folders of sub-folders haha.
I’m certain I can’t be the only person with this problem, so many apps have complex views with lots of conditional logic going on, so I’m really curious to know how they are put together.
Thanks so much in advance for any input, and if I can clarify anything please let me know!