web-dev-qa-db-ja.com

Rubyモデルの配列属性

配列であるクラスの属性を作成することは可能ですか?私は this を読んでみましたが、それをあまり活用していませんでした。私はこのようなことをしたいです:

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

archのインスタンスで.thearrayを呼び出すと、新しい要素を追加できる配列が得られます。

Ruby-1.9.2-p290 :006 > arc = Arch.new
Ruby-1.9.2-p290 :007 > arc.thearray
 => [] 
28
tquarton

テキストフィールドを含むモデルを作成する

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

モデルを編集してフィールドを配列にシリアル化する

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

試してみる

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
sorens

Toklandが示唆するようにシリアライズされた配列を使用できますが、これはリレーショナルデータベースではあまり良いアイデアとは言えません。次の3つの優れた選択肢があります。

  • 配列がエンティティオブジェクトを保持している場合は、おそらくhas_many関係としてモデル化した方がよいでしょう。
  • 配列が数値などの値の配列にすぎない場合は、各値を別々のフィールドに入れて、composed_ofを使用することができます。
  • has_manysではない多くの配列値を使用する場合は、実際に配列フィールドをサポートしているDBを調査することをお勧めします。 PostgreSQLはこれを行います(そして、配列フィールドはRails 4移行)でサポートされますが、MongoDBなどの非SQLデータベースまたは MagLev などのオブジェクト永続性を使用することもできます=提供することになっています。

ユースケース、つまり配列に取得したデータを説明できれば、最善のアクションを理解するのに役立ちます。

10

移行:

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

モデルでは serialize を使用します:

class MyModel
  serialize :thearray, Array
  ...
end

Marnenが彼の答えで述べているように、その配列にどのような種類の情報を格納したいかを知っておくと良いでしょう。シリアル化された属性は最良のオプションではないかもしれません。

[Marten Veldthuisの警告]シリアル化された配列の変更には注意してください。次のように直接変更した場合:

my_model.thearray = [1,2,3]

それはうまくいきますが、これを行うと:

my_model.thearray << 4

次に、ActiveRecordは配列の値が変更されたことを検出しません。その変更についてARに伝えるには、次のようにする必要があります。

my_model.thearray_will_change!
my_model.thearray << 4
6
tokland

Postgresを使用している場合は、その 配列機能 を使用できます。

移行:

add_column :model, :attribute, :text, array: true, default: []

そして、それを配列のように使用します:

model.attribute # []
model.attribute = ["d"] #["d"]
model.attribute << "e" # ["d", "e"]

このアプローチはMarnenによって言及されましたが、ここでは例が役立つと思います。

0
akz92