2011-07-16 13 views
42

Estoy utilizando raíles y quiero configurarlo para que attr_accessor :politics esté configurado, de manera predeterminada, como falso.attr_accessor valores predeterminados

¿Alguien sabe cómo hacer esto y es capaz de explicarlo en términos simples para mí?

Respuesta

101

Carriles ha attr_accessor_with_default por lo que podría escribir

class Like 
    attr_accessor_with_default :politics,false 
end 

i = Like.new 
i.politics #=> false 

y eso todos

ACTUALIZACIÓN

attr_accessor_with_default ya no se utiliza en Rails 3.2 .. usted podría hacer esto en su lugar con Ruby puro

class Like 
    attr_writer :politics 

    def politics 
    @politics || false 
    end 
end 

i = Like.new 
i.politics #=> false 
+13

Tenga en cuenta que el ejemplo solo funciona para un valor predeterminado de falso. Necesitaba un valor predeterminado de verdadero, así que usé: '@ politics.nil? ? true: @ politics' – micapam

+3

Si va a utilizar una matriz por defecto, use: 'def politics; @politics || = []; end' or << no funcionará hasta que asigne un valor a la política de otra manera. –

+0

Creo que el método 'after_initialize' sugerido por Dave Newton es la mejor solución – josal

-1

Esto no se hace en attr_accessor, sino en su migración.

Así que .. se podría realizar una migración

(1) rails g migration ChangePoliticsColumnToDefaultValueFalse

(2) añadir esto en def self.up

def self.up change_column :your_table, :politics, :boolean, :default => 0 end

La conclusión es que los atributos por defecto se establecen en migraciones.

Espero que esto ayude!

Editar:

Hay algunas preguntas similares también que han sido contestadas así:

Como here y here

+4

En realidad 'attr_accessor' ES el método correcto si no desea que su atributo se almacene en la base de datos. –

0

Si define su attr_accessor, por defecto el valor es nil. Se puede escribir en él, lo que hace !nil

-2

He estado usando esta forma en ActiveRecord:

class Song < ActiveRecord::Base 

    def initialize(*args) 
     super(*args) 
     return unless self.new_record? 
     self.play_count ||= 0 
    end 
end 
+2

No debe sobrescribir la inicialización en objetos ActiveRecord, use before_create en su lugar. – tesserakt

+0

¿por qué no? El inicializador se omite solo cuando se leen objetos de la base de datos. Para un valor predeterminado, no le gustaría sobrescribir la información del db de todos modos. – mcmoyer

+0

@ user1144360 Porque como [notas de la guía de RA de Rails] (http://guides.rubyonrails.org/active_record_validations_callbacks.html#after_initialize-and-after_find) hay un 'after_initialize' provisto específicamente para evitar la necesidad de anular' initialize'. OMI es más seguro hacerlo a largo plazo. El problema es que AR puede cambiar debajo de ti y cambiar el comportamiento. –

0
class Song < ActiveRecord::Base 
    def initialize(*args) 
    super(*args) 
     return unless self.new_record? 
     self.play_count ||= 0 
    end 
end 

En mi opinión, creo que esta respuesta es buena. Aunque estamos anulando el método de inicialización pero como se llama a super en la primera línea de este método, no cambió nada al método de inicialización de clase base, sino que esta es una característica clave de la programación orientada a objetos que podemos anular, y agregar algunos más funcionalidad en el momento de la inicialización de obects. Además, el inicializador no se omitirá al leer objetos de la base de datos, ya que se llama a super en la primera línea de la función.

+4

IMO 'after_initialize' es una mejor opción que anular un método reemplazado por el framework, y la [guía Rails AR alienta su uso] (http://guides.rubyonrails.org/active_record_validations_callbacks.html#after_initialize-and- after_find). El problema es que AR puede cambiar debajo de ti y cambiar el comportamiento. –

+0

Gracias Dave por su sugerencia, ¡creo que es la mejor! – josal

-3

attr_accessor in rails son solo variables virtuales que no se almacenan en la base de datos y solo se pueden usar hasta que el registro activo no se guarde o actualice en la aplicación. Puede definir attr_accessor en el modelo como

class Contact < ActiveRecord::Base 
attr_accessor :virtual_variable 
end 

y utilizar en forma tal que: -

<div class="field"> 
    <%= f.label :virtual %><br> 
    <%= f.text_field :virtual %> 
    </div> 

y podemos encontrar estos vartual valor de la variable en el parámetro controlador ...

0

Usted podría utilizar la gema virtus:

https://github.com/solnic/virtus

Desde el README:

Virtus le permite definir atributos en clases, módulos o instancias de la clase con información opcional acerca de los tipos, lector/escritor método visibilidad y el comportamiento de la coacción. Es compatible con una gran cantidad de coacciones y mapeo avanzado de objetos incrustados y colecciones.

Es compatible específicamente con default values.

Cuestiones relacionadas