Atrybut Array dla modelu Ruby

Czy jest możliwe utworzenie atrybutu dla klasy, która jest tablicą? Próbowałem przeczytać to , ale nie wyciągnąłem z tego zbyt wiele. Chcę zrobić coś takiego:

class CreateArches < ActiveRecord::Migration
  def change
    create_table :arches do |t|
      t.string :name
      t.array :thearray
      t.timestamps
    end
  end
end
Tak, że kiedy dzwonię .thearray na instancji Arch dostaję tablicę, do której mogę dodać nowe elementy.
ruby-1.9.2-p290 :006 > arc = Arch.new
ruby-1.9.2-p290 :007 > arc.thearray
 => [] 
Author: Community, 2011-11-11

3 answers

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

Edytuj model, aby pole zostało serializowane do tablicy

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

Przetestuj to

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"] 
 48
Author: sorens,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-11 17:44:11

Chociaż można użyć szeregowej tablicy, jak zasugerował tokland, rzadko jest to dobry pomysł w relacyjnej bazie danych. Masz trzy lepsze alternatywy:

  • jeśli tablica zawiera obiekty encji, jest prawdopodobnie lepiej modelowana jako relacja has_many.
  • jeśli tablica jest tak naprawdę tylko tablicą wartości, takich jak liczby, możesz umieścić każdą wartość w osobnym polu i użyć composed_of.
  • Jeśli masz zamiar używać wielu wartości tablicy, które nie są has_many s, Możesz może warto zbadać DB, które faktycznie obsługuje pola tablicy. PostgreSQL robi to (a pola tablic są obsługiwane w migracjach Rails 4), ale możesz chcieć użyć innej bazy danych niż SQL, takiej jak MongoDB lub obiekt persistence, takiej jak MagLev .

Jeśli możesz opisać swój przypadek użycia , czyli jakie dane masz w tablicy, możemy spróbować pomóc ustalić, jaki jest najlepszy sposób działania.

 10
Author: Marnen Laibow-Koser,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-01 21:12:35

Migracja:

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

W modelu użyj serialize :

class MyModel
  serialize :thearray, Array
  ...
end

Jak mówi Marnen w swojej odpowiedzi, dobrze byłoby wiedzieć, jakie informacje chcesz przechowywać w tej tablicy, seryjny atrybut może nie być najlepszą opcją.

[[5]} [Ostrzeżenie Martena Veldthuisa] uważaj na zmianę tablicy seryjnej. Jeśli zmienisz go bezpośrednio w ten sposób:
my_model.thearray = [1,2,3]

To działa dobrze, ale jeśli to zrobisz:

my_model.thearray << 4

Wtedy ActiveRecord nie wykryje, że wartość thearray się zmienił. Aby powiedzieć AR o tej zmianie, musisz to zrobić:

my_model.thearray_will_change!
my_model.thearray << 4
 6
Author: tokland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-11 17:59:01