Problemi con gli attributi di impostazione
-
15-10-2019 - |
Domanda
Ho un ActiveRecords
elemento e sto cercando di impostare un valore predefinito ( "elemento di prova") per ciascuno di essi utilizzando un blocco.
In questa espressione:
list = {"type1", "type2", "type3", "type4", "..."}
list.each { |name| @item.attributes["#{name}"] = "Test item"] }
I valori non sono impostati.
I deve utilizzare @item.attributes["#{name}"]
per interpolazione perché non posso fare questo per ogni elemento:
@item.tipe1 = "Test item"
Quindi, cosa succede nella prima dichiarazione? Perché? Se quello che vorrei fare non è possibile in questo modo, come posso fare lo stesso?
Soluzione
Il @items.attributes["#{name}"] = "Test item"]
assegnazione non funziona, perché il metodo attributes
restituisce un nuovo oggetto Hash ogni volta che si chiama. Quindi non si modifica il valore dell'oggetto @items
' come si pensava. Invece si sta modificando il valore del nuovo Hash che è stato restituito. E questo hash viene persa dopo ogni iterazione (e, naturalmente, quando il blocco each
ha finito).
Una possibile soluzione potrebbe essere quella di creare un nuovo hash con le chiavi del @items
' attributi e assegnare questo tramite il metodo attributes=
.
h = Hash.new
# this creates a new hash object based on @items.attributes
# with all values set to "Test Item"
@items.attributes.each { |key, value| h[key] = "Test Item" }
@items.attributes = h
Altri suggerimenti
È possibile utilizzare il metodo di invio per questo scopo. Forse in questo modo:
list = {"type1", "type2", "type3", "type4", "..."}
list.each { |name| @item.send("#{name}=", "Test item") }
Credo che il problema è che si sta solo cambiando l'hash attributo restituito, non l'oggetto ActiveRecord.
Hai bisogno di fare qualcosa di simile:
# make hash h
@items.attributes = h
Seguendo il tuo esempio, forse qualcosa di simile a:
@items.attributes = %w{type1 type2 type3 type4}.inject({}) { |m, e| m[e] = 'Test item'; m }
A proposito, "#{e}"
è la stessa cosa come stringa espressione e
o per qualsiasi tipo: e.to_s
. Un secondo esempio, forse più facile da leggere:
a = %w{type1 type2 type3 type4}
h = {}
a.each { |name| h[name] = 'test item' }
@items.attributes = h
Utilizzando il metodo attributes=
è probabilmente destinato per le costanti di hash, come:
@items.attributes = { :field => 'value', :anotherfield => 'value' }
Per gli attributi interamente generati si poteva prendere suggestione e l'uso di invio di DanneManne.