2011-11-11 12 views
28

Czy jest możliwe utworzenie atrybutu dla klasy będącej tablicą? Próbowałem przeczytać this, ale nie miałem z tego zbyt wiele. Chcę zrobić coś takiego:Atrybut tablicy dla modelu Ruby

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

tak, że gdy zadzwonię .thearray na wystąpienie Arch mam tablicę, że mogę dodać nowe elementy do.

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

Odpowiedz

47

Tworzenie modelu z polem tekstowym

> 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) ========================================== 

zmieniać swoich modeli, aby pole szeregowane do tablicy

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

przetestować go

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

Migracja:

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

W zastosowaniu modelu serialize:

class MyModel 
    serialize :thearray, Array 
    ... 
end 

Jak Marnen mówi w swojej odpowiedzi, że byłoby dobrze, aby wiedzieć, jaki rodzaj informacji chcesz zapisać w tej tablicy atrybut szeregowy może nie być najlepszą opcją.

[Ostrzeżenie Martena Veldthuisa] Uważaj na zmianę zserializowanej tablicy. Jeśli go bezpośrednio zmienić tak:

my_model.thearray = [1,2,3] 

który działa dobrze, ale jeśli to zrobić:

my_model.thearray << 4 

Następnie ActiveRecord nie wykryje, że wartość thearray uległ zmianie. Powiedzieć AR o tej zmiany, trzeba to zrobić:

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

Będzie to tablica ciągów. Czy serializacja to droga? – tquarton

+0

@tquarton Prawie na pewno nie. Zobacz moją odpowiedź. –

9

Wh ile możesz użyć serializowanej tablicy, jak sugerował tokland, rzadko jest to dobry pomysł w relacyjnej bazie danych. Masz trzy doskonałe alternatywy:

  • Jeśli tablica zawiera obiekty obiektu, prawdopodobnie jest lepiej wymodelowana jako relacja has_many.
  • Jeśli tablica jest tak naprawdę tylko tablicą wartości, takich jak liczby, wtedy możesz umieścić każdą wartość w osobnym polu i użyć composed_of.
  • Jeśli zamierzasz używać wielu wartości tablicowych, które nie są has_many s, możesz sprawdzić DB, który faktycznie obsługuje pola tablicy. PostgreSQL robi to (i pola tablicy są obsługiwane w migracji Rails 4), ale możesz chcieć użyć bazy danych innej niż SQL, takiej jak MongoDB lub trwałość obiektów, takich jak MagLev.

Jeśli możesz opisać swój przypadek użycia - czyli jakie dane masz w tablicy - możemy spróbować pomóc w ustaleniu najlepszego sposobu działania.

+0

Ach ok, moja tablica będzie miała tylko łańcuchy. Co myślisz? – tquarton

+0

Co reprezentuje tablica? Dlaczego masz to na pierwszym miejscu? –

+3

Pierwotnie napisałem, że nie znałem żadnej bazy danych SQL, która przechowywała tablice lub hasze natywnie. Okazało się, że Postgres radzi sobie z tymi dwoma typami, a Railsy 4 wspierają je w migracji i ActiveRecord. Jeszcze jeden powód, aby korzystać z PostgreSQL. :) –

Powiązane problemy