28

È possibile creare un attributo per una classe che è un array? Ho provato a leggere this ma non ne ho ricavato molto. Voglio fare qualcosa di simile:Attributo array per Ruby Modello

class CreateArches < ActiveRecord::Migration 
    def change 
    create_table :arches do |t| 
     t.string :name 
     t.array :thearray 
     t.timestamps 
    end 
    end 
end 

tale che quando chiamo .thearray su un'istanza di Arch ottengo un array che posso aggiungere nuovi elementi al.

ruby-1.9.2-p290 :006 > arc = Arch.new 
ruby-1.9.2-p290 :007 > arc.thearray 
=> [] 

risposta

47

Creare un modello con un campo di testo

> rails g model Arches thearray:text 
    invoke active_record 
    create db/migrate/20111111174052_create_arches.rb 
    create app/models/arches.rb 
    invoke test_unit 
    create  test/unit/arches_test.rb 
    create  test/fixtures/arches.yml 
> rake db:migrate 
== CreateArches: migrating =================================================== 
-- create_table(:arches) 
    -> 0.0012s 
== CreateArches: migrated (0.0013s) ========================================== 

modificare il proprio modello per rendere il campo serializzato in un array

class Arches < ActiveRecord::Base 
    serialize :thearray,Array 
end 

provarlo

ruby-1.8.7-p299 :001 > a = Arches.new 
=> #<Arches id: nil, thearray: [], created_at: nil, updated_at: nil> 
ruby-1.8.7-p299 :002 > a.thearray 
=> [] 
ruby-1.8.7-p299 :003 > a.thearray << "test" 
=> ["test"] 
6

Migrazione:

t.text :thearray, :default => [].to_yaml 

Nell'uso modello di serialize:

class MyModel 
    serialize :thearray, Array 
    ... 
end 

Come Marnen dice nella sua risposta, sarebbe bene sapere che tipo di informazioni che si desidera memorizzare in quell'array, un attributo serializzato potrebbe non essere l'opzione migliore.

[avviso Marten Veldthuis] Prestare attenzione a modificare l'array serializzato. Se si modifica direttamente in questo modo:

my_model.thearray = [1,2,3] 

Questo funziona bene, ma se si esegue questa operazione:

my_model.thearray << 4 

Allora ActiveRecord non rileverà che il valore di theArray è cambiato. A dire AR quel cambiamento, è necessario fare questo:

my_model.thearray_will_change! 
my_model.thearray << 4 
+0

Sarà una serie di stringhe. La serializzazione è la strada da percorrere? – tquarton

+0

@tquarton Quasi certamente no. Vedi la mia risposta. –

9

Wh è possibile utilizzare un array serializzato come suggerito da tokland, raramente è una buona idea in un database relazionale. Esistono tre alternative alternative:

  • Se la matrice contiene oggetti entità, è probabilmente meglio modellata come una relazione has_many.
  • Se la matrice è in realtà solo una matrice di valori come i numeri, è possibile inserire ciascun valore in un campo separato e utilizzare composed_of.
  • Se si stanno utilizzando molti valori di array che non sono has_many s, è possibile esaminare un DB che supporti effettivamente campi di array. PostgreSQL esegue questa operazione (e i campi dell'array sono supportati nelle migrazioni di Rails 4), ma è possibile che si desideri utilizzare un database non SQL come MongoDB o la persistenza dell'oggetto, ad esempio MagLev.

Se riesci a descrivere il tuo caso d'uso, ovvero quali dati hai nell'array, possiamo provare a capire quale sia la migliore linea d'azione.

+0

Ah ok, il mio array sarà solo di stringhe. Cosa ne pensi? – tquarton

+0

Che cosa rappresenta la matrice? Perché lo hai in primo luogo? –

+3

Originariamente scrivevo che non conoscevo alcun database SQL che memorizzasse array o hash nativamente. Si scopre che Postgres si occupa di entrambi questi tipi in modo nativo e Rails 4 li supporta nelle migrazioni e ActiveRecord. Un motivo in più per usare Postgres. :) –