2011-11-11 33 views
28

Có thể tạo thuộc tính cho một lớp là mảng không? Tôi đã cố gắng đọc this nhưng tôi đã không nhận được nhiều ra khỏi nó. Tôi muốn làm một cái gì đó như thế này:Thuộc tính mảng cho Ruby Model

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

như vậy mà khi tôi gọi .thearray trên một thể hiện của Arch tôi nhận được một mảng mà tôi có thể thêm các yếu tố mới để.

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

Trả lời

47

Tạo một mô hình với một trường văn bản

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

chỉnh sửa mô hình của bạn để làm cho lĩnh vực này tuần tự để một mảng

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

kiểm tra xem nó ra

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

Migration:

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

Trong việc sử dụng mô hình serialize:

class MyModel 
    serialize :thearray, Array 
    ... 
end 

Như Marnen nói trong câu trả lời của mình, nó sẽ là tốt để biết những loại thông tin mà bạn muốn lưu trữ trong mảng đó, thuộc tính được tuần tự hóa có thể không phải là tùy chọn tốt nhất.

[Cảnh báo Marten Veldthuis] Hãy cẩn thận khi thay đổi mảng được tuần tự hóa. Nếu bạn thay đổi nó trực tiếp như thế này:

my_model.thearray = [1,2,3] 

đó làm việc tốt, nhưng nếu bạn làm điều này:

my_model.thearray << 4 

Sau đó ActiveRecord sẽ không phát hiện rằng giá trị của thearray đã thay đổi. Để nói AR về sự thay đổi đó, bạn cần phải làm điều này:

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

Nó sẽ là một chuỗi các chuỗi. Tuần tự hóa đường đi? – tquarton

+0

@tquarton Hầu như chắc chắn là không. Xem câu trả lời của tôi. –

9

Wh ile bạn có thể sử dụng một mảng serialized như tokland đề nghị, điều này hiếm khi là một ý tưởng tốt trong một cơ sở dữ liệu quan hệ. Bạn có ba lựa chọn thay thế cao cấp:

  • Nếu mảng chứa đối tượng thực thể, có thể mô hình tốt hơn là mối quan hệ has_many.
  • Nếu mảng thực sự chỉ là một mảng các giá trị như số, thì bạn có thể muốn đặt từng giá trị vào một trường riêng biệt và sử dụng composed_of.
  • Nếu bạn định sử dụng nhiều giá trị mảng không phải là has_many, bạn có thể muốn điều tra một DB thực sự hỗ trợ các trường mảng. PostgreSQL thực hiện điều này (và các trường mảng được hỗ trợ trong việc di chuyển Rails 4), nhưng bạn có thể muốn sử dụng một cơ sở dữ liệu không phải SQL như MongoDB hoặc đối tượng bền vững như MagLev được cho là cung cấp.

Nếu bạn có thể mô tả trường hợp sử dụng của mình - tức là dữ liệu bạn có trong mảng - chúng tôi có thể cố gắng tìm ra hành động tốt nhất.

+0

Ah ok, mảng của tôi sẽ chỉ là chuỗi. Bạn nghĩ sao? – tquarton

+0

Mảng đại diện cho những gì? Tại sao bạn có nó ở nơi đầu tiên? –

+3

Ban đầu tôi viết rằng tôi không biết về bất kỳ cơ sở dữ liệu SQL nào lưu trữ mảng hoặc băm. Hóa ra Postgres giao dịch với cả hai loại này một cách tự nhiên, và Rails 4 hỗ trợ chúng trong việc di trú và ActiveRecord. Chỉ cần thêm một lý do nữa để sử dụng Postgres. :) –

Các vấn đề liên quan