Estoy creando un objeto tonto como este:

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

Pero hay otros objetos que también necesitaré para hacer esto. Entonces, pensé en anular el método de inicialización Foo para hacer algo como esto:

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

Y lo llaman así:

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

Pero Foo es un ApplicationRecord y parece que no se recomienda anular el método de inicialización de ApplicationRecord.

Entonces, ¿cómo podría hacer esto? ¿Alguna otra idea? ¿Funcionaría esto inicializar la cosa primordial?

9
Rafael Costa 15 dic. 2016 a las 16:35

2 respuestas

La mejor respuesta

Puede utilizar devoluciones de llamada de registros activos para eso. Sin embargo, no podrá especificar bar_name y de alguna manera necesitará encontrarlo dinámicamente desde los atributos de Foo.

Si esa opción te funciona. Agregue a su modelo algo como el siguiente código.

after_initialize :set_bar

# some other code

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

En caso de que realmente necesite especificar bar_name, sugeriría crear un método para ello.

Foo.new(params).with_bar

def with_bar(bar_name)
  self.bar = Bar.where(name: BarName).first_or_create
end
12
Nikita Misharin 15 dic. 2016 a las 14:06

Puede hacer uso de la devolución de llamada after_initialize y usar transitorios si es necesario:

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

La aplicación registra la inicialización propia debe encargarse de configurar barname siempre que esté en los parámetros

5
David 15 dic. 2016 a las 14:35