Refactoring essentially means improving your existing code without changing its functionality.
It’s all about code quality and optimisation – not product redesign. Users never see the changes. So why do it?
Because ultimately, refactoring can prevent your app from generating huge upkeep costs and save you money – making your business more successful.
- Ruby on Rails and refactoring – why do it?
- How to verify the quality of a development agency using Ruby on Rails
- First three things to do after receiving a new Rails project
Refactoring Ruby on Rails – why do it?
The basic aim behind refactoring is as follows: to fix problems in the code but keep its current functionality.
You modify and restructure what you or other developers on the team have written, but the product stays more or less the same. Refactoring is not about improving users’ interactions with the product – it's about the developers’ interactions with the codebase. Refactoring makes the code more readable to the current (and, importantly, future) developers working on it. It’s then easier – and cheaper – for them to continue developing and maintaining the product.
A ‘refactor’ means a single change in the code. To make or do a refactor means to introduce a particular fix which, in accordance with the above definition, enhances the code’s quality.
Here are some extra reasons to do it, if you weren’t convinced already.
If you think about it, making errors when coding is inevitable. Maybe there are geniuses out there who always write clean and flawless code, but if so, they are rare. You can’t expect super-human performance from your development team, and you have to accept that their mistakes will be part and parcel of the development process.
Just like refactoring, fixing those mistakes is a part of the process.
If you see a code fragment that could have been written better, improve it. Immediately. If you don’t do it often enough, your product will suffer as current risks lead to future problems.
Refactoring helps developers understand how the product works and what it’s supposed to do.
They are more engaged in the project, can easily delegate tasks to other developers (who should now have no trouble reading and working with more understandable code), and can take full advantage of others’ work thanks to, for instance, clearer methods. It’s best to put everything a developer needs to know into the code, so comments and remembering a lot of information become unnecessary.
Clean code means that developers can easily see which fragments hold the most business value.
Actually, clean code means developers can more easily spot separate elements in the code. You might think it should be obvious from the beginning which functionalities will matter most, but that’s a fallacy. It’s something you need to learn anew for every product you work on, because every product is different.
Projects get really expensive when you need to fix legacy code months or years down the line.
With regular refactoring, developers find bugs more easily, which means a smaller QA budget and fewer hours spent on scrutinising the code by developers themselves. There will be no need to constantly go back and fix something that has become a blocker. By preventing problems from occurring rather than reacting to them, you will be able to achieve faster development. And obviously, the development work is the most expensive part of building a digital product.
Martin Fowler is a proponent of refactoring, and he knows what he’s talking about, because he’s been doing this for years.
Fowler and other experts agree that building a product without any refactoring is a massive risk. Here, have some quotes:
All right, now that we’ve established that your project needs regular refactoring, how should you go about it?
Before you even start thinking about it, make sure the code under scrutiny has been tested. Extensively. Never refactor before you’ve written tests, that’s just asking for trouble. I mean it. Never. If you have no tests, write them. Then come back to the idea of refactoring.
Here’s a list of warning signs that almost always mean that particular fragment of code needs a refactor and some basic guidelines on what you can do with them:
At Netguru, we enjoy using RoR so we’ve picked up a few tricks over the years and we are always happy to share our knowledge.
Refactoring is a wonderful tool, as long as it’s done well.
In some situations and without the necessary experience, it may do more harm than good. If you aren’t sure that refactoring will bring business value to your product, don’t do it.
Stakeholders will naturally view refactoring as a waste of time. They will usually be wrong, but it’s important for the product owner to establish what’s most important for the project at any given time. Should we focus on time to market or future refactoring debt? The latter may seem like a problem that can be taken care of later, but many people who have thought so, have suffered by adopting this approach.
Finally, refactoring should always have a clear goal: improving the code behind one functionality. If it’s about a very general value, such as efficiency, you will simply never reach your goal. It’s too big a task for a single refactor, and it can be a waste of resources. Moreover, without a clearly defined goal, you won’t even be able to tell whether you’ve achieved it or not.
We’ve witnessed refactors doing wonders for projects, and we’ve witnessed refactors going really, really wrong.
One example of the former is a project that involved generating reports from questionnaires. It used a really old gem that had had no support for 6 years. It took care of the whole functionality, but seriously complicated the code, which means that adding features to the product was pretty much a heroic feat. And expensive. We talked to the client and did a refactor, which resulted in dumping the prehistoric gem and building a custom solution with the same functionality. The database shrank from 15 to only 2 tables, a critical component of the app started working more quickly, and the behaviour of the whole product became more predictable. The code was, of course, easier and cheaper to maintain and develop further.
A less cheerful example is a client who wanted a refactoring for its own sake. The whole process wasn’t well thought out, we had too little information and instead of completing the refactor in 3 months, as we estimated, we laboured over it for half a year. During that time, no new code was produced, which obviously set the project back quite a bit. Eventually, we managed to get the development work going at full speed and the project is doing quite well, but doing the refactor was a waste of time and resources.
These stories show you that, while refactoring is crucial and should be an integral part of your process, there must a time and place for it. Refactoring comes with a risk that can be mitigated by an experienced team. So, if you are thinking about refactoring your project, feel free to contact us about any questions or doubts you might have, and we will be happy to share our knowledge and experience with you.
How to verify the quality of a development agency using Ruby on Rails
A lot of businesses decide to start a collaboration with an external agency to help them optimize their Ruby on Rails application.
As using remote support is becoming more and more popular in different businesses, it is crucial for stakeholders to understand both the opportunities and the potential risks of such an approach, and to be able to verify the skill and experience level of a software development agency.
When hiring an external Ruby on Rails development team, you may not realise that you aren’t just getting people who will build your product.
You’re not only hiring people – you’re also tapping into the whole organisation behind them, their shared knowledge, and the processes developed collectively by the company.
That’s a lot of value for both your product and your company.
When working with an agency, pay attention to their processes – do this for two reasons.
Firstly, you want to make sure they know what they’re doing, and they are well-organised. Secondly, if you’re a startup, or you have just embarked on your business journey, you can learn a lot from a mature company and pick up their tools and processes instead of reinventing the wheel.
A professional external development team should be Agile. Don’t worry about applying the methodology to the letter, but you should see clearly defined practices that align with the Agile ideology.
Next is communication, which can make or break a good business relationship. Plenty of communication channels should be available to you so that you can reach your development team whenever you need to. Slack, Google Hangouts, email and a regular meeting schedule are the basics.
At Netguru, we strive to be completely transparent with clients – we share our style guide, our internal documentation, and code review practices, because we believe in sharing our knowledge and building trust.
Just because another company doesn’t do the same doesn’t mean they are doing something wrong – you simply have to ask about the processes and practices when choosing an agency and make sure you’re comfortable with how they do things.
Expect and require only the top tools from your development agency – this is a big part of why you’re hiring them in the first place – to avoid costs of providing an internal team with tools, equipment, office space, etc.
Their practices have taken the agency years to implement and master, and you get to skip the hard part and get to access them right away.
We’ve put together a list of some of the tools we use at Netguru – they are not the only existing options, but they certainly are some of the best ones.
Measuring the value of such tools in US dollars is actually an easy task. Here are some basic calculations, though they don’t include all of our tools.
Team account: Starting at $25 / month which includes your first 5 users.
At least 4 containers (x4 parallel).
1-10 users cloud hosting.
Bootstrap variant for small teams.
1 user ($16.67 USD per user).
4 users calculated, though there might be more ($8 per user).
Heroku 2x - 1 dyno.
Total monthly cost:
This might not seem like a lot, but keep in mind that most projects are developed over at least several months, and that this is only part of the hidden value offered by every development team.
If you hire your own developers, you will have to cover similar costs for a somewhat lower value, because you’ll have to develop the processes and practices that an external team would bring to your project.
It’s common knowledge that working with an external software development agency is the cheaper option.
You don’t have to provide office space, equipment, and testing equipment – basically none of the material stuff necessary for building an app. You can also forget about recruitment costs. You don’t need to worry about software and a test infrastructure. You can skip trying to gather the exact set of skills necessary for your project – a good agency will offer Devops, backend and frontend development, UI and UX design, as well as product and graphic design.
All in all, it often makes sense not to invest in your own team before you even have proof of concept for your product.
First Three Things to Do after Receiving a New Rails Project
Going it alone?
If your developer team have received a new Ruby on Rails project here are some tips from our Senior RoR developer Jakub Naliwajek:
First of all, grab pen and paper. I’m not kidding.
At the end of the day, you may toss these notes in the trash but for now your notebook is your most valuable tool. Ready?
Go through all the points below – if you encounter something that doesn't meet the 'Rails way' then write it down.
It sounds obvious, but bear with me – more obviousness coming your way in a second.
Every software project should have a well-documented README file with a detailed description of the codebase and the application's business model. If your new project lacks one, then – guess what – write it down. TO-DO: create a good README from these notes.
If your README is good, then don’t get caught in the trap of reading it all right now. Read the introduction. Maybe skim through the general sections about architecture, patterns and third-party services. Skip detailed and long paragraphs. You will return here later.
Again, this is obvious – told you. There is no need to open your editor yet. Just go to your project directory and execute:
This should give you a long list of all the folders, subfolders and files in the project. Here are some questions you can ask yourself:
Maybe there is a folder called app/policies that you don't recognise? Something that is done in a non-standard Rails way? Are there more directories in the root of the project itself? Maybe a folder with assets actually keeps a dozen front-end applications?
Remember to note anything suspicious, weird, non-standard, longer or shorter than usual, and so on. Write it all down.
If your assets/images directory has a lot of cat pictures, it's a good indicator of possible issues. The same goes for many other directories. Even a shallow in-depth /lib directory with a large number of files may indicate possible problems for you if you ever need to modify those files. It would be a great place to mark for future refactoring.
This is what I like the most. Dive right into your Gemfile and see what gems and technologies your new application uses. Even if the README from the first step is missing, you should find a lot of answers here.
Go through them one by one. Presumably, each gem will have its own repository which you can visit. Skim each README you find. You don't have to learn everything now, but it's important you know about the possibilities.
If your Devise version is locked at 4.0.1, you should check why. Browse the git history and read the commits' messages. If you are lucky, maybe previous developers have left a clue there. Otherwise, search through the issue tracker and the gem's repository to find out why the specific version is so important.
A note about patch versions: according to semantic versioning, patch versions can be updated without the need to worry about backward-compatibility. So, if you find your gem in version 1.0.1 and the newest version is 1.0.3, it's fair to assume you can update it right away.
Grouping gems into groups such as production, development, test, and doc is a standard Rails practice. Any other group is a worthy anomaly to notice, though. No developer would create one if there was no purpose for its existence. If you find an extra group, grep your source files for occurrences and see what's the deal.
Before we jump into reading models’ source code, it's a good idea to browse the contents of db/schema.rb. Familiarise with the existing table names and attributes. Other important things to look for, depending on your database engine, may include:
Ah, the models. Often fat and responsible for everything, at least when you're just starting a refactor job. A place with a lot of answers, e.g.:
You can, of course, see that in db/schema.rb, but looking at all those belongs_to and has_many keywords seems faster – at least to me. But there is an even better way to learn all the relations.
Just use gems such as Rails ERD which can graph all your relations and present them in a single PDF file.
If you need help implementing any of the advice in this article learn more about our veteran Ruby on Rails team today.
This article was originally published on October 3rd, 2017 and was updated with new information added.