During development process, things are constantly changing (especially in early phases). Requirements change, UI changes, everything changes. Pages that clearly belonged to specific controller, mutated to something completely different in the future.For example. Lets say that we have website for managing Projects. One page of the website was dedicated to managing existing, and inviting new members of specific project. Naturally, I created members controller nested under projects which had proper responsibility. Later in the development, it turned out that it was the only page that was configuring the project in some way, so additional functionalities were added to it:editing project descriptionsetting project as a default...In other words, this page changed its primary responsibility from managing project members to managing project itself. Ideally, this page should be moved to edit action of projects controller. That would mean that all request and controller specs need to refactored too. Is it worth the effort? Should it be done?Personally, I am really starting to dislike the 1-1 relationship between views and controllers. Its common situation that we have 1 page (view) that handles 2 or more different resources. I think we should have views completely decoupled from controllers, but rails is giving us hard time to achieve this.I know that AJAX can be used to solve this issue, but I consider it an improvisation. Is there some other kind of architecture (other than MVC) that decouples views from controllers?
how to deal with controller mutations
ruby on rails
Applying composition over inheritance to controllers is one of those approaches with which you just can't go wrong.The idea is to have as thin of a controller as possible. The controller should just define the request/response processes, but anything substantial happening in between is going to be defined outside of the class.For instance, if you had a controller that filtered a collection of Product instances by a certain criteria, apply the VAT to the base price and then produce a tabular representation, CSV or JSON response, you'd end up with the following classes:A class that takes the request object and returns an appropriate collection of Product instances; this class is concerned with knowing how to construct an appropriate query based on the incoming request (like querying products based on a mix of attribute values).A class that takes a Product collection, processes each entry and returns the resulting collection; this class is concerned with taking a product's specified VAT and applying it on the base price.A class that takes the incoming request object and a Product collection and produces an appropriate response; this class is concerned with figuring out whether to produce an HTML, CSV or JSON response of the collection.Your actual controller that simply creates a network of communication between the three classes; this class finally specifies the notion of collecting, processing and displaying the Product model appropriately.The thing is that controllers often end up exhibiting a lot of complex behavior, but this way that behavior is factored into several different components that are defined and tested independently. By simply mixing in different classes and changing a few lines of code, your controller's behavior changes dramatically. I don't really have any experience with Ruby, but from what I know this can be achieved by including and mixing different modules and perhaps even a macro or two for seasoning.One good example of this approach are Django's generic controllers. They're just types composed of different mixins where each mixin defines certain behavior and exposes class attributes and instance methods that can be specified/overriden to configure their behavior. The generic controllers provided are just a particular combination of existing mixins that are suited for a particular problem.Another good example is Android with it's controllers. An Acitivty is called by the instrumentation framework whenever the activity needs to respond to a certain kind of request (create yourself, start yourself, destroy yourself) with certain input, but it's all happening on a UI thread that expects these methods to be snappy. Anything substantial, such as number crunching, retrieving data over HTTP, collecting data from the DB, so forth, is actually managed by objects of some external types that communicate some data back to the calling controller. Sometimes, this communication is generic enough that it can structured by implementing interfaces and the behavior pertaining to each is specified in an anonymous class. Again, you end up with a simple controller that only wires a network of communication between different objects to define some complex behavior, but the behavior is defined in a compact form from which you can readily figure out what's going on.This is the code reuse promised by the composition principle: if your controller's behavior needs to be migrated to a different controller or if a certain kind of behavior needs to be shared between multiple controllers, composition over inheritance provides you with the ability to do so. And what's best, by applying Liskov substitution principle, the possibilities become endless!