You can run it via rails r UserImport.new.perform. But it’s hard to test this code. You need to create different CSV files with valid and invalid data. It is also harder to scale this. Next step is to break up into reading the file and processing each row.

You can test private method process_row with .send and pass various params. But it’s still going to process the records one at a time which is slow. And what if you restart server? So let’s break up code into separate classes.

Now let’s wrap each service object into ActiveJob. You want to use something like Resque / Sidekiq / SQS so job queueing is very fast. This will allow you to quickly queue up the jobs and process them in background parallel to each other. Even if you completely shutdown both webserver and background job process the jobs will still be persisted.

We are back to just 2 files but the actual business logic is encapsulated in private methods which can be eaisly tested like any Ruby methods. Here is a great blog post.

Overall the amount of code increased from 7 lines total in first snippet to 21 but most of that code is simple class declarations and method definitions. In real applications your business logic will be much more complex and comprise much higher % of code. So a little bit of overhead that comes with breaking the code apart will matter much less. However the modularity and ease of understanding / testing your code will more thay pay off.