7

Eventuali duplicati:
attr_accessor default valuesCome inizializzare i valori degli attributi 'attr_accessor'?

Sto usando Ruby on Rails 3.0.9 e vorrei inizializzare alcuni valori degli attributi attr_accessor nella mia classe \ modello che eredita da ActiveRecord::Base. Cioè,

... nel mio modulo ho:

class User < ActiveRecord::Base 
    attr_accessor :attribute_name1, 
       :attribute_name2, 
       :attribute_name3, 
       ... 
end 

e vorrei impostare true tutte attributo attr_accessor valori. Come posso farlo?

P.S .: Ovviamente vorrei risolvere il problema di cui sopra che si avvicina "à la Ruby on Rails Way". So del after_initialize richiamata ma utilizzando il metodo che dovrei ripetere ogni attribute_name<N> dichiarazione per la quale vorrei impostare il valore true all'interno che after_initialize dichiarazione (... e questo è non secco - Non Repeat Yourself) . Forse c'è un modo migliore per raggiungere questo obiettivo. C'è un modo per impostare i valori degli attributi attr_accessor "al volo" quando si specificano questi attributi? Cioè, mi aspetto di dichiarare e impostare gli attributi attr_accessor in una sola volta!

+0

c'è una vera e propria logica dietro i nomi (1,2 ...)? – apneadiving

+0

@apneadiving - Sì, certo. – Backo

risposta

6

Per Rails 3.2 o versioni precedenti, è possibile utilizzare attr_accessor_with_default:

class User < ActiveRecord::Base 
    attr_accessor_with_default :attribute_name1, true 
    attr_accessor_with_default :attribute_name2, true 
    attr_accessor_with_default :attribute_name3, true 
    ... 
end 

Dal momento che il valore predefinito è un tipo immutabile (booleano), questa forma del metodo è sicura da usare qui. Ma non usarlo se il valore predefinito è un oggetto mutabile, incluso un array o una stringa, perché tutti i nuovi oggetti del modello condivideranno la stessa identica istanza, che probabilmente non è ciò che desideri.

Invece, attr_accessor_with_default accetterà un blocco, in cui è possibile restituire una nuova istanza ogni volta:

attr_accessor_with_default(:attribute_name) { FizzBuzz.new } 
+5

Nota ai lettori attuali che 'attr_accessor_with_default' è deprecato a partire da Rails 3.2 –

11

Hai provato:

class User < ActiveRecord::Base 
    attr_accessor :attribute_name1, 
       :attribute_name2, 
       :attribute_name3, 
       ... 

    after_initialize :set_attr 

    def set_attr 
    @attribute_name1 = true 
    ... 
    end 
end 
+0

Ho aggiornato la domanda (leggi "P.S .:" alla fine). – Backo

+0

@Backo, qui c'è tutto abbastanza ASCIUTO n la risposta – fl00r

+0

@apneadiving - C'è un modo per impostare "att_accessor" i valori degli attributi "al volo" quando li si specifica? – Backo

3

vorrei solo definire un getter che carica pigramente il valore che ti interessa e utilizzare attr_writer per definire il setter. Per esempio,

class Cat 
    attr_writer :amount_of_feet 
    def amount_of_feet; @amount_of_feet ||= 4; end # usually true 
end 

Il che, se davvero sul serio, può essere riscritta con un po 'di meta-programmazione:

class Cat 
    # The below method could be defined in Module directly 
    def self.defaulted_attributes(attributes) 
    attributes.each do |attr, default| 
     attr_writer attr 

     define_method(attr) do 
     instance_variable_get("@#{attr}") || 
      instance_variable_set("@#{attr}", default) 
     end 
    end 
    end 

    defaulted_attributes :amount_of_feet => 4 
end 

calin = Cat.new 
print "calin had #{calin.amount_of_feet} feet... " 
calin.amount_of_feet -= 1 
puts "but I cut one of them, he now has #{calin.amount_of_feet}" 

Questo funziona perché, di solito, il calcolo del valore di default non avrà alcun lato l'effetto rende l'ordine importante e non sarà necessario per calcolare il valore finché non provi ad accedervi per la prima volta.

(Câlin è il mio gatto, che sta facendo bene, e ha ancora quattro dei suoi piedi)

Problemi correlati