Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding ApplicationRecord initialize, bad idea?

I am creating a foo obeject like this:

@foo = Foo.new(foo_params)
@foo.bar = Bar.where(name: "baz").first_or_create

But there are other objects that I will need to do this as well. So, I thought of overriding the Foo initialize method to do something like this:

class Foo < ApplicationRecord
  def initialize(*args, BarName)
    @foo = super
    @foo.bar = Bar.where(name: BarName).first_or_create
  end
end

and call it like this:

@foo = Foo.new(foo_params, "baz")

But Foo is an ApplicationRecord and it seems that it's not recommended to override the ApplicationRecord initialize method.

So how could I do this? Any other ideas? Would this initialize overriding thing work?

like image 610
Rafael Costa Avatar asked Dec 15 '16 13:12

Rafael Costa


2 Answers

You can make use of the after_initialize callback and use transients if necessary:

class Foo < ApplicationRecord
  after_initialize :custom_initialization

  attr_accessor :barname

  def custom_initialization()
    self.bar = Bar.where(name: self.barname).first_or_create
  end
end

The application records own initialisation should take care of setting barname providing it is in the params

like image 59
David Avatar answered Nov 01 '22 11:11

David


You can use active record callbacks for that. However you won't be able to to specify bar_name and will somehow need to find it dynamically from Foo attributes.

If that option works you. Add to your model something like the the following code.

after_initialize :set_bar

# some other code

def set_bar
  name = # dynamicly_find_name
  self.bar = Bar.where(name: name).first_or_create
end

In case you really need to specify bar_name, I would suggest to create a method for it.

Foo.new(params).with_bar

def with_bar(bar_name)
  self.bar = Bar.where(name: BarName).first_or_create
end
like image 14
Nikita Misharin Avatar answered Nov 01 '22 11:11

Nikita Misharin