【问题标题】:Storing arrays in database using ActiveRecord使用 ActiveRecord 在数据库中存储数组
【发布时间】:2010-06-23 09:28:27
【问题描述】:

我在 Rails 2.3.8 上,我使用 mysql 作为数据库适配器。 我想将数组存储在我的数据库中。经过搜索,我可以想出这个非常有用的article

现在我需要使用 GUI 进行输入,而不仅仅是服务器控制台。所以说我有一个名为 nums 的文本字段,它在逻辑上应该有 int 数组。 nums 的格式应该是什么,以便从该字符串中检索和存储数组变得容易?

【问题讨论】:

  • 在 Rails 4 中,您现在可以使用 array 类型,它在 PostgreSQL 上将其存储为数组,或者在其他所有内容上存储为字符串。

标签: ruby-on-rails ruby activerecord


【解决方案1】:

如果您使用serialize,那么您不必担心数据在文本字段中的存储方式,尽管它实际上是 YAML。

serialize 记录在 the Rails/ActiveRecord API 中(向下滚动到标题为“在文本列中保存数组、哈希和其他不可映射的对象”部分)

对于显示,您需要一种用户可以理解的格式,并且可以在代码中轻松转换回数组。逗号或空格分隔?

输出格式:

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

转换回数组可能如下:

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

或者也许使用 String#scan?

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

【讨论】:

  • 谢谢迈克。 :) 我已经想通了。一种更简单(尽管容易出错)的方法是直接使用 eval 函数。所以:num_array=eval(nums) 也很好用!
  • 这更容易,但如果您要使用 eval,则需要非常彻底地清除无效输入的数据。如果您不小心,eval() 会打开大量安全漏洞。
【解决方案2】:

如果您使用的是 postgres 和 rails 4,现在您有一个更好的原生选项。

# 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

【讨论】:

    猜你喜欢
    • 2015-02-07
    • 2020-08-05
    • 2011-11-13
    • 2015-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多