2

I have a question concerning best practices in rails. In my rails project I have the following code:

class MyController < ApplicationController

  def some_method
    @product = MyFabricatorClass.new.create_product
  end

  ...
end

MyFabricatorClass is not dependent of some state and its behaviour is constant. I am also doing a lot of C++ stuff and to me it feels kind of unefficient to always instantiate a new MyFabricatorClass object. In a C++ project I would propably use something like:

class MyController < ApplicationController

  @@my_fabricator = nil

  def some_method
    @@my_fabricator ||= MyFabricatorClass.new
    @product = @@my_fabricator.create_product
  end

  ...
end

Is this style also legit in Rails? What would be the typical rails way to do it?

Thanks for any advice...!

schmitze333
  • 192
  • 1
  • 9
  • 1
    Why not make `create_product` a class method on `MyFabricatorClass`? – jvillian Sep 15 '17 at 23:53
  • @jvillian: Thanks for your comment. Sorry, I've chosen bad naming. MyFabricatorClass isn't realls my class but 3rd party. So, changing MyFabricatorClass is not an option. – schmitze333 Sep 16 '17 at 15:21

1 Answers1

5

It is a better practice to not use class variables (those that start with @@) in ruby; see here why

This might look like a weird code, but this is the more conventional way:

You set a "class" instance variable, instead of setting a "class variable".

class MyController < ApplicationController
  @my_fabricator = nil

  class << self
    def some_method
      @my_fabricator ||= MyFabricatorClass.new
      @product = @my_fabricator.create_product
    end
  end
end

About class << self, see here

The above code is just the same as:

class MyController < ApplicationController
  @my_fabricator = nil

  def self.some_method
    @my_fabricator ||= MyFabricatorClass.new
    @product = @my_fabricator.create_product
  end
end

Now you can just do:

MyController.some_method
Jay-Ar Polidario
  • 6,463
  • 14
  • 28
  • Thanks for clarifying and the additional resources. Accepted and upvoted. – schmitze333 Sep 16 '17 at 15:22
  • are there any differences if I declare `@my_fabricator` inside `class << self` block ? thanks – hqt Sep 12 '18 at 19:56
  • @hqt Yes, if you declare `@my_fabricator` outside `class << self`, those become instance variables for the object `MyController` (which is an instance of `Class`). If you declare them inside however, those become instance variables for the object `` (which is the singleton class object of `MyController`). Singleton class is like "where the methods are defined for that specific object". i.e.: `puts MyController.new.singleton_class` will show `#>` while `puts MyController.singleton_class` will show `#` – Jay-Ar Polidario Sep 12 '18 at 21:17
  • @hqt see [this SO for more info](https://stackoverflow.com/questions/34429693/singleton-method-vs-class-method) – Jay-Ar Polidario Sep 12 '18 at 21:18