Chapter 10. Down the Track

Throughout this book, we have followed Rory in the construction of his first Ruby on Rails application. The process of building a basic application has been described using this example. From this straightforward starting point, the application has been developed and expanded allowing us to describe the techniques used to overcome problems and create working solutions that can be used in a variety of situations.

So where does a developer of a small business applications go from here? A simple answer to this is that a developer can improve their Rails and Ruby skills further and become an expert in the language and the framework. However, there is an alternative approach, which is to widen your skills. That is, to develop skills in the areas and systems that work with Rails and your applications in your environment. Therefore, in this chapter, we will cover both: how one can improve one's Rails skills further and suggest alternative skills that complement Ruby on Rails, thereby broadening your skill set. Rather than using Rory's solution to discuss the issues, we will use our own experiences to describe some paths that have led us beyond the ability to build straightforward Rails applications.

Going off the Rails

Convention is the strength of Rails. It makes it easier to use, and the resulting code is easier to read as well as modify. It is the convention that goes a long way to make Ruby on Rails such a good and agile development environment.

Yet, at some point while creating applications, you will need to break the basic conventions. The danger in this is that you can end up with a disorganized mess. However, in my experience the process of going beyond conventions has taught me more than any other process about how Rails works. It has given me a deeper understanding of how the different parts work together. I believe that going through this process has been an essential part of my Rails skill development.

When I was younger, I used to kayak canoe and the development of my canoeing skills gave a useful analogy to my skill development in Rails. I spent a couple of years learning the basic kayak skills: paddling straight, changing direction, sculling sideways, escaping from an over-turned kayak, preventing over-turning, and eventually the Eskimo roll. This initial maneuver allows a canoeist to right a capsized kayak without leaving their seat. Even after I had learnt the skill and practised it many-a-times in safe environments, it was some time before I used it to right a genuine capsize. That is, to restore to upright a capsized kayak that I had not deliberately over-turned. Then the day came: I was caught in a wave and flipped upside down. Previously, I would have bailed out, but on this occasion I held fast, adjusted my paddles, and flipped the kayak upright.

From that point on, my canoeing skill leaped up to a new level. Because, I no longer had to worry about capsizing the kayak, I was able to be more adventurous. And if I over did it, a quick twist of the torso and flick of the paddles, and I was upright again. I went from being a canoeist that kept to the quiet stretches of water to the one who thoroughly enjoyed the rough water.

The analogy is useful as it allows me to make the following points:

  • The skill is not in being able to capsize a kayak (in fact, learners can be very good at capsizing), but rather the skill is in the ability to return back to the upright position. Similarly, any developer can break the standard Rails conventions: the skill is in being able to break the convention and then tidy up the result so that the rest of the application is not adversely affected.
  • The Eskimo roll is not the first skill you learn as a canoeist. You should not start your Rails development by breaking the conventions. You need to be skilled at Rails to understand the effect of breaking a convention, and therefore limit its impact.
  • Even after you master the Eskimo roll, the best position to be in a kayak is upright. Keeping to the Rails conventions makes the framework a joy to work with. Break conventions because you have to, not for any other reason.

The process of successfully breaking the Rails convention goes through the cycle described in figure 1.

Going off the Rails

This cycle has three elements:

  1. Identify the need to break convention: we find there is something we want the application to do, that we are unable to do within the standard Rails practice.
  2. Construct a solution to the problem: following some research and testing a solution is found that allows us to achieve the desired solution.
  3. Reconcile the solution with the rest of the application to minimize the impact: modifications are made to the application so the solution can be integrated. This is the hardest part of the process, but is the most important part for success to be achieved. It basically requires that our solution passes on to Rails resulting objects that behave as closely as possible to the standard Rails objects.

The key to success is in completing the whole cycle.

The point where I first went off the Rails was while working with an application that was relatively mature. It had been developed over a number of months and was already in daily use within the business. However, as its importance within the business grew, so did a requirement for it to be able to use data from an external source. In this case, it was a time-sheet application, the database for which was hosted on a Microsoft SQL server. My Rails application used a MySQL database. The structure of the time-sheet data was complex and it would be very complicated to create Rails models to match each table. Therefore, two basic conventions were being broken. The first, reasonably minor: data being spread across two databases. The second, more fundamental: the database data to model object relationship did not comply to what ActiveRecord expected.

My first attempt at a solution was difficult to maintain. It relied on a single model, a custom connection to the MS SQL database and multiple find_by_sql calls grabbing data via complex joins of views and tables in the time-sheet database. It worked, but each time I used objects that were created via the model, I had to customize the connection to other objects. The solution would not scale. The more I used it, the more modifications I needed to make. However, the process did teach me how to connect to a second database, and how I could use customized model methods to replicate the way a normal Rails model behaves.

I then discovered that MS SQL Server Integration Services (SSIS) can be used to pull the data I needed into a new database. Most of the joins could be managed within the SSIS data transfer. The resulting database would then have a simpler structure. I only needed to read information from the time-sheet system; no writing back to the time-sheet system was required. So, I did not have to maintain a link between the new database and the time-sheet system. Instead, a scheduled process passed new time-sheet data to the new database at midnight each night. With a simpler data structure, I was able to split the data across a small number of Rails models that more accurately matched the data structure. However, the structure was such that I still had to work differently with the model objects using the time-sheet data, than with the normal ActiveRecord objects. This build of the solution taught me how I could use the database tools to simplify the problem.

The third iteration of a solution came about when I realized that some fairly small modifications to the SSIS data transfer would allow me to structure the new database in a manner that was compliant with ActiveRecord. That is with table names being plurals of object names, each table having a primary key field called ID, and field names in lower case with underscores separating the words. Once I had done this, the deviation from Rails convention was reduced to a minimum—that minimum deviation being that some data was on a second database. The only problem then was to ensure that ActiveRecord did not try to access data across both databases with a single SQL call. To do this, custom methods were written that recreated the model connections normally generated by belongs_to and has_many relationships.

So, for example, in a projects model rather than using "has_many: tasks" to create a project.tasks relationship, a new project method called tasks would be created that returned an array of task objects. Similarly, a project method in the task model returned a project object that matched the project to which the task belonged. This, therefore, replicated the behavior that would have been achieved with "belongs_to: project" in a normal Rails application.

What I had done, in effect, was three Eskimo rolls; that is three rotations through the cycle of: identify the requirement to break convention; find a solution; reconcile the solution with the rest of the application. Each time I went through the cycle, the solution became simpler and the deviation away from the basic Rails practice became less.

A measure of the solution's success was that I was able to use the final solution to pull information from a third system: the company accounts. While going through the three cycles, I learned more about the interaction between model objects and their databases than I believe I could easily have if I had not had to fix my broken conventions.

In my experience, the most useful skills required to allow me to step outside the Rails conventions have been an understanding of the underlying Ruby language and SQL database tools. However, I have also used modifications to web servers to over come other Rails issues. To get the best from Rails, one must learn to get the best out of the supporting systems.

Note

Better to go off the Rails than grind to a halt

The key point here is that success does not come from the breaking, but from the fixing. If you come to a point where you cannot proceed without breaking the standard conventions, then break them, but always carry out the whole cycle by reconciling and minimizing the impact. It is always better to find a solution and improve it, than to grind to a halt because you cannot find a solution within the standard tool set. Often, the process of stepping outside of Rails will help you find a better way to solve your problem within Rails.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.178.9