2010-06-23 33 views
23

Tôi đang trên đường ray 2.3.8 & Tôi đang sử dụng mysql làm bộ điều hợp db. Tôi muốn lưu trữ các mảng trong cơ sở dữ liệu của mình. Sau khi tìm kiếm tôi có thể đưa ra điều này rất hữu ích article.Lưu trữ các mảng trong cơ sở dữ liệu bằng ActiveRecord

Bây giờ tôi cần sử dụng GUI để nhập & không chỉ bàn điều khiển máy chủ. Vì vậy, nói rằng tôi có một trường văn bản được gọi là nums mà hợp lý nên có mảng int. Định dạng chữ số sẽ là gì để dễ dàng truy xuất & lưu trữ mảng ra khỏi chuỗi đó?

+0

Trong Rails 4, bây giờ bạn có thể dùng lệnh 'array' loại, mà các cửa hàng nó như một mảng trên PostgreSQL, hoặc như là một chuỗi trên mọi thứ khác. – Zaz

Trả lời

35

Nếu bạn sử dụng serialize thì bạn không cần phải lo lắng về cách dữ liệu được lưu trữ trong trường văn bản, mặc dù nó thực sự là YAML.

serialize được ghi chép lại trong the Rails/ActiveRecord API (di chuyển xuống phần đầu "mảng tiết kiệm, băm, và các đối tượng phi trí trên bản đồ khác trong các cột văn bản")

Đối với màn hình, bạn cần có một định dạng đó là dễ hiểu cho người dùng và có thể dễ dàng chuyển đổi trở lại thành mảng trong mã của bạn. Phân cách bằng dấu phẩy hoặc dấu cách?

Định dạng cho đầu ra:

delim = ',' # or ' ' for spaces, or whatever you choose 
array.join(delim) 

Chuyển đổi trở lại thành một mảng có thể làm việc như sau:

num_array = nums.split(delim).map(&:to_i) # or to_f if not integers 

hoặc có lẽ sử dụng String # quét?

num_array = nums.scan(/\d+/).map(&:to_i) # for positive integers 
+0

Cảm ơn Mike. :) Tôi đã tìm ra. Một cách dễ dàng hơn (mặc dù bị lỗi) là trực tiếp sử dụng hàm eval. như vậy: num_array = eval (nums) làm việc quá ngọt ngào! –

+3

Nó dễ dàng hơn, nhưng nếu bạn đang sử dụng eval, bạn cần phải chà dữ liệu cho các đầu vào không hợp lệ RẤT kỹ lưỡng. eval() mở ra một tấn lỗ hổng bảo mật nếu bạn không cẩn thận. – MunkiPhD

13

Nếu bạn đang sử dụng postgres và ray 4, bây giờ bạn có tùy chọn gốc tốt hơn.

# db/migrate/20140207133952_create_books.rb 
create_table :books do |t| 
    t.string 'title' 
    t.string 'tags', array: true 
    t.integer 'ratings', array: true 
end 
add_index :books, :tags, using: 'gin' 
add_index :books, :ratings, using: 'gin' 

# app/models/book.rb 
class Book < ActiveRecord::Base 
end 

# Usage 
Book.create title: "Brave New World", 
      tags: ["fantasy", "fiction"], 
      ratings: [4, 5] 

## Books for a single tag 
Book.where("'fantasy' = ANY (tags)") 

## Books for multiple tags 
Book.where("tags @> ARRAY[?]::varchar[]", ["fantasy", "fiction"]) 

## Books with 3 or more ratings 
Book.where("array_length(ratings, 1) >= 3") 

http://edgeguides.rubyonrails.org/active_record_postgresql.html

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