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?

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top