2013-05-22 10 views
7

Ho un modello nella mia app Rails per un Bollettino, e quando viene creato, molti valori sono memorizzati nel database come hash o array serializzati, per poterli accedere successivamente. Sto cercando di creare una visualizzazione di modifica solo per uno di questi hash, ma non riesco a capire come accedervi nel mio modulo.Come modificare gli hash serializzati di Rails in un modulo?

L'hash assomiglia a questo, se conservati:

top_offices = { first_office: "Office Name", first_office_amount: 1234.50, 
second_office: "Office Name", second_office_amount: 1234.50 } 

E così via ... ci sono cinque uffici.

Così nella console posso modificare i valori facendo:

bulletin = Bulletin.last 
bulletin.top_offices[:first_office] = "New Office" 
bulletin.top_offices[:first_office_amount] = 1234.00 
bulletin.save 

io non riesco a capire come fare un modulo che mi permette di assegnare correttamente quei valori. Non ho nemmeno realmente bisogno del modulo per popolare con i valori precedentemente memorizzati perché li sto modificando completamente ogni volta che utilizzo il modulo.

risposta

8

Opzione 1: metodo di istanza singola per aggiornare attributo serializzato

Per quanto ne so che non è possibile modificare direttamente da un modulo di un attributo serializzato.

Quando ho questo tipo di cose, creo sempre un metodo di istanza nel modello che riceve parametri e fa l'aggiornamento (Potrebbe anche fare il salvataggio se termino il nome del metodo con un botto (!)).

Nel tuo caso vorrei fare le seguenti operazioni:

class Bulletin 

    ... 

    def update_top_offices!(params) 
    params.each do |key, value| 
     self.top_offices[key] = value 
    end 

    self.save 
    end 

    ... 
end 

Opzione 2: un getter/setter per le chiavi degli attributi serializzati

anche un'altra possibilità se si vuole veramente ad utilizzare un modulo per aggiornare il serializzato attributo è quello di creare un getter/setter come segue:

class Bulletin 

    ... 

    def first_office 
    self.top_offices[:first_office] 
    end 

    def first_office=(value) 
    self.top_offices[:first_office] = value 
    end 

    ... 
end 

Ma poi non dimenticare di salvare valori aggiornati.

Opzioni 3: method_missing Overriding

Un'ultima possibilità è quella di ignorare method_missing ma è un po 'più complessa.

+0

Ok. Penso che sarò in grado di capirlo usando l'opzione uno. Probabilmente preferisco il secondo approccio, ma non riesco a capire come funziona nella mia testa. Come uso questi metodi nel modulo? Posso semplicemente creare un 'form_tag' e alcuni' text_field_tag' per ': first_office' e così via, una volta che li definisco e invio all'azione di aggiornamento? –

+1

Gli helper * _fieldview stanno cercando il nome dell'attributo assegnato all'oggetto dato form_for. Quindi, se hai fatto 'form_for @bulletin do | f |' e poi fai 'f.text_field: first_office', l'helper' text_field' chiamerà qualcosa chiamato first_office sull'oggetto.Potrebbe essere un attributo o un metodo. Questa è la parte "magica";) – ZedTuX

5

Ecco un esempio che esegue semplicemente un'iterazione sulle coppie chiave/valore esistenti in top_offices e genera campi modulo per esse.

<% @bulletin.top_offices.each do |key, value| %> 
    <input name="bulletin[top_offices][<%= key %>]" type="text" value="<%= value %>" /> 
<% end %> 

genererà:

<input name="bulletin[top_offices][first_office]" ... /> 
<input name="bulletin[top_offices][first_office_amount]" ... /> 
# etc. 

Se non vi fidate gli utenti allora si potrebbe desiderare di fare un controllo di integrità sui valori presentati per top_offices.

Problemi correlati