Blog logoMatthew Lang

Ruby on Rails

A 4 post collection


Is Ruby on Rails Still Relevant?

 •  Filed under Dev Life, Ruby on Rails

It’s a question that I’m seeing on an increasing basis as I venture through the Internet. I’ve seen it appear on a few forum sites and it has appeared in a couple of newsletters that I subscribe to.

Before we answer the question, let’s take a brief look at the history of Rails. 10 years ago the first version of Ruby on Rails dropped. It caused a stir due to the ease with which web applications could be made. In that time it’s moved on through four major versions, had hundreds of releases and has been the collective work of hundreds of software developers who have devoted their free time to making Ruby on Rails what it is today.

Since then there’s been a search for the next killer web framework that will replace Ruby on Rails. 10 years on I’d say we’re still waiting. No other web framework has had the impact that Ruby on Rails has.

So is Ruby on Rails still relevant?

Definitely yes. While a lot of developers have adopted and then moved onto other languages and frameworks, there is still a large amount of developers that specialise in Ruby on Rails. The market for Ruby on Rails developers for full-time and contract work is still healthy. There’s also still a large amount of companies and organisations that need Ruby on Rails developers to maintain web applications and there’s still a demand for these developers with Greenfield projects as well.

It’s not as highly a sought after as it was maybe five years ago, but it’s still a relevant technology as well as a mature technology. It’s been tried and tested by many developers and it’s benefits for building web applications is well known now. Given that companies would rather not risk building an application in a new and unfamiliar technology, Ruby on Rails is now seen as a mature web framework that has grown up over the years.

Ruby on Rails will be relevant for at least the next five years and possibly the next ten years. From there, who knows. As long as it is a low-risk technology for clients, I’ll keep recommending Rails for projects that it is a good fit for.

Time to Explore

 •  Filed under Dev Life, Ruby on Rails, Django, Python, Learning, By Me

I've been working with Ruby on Rails full-time now for close to 4 years. Two years as a full-time employee and two years as a freelancer. In that time I've worked with and built all manner of Rails applications. Content management systems, business support applications, healthcare service portals and my own little product, DailyMuse. It's still my choice of web framework for new projects, but I feel that lately I've become too settled with Rails. Yes it's a fine framework to work with and who could argue. It has a thriving community that offers great support and ensures the ongoing development of the framework, but there's more than one web framework out there.

In the last few months I've been trying out the Rust systems programming language. It's been a hit and a miss getting my head round the syntax but largely I feel that I am wasting my time with it. Why? Well Rust is still fairly new and at the time of writing this it's just about to emerge from its 1.0 beta phase. Despite the immeninent release of the stable version of the language, I still think I arrived at the Rust party too early. I've never been an early adopter of technology. I like to sit on the fence longer than normal before making any decisions about investing in a language or a framework. I might re-visit Rust in six months time or even a year to see how popular it is and whether it's worth investing my time in. So, putting Rust to the side has left a space for me to look at another language or framework.

Looking at the market today, there's such a variety in the demand for different languages and frameworks. I've done .NET in the past and while I think there's going to be a steady demand for it in the future, I do want to try something completely new. A language I've never used before. Enter Python.

Okay, it's not completely different to Ruby. It has duck typing and It's dynamic but it is also an established programming language. If I was going to learn a new language then it was going to be something that I could use in my career. Getting a Python contract with no experience might be tricky, but I'm prepared to tart up my Github page with a couple of projects done in Python that could add weight to my cause.

Also, if I'm going to pick a language that gives me extra tools to use then I want something that sits alongside it just like Ruby on Rails sits alongside Ruby. I not only want to learn a new programming language but a new web framework that is made with that programming language. Enter Django.

In the past I've tried to learn different programming languages and failed spectacularly but this feels different. Rather than picking an new cutting edge technology, I've picked an established programming language and an established web framework to go with it. They're not completely different from Ruby and Rails, but that's the idea. I'm a web developer, therefore it makes sense to learn another web framework. This might be a low risk investment, but that's okay. There's enough developers chasing the bleeding edge technology. How many are chasing established technology?

What is The Rails Way?

 •  Filed under Ruby on Rails, Dev Life, By Me

It's a question I've been asking myself as I switch between different Rails applications for different clients. In my early days of working with Rails, I had a preferred selection of gems that I liked to use and that I stuck with for many Rails applications. After a few upgrade issues on a couple of applications I started to pay more attention to how I build applications with Rails. I questioned the gems that I was using and my testing practices. As I've gained more experience I've started to see that working closely to the Rails framework when building applications has some benefits that I previously overlooked.

What you're about to read isn't a silver bullet approach to building Rails applications. This is simply a guide to what I've find works for me.

Application Architecture

In the past most applications I worked on followed the old favourite of "fat model, skinny controller". Most applications tightly followed the MVC pattern and very few classes or objects were located outside of these three folders of the application. It does work, otherwise Rails wouldn't be as popular as it is, but following the MVC pattern did present one problem. Models became huge wells of code as they tried to contain the bulk of the application's code. Now I try to follow some best practices when coding but I don't strictly adhere to them, but you have to admit that a model with a 1000+ lines of code could probably be trimmed down a bit.

Since reading and watching a number of different ways in organising your Rails application, I've started to see the argument for extracting business logic into individual classes. You might be thinking of service objects or Hexagonal Rails when I say this. It's the same idea. I've started to keep classes that contain business logic in the app folder, alongside the rest of the application's objects. The reason for this is that I see the business logic as being part of the application, not a seperate layer or component of the application. I'm using Rails for my application, so I want to keep the business logic close to the rest of the application.

Gem Dependencies

Gems sure are handy. Just add to the Gemfile, install and your application has access to new functionality when it needs it. While adding gems is the easy way to add functionality to your application, you then have a dependency on that gem to stay maintained.

Before you even begin adding the gem to your Gemfile, ask yourself if it is truly necessary for your application?

In the past I would happily add a gem that I thought I needed, but now I take a different stance on it. If a gem provides just a small bit of functionality to the application, I take the time to spike a similar or better solution for the application on my own. The reason for this is that sometimes a gem won't do everything you need it too. If it can provide everything you need then great, but if it only provide most of your needs, could you add the complete functionality that you need by yourself?

Building this functionality on your own isn't always the best way to go, but if your application has specific requirements, then I say it's definitely worth looking at. Rolling your own solution to your application's requirements means that your solution could be a better fit for your application than anything else that's out there. It also means that with your own solution, you are responsible for keeping it maintained. Lastly, it keeps your Gemfile lean and the dependencies for your Rails application lean. I don't suggest you do this for everything, just the gems that you might question over their suitability for your application.

Testing

In the past I was a keen advocate of Cucumber and RSpec. That has changed over the last year. I'm finding that the testing tools that Rails provides are more than adequate for new Rails projects and sometimes better suited for smaller Rails projects.

Out of the box Rails provides Minitest through Ruby to write your tests and fixtures to organise the data you want to test against. Minitest is flexible in that you can write tests or specs depending on your preference, so I don't have any issues there. Minitest in a new Rails application is straightforward and it doesn't require any changes to your application's setup to get it working. Why even bother changing?

The real benefit I've seen though is in doing testing the Rails way is by using fixtures. They do require some initial effort to put together, but they're always there for subsequent tests runs and soon you'll start re-using fixtures for different tests and rarely have to touch them.

Rails is a database backed web application framework. Now I've seen the arguments for isolating the database from your tests, but for a framework that persists its data to the database, I think it's overkill to start stubbing out calls to the database and canning data using factories. This is why I like using fixtures. It's real data you're working with. A complete working set of test data.

Finally, an argument against using fixtures in the past was that tests took too long to run. I have to say that this is not a concern now. I have worked on a number of Rails projects using Minitest and fixtures and while their test and assertion counts run into the hundreds, I've yet to see a test suite take longer than 30 seconds. And even if your test suite is on the large side, it shouldn't be a major concern as you should have your tests automated to run as you edit your code by using something like Guard or Spork.

So What is The Rails Way?

Since I've made a few changes in how I build Rails applications, I'm definitely a more productive developer and I'm able to build new features with minimal fuss. The Rails way for me is working with the tools that Rails provides and building an application as close to the application's own models, controllers and views as you can. Simple patterns and designs are available to reduce complexity but aren't always necessary. I don't suggest you immediately think about re-writing your whole application to fit around these three suggestions, but bear them in mind for any future Rails projects that you have.

Custom Assertions with Minitest

 •  Filed under By Me, Ruby on Rails, Minitest

In the last few weeks I've been working on a Rails 3 application for a client. The test suite doesn't cover the whole application, so along with features being added for the client, I've been gradually expanding the test suite to cover the entire application.

The test suite itself uses Minitest and the test syntax. So far I've had an enjoyable experience in adding tests for each part of the application. This week though I faced an issue of duplication in my tests. The application includes a number of mailers. Each mailer has an erb and plain text template. In my first pass at testing this mailer I had some duplication going on with the different templates for each mailer.

assert_match(/Hi there #{person.first_name}/, mail.text_part.to_s)
assert_match(/Hi there #{person.first_name}/, mail.html_part.to_s)

This is just one of many lines in the tests that assert that the two mailer types include the right content. Wouldn't it be nice to wrap these two assertions into one?

Minitest allows you to define your own assertions but up until this time I made do with Minitest and Rails' own assertions. Turns out that adding your own assertions to Minitest is easily done. I included the following assertion in my test_helper file but you can include your own assertions in a seperate file if you want to and then include that in your test_helper file using require.

module Minitest::Assertions
  def assert_mail_match(expected, actual)
    ["text","html"].each do |mail_part|
      assert_match(expected, actual.send("#{mail_part}_part").to_s)
    end
  end
end

What we're doing is adding a wrapper around Mintest's assert_match method and pass in our expected value and the actual value. The method will iterate over the two mail parts in the mailer and assert that each format has the correct corresponding content.

We can now call the new assertion in our tests:

assert_mail_match(/Hi there #{person.first_name}/, mail)

Wrapping these two assertions into one makes sense. The template formats for the mailers is unlikely to change and the two different formats have the same content albeit with different formatting.

After a couple of years of using RSpec, Minitest has been a nice change to how I test the Rails applications I'm working on. Its syntax and single way of doing things means that I find it easier to write tests. Hopefully, I'll be able to share more insights into using Minitest in the future.