Yutaka's blog

Excess use of singleton methods

I often come across singleton methods when I read Rails application codes.

# This is a bad example.
class Item < ApplicationRecord
  def self.insert_item(data)
    # Do something with `data`
    true
  rescue StandardError => e
    logger.error(e)
    false
  end
end

I wonder if we can write this process within a controller. As far as I see, there are few singleton methods to be used in multiple places; most of them are only used for a single controller. I asked my coworkers why such singleton methods exist. The answer is that processes related to models should be written models, so they write them within model classes as singleton methods.

I think it's a bad idea. Singleton methods should be at least associated with the class the methods belong to. It would be better to return an instance of the class. Or, singleton methods on ActiveRecord should return its relation for scope. If the process of a singleton method is not relevant to the class, it doesn't have to be in the class. The above code is this example; it returns true or false, and completely nothing related to the class exists. In this case, I always suggest writing the process within a controller.

If I admitted that such processes could be defined as singleton methods, there's still a glitch. Model methods can be used from various places, so they should be reusable and generic. Of course, it involves a lot of test cases to make sure it works for diverse use cases. But, is it really used in many places? If not, such processes should be within a controller. Developers don't have to consider edge cases for testing, and they can write test code just for a controller.