[ruby-on-rails] ¿Cómo creo un valor predeterminado para los atributos en el modelo de Rails activerecord?



Answers

Debido a que me encontré con este problema hace poco tiempo y las opciones para Rails 3.0 son un poco diferentes, daré otra respuesta a esta pregunta.

En Rails 3.0 quieres hacer algo como esto:

class MyModel < ActiveRecord::Base
  after_initialize :default_values

  private
    def default_values
      self.name ||= "default value"
    end
end
Question

Esta pregunta ya tiene una respuesta aquí:

Quiero crear un valor predeterminado para un atributo definiéndolo en ActiveRecord. De forma predeterminada, cada vez que se crea el registro, quiero tener un valor predeterminado para atributo :status . Traté de hacer esto:

class Task < ActiveRecord::Base
  def status=(status)
    status = 'P'
    write_attribute(:status, status)
  end
end

Pero al momento de la creación, aún recupero este error de la base de datos:

ActiveRecord::StatementInvalid: Mysql::Error: Column 'status' cannot be null

Por lo tanto, supongo que el valor no se aplicó al atributo.

¿Cuál sería la manera más elegante de hacer esto en Rails?

Muchas gracias.




Consideraría usar attr_defaults que se encuentran here . Tus sueños más salvajes se harán realidad.




Encontré una mejor manera de hacerlo ahora:

def status=(value) 
  self[:status] = 'P' 
end 

En Ruby, una llamada a método no tiene paréntesis, por lo tanto, debería nombrar la variable local en otra cosa, de lo contrario, Ruby lo reconocerá como una llamada a método.




Según lo veo, hay dos problemas que deben abordarse cuando se necesita un valor predeterminado.

  1. Necesita el valor presente cuando se inicializa un nuevo objeto. El uso de after_initialize no es adecuado porque, como se dijo, se invocará durante las llamadas a #find, lo que dará lugar a un golpe de rendimiento.
  2. Debe conservar el valor predeterminado cuando se guarde

Aquí está mi solución:

# the reader providers a default if nil
# but this wont work when saved
def status
  read_attribute(:status) || "P"
end

# so, define a before_validation callback
before_validation :set_defaults
protected
def set_defaults
  # if a non-default status has been assigned, it will remain
  # if no value has been assigned, the reader will return the default and assign it
  # this keeps the default logic DRY
  status = status
end

Me encantaría saber por qué la gente piensa en este enfoque.




Cuando necesito valores predeterminados, generalmente es para nuevos registros antes de que se muestre la vista de la nueva acción. El siguiente método establecerá los valores predeterminados para solo los nuevos registros para que estén disponibles cuando se procesen los formularios. before_save y before_create son demasiado tarde y no funcionarán si desea que los valores predeterminados aparezcan en los campos de entrada .

after_initialize do
  if self.new_record?
    # values will be available for new record forms.
    self.status = 'P'
    self.featured = true
  end
end



Related