Ruby 模型的数组属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8097750/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 04:28:51  来源:igfitidea点击:

Array Attribute for Ruby Model

rubydatabase-designattributesmigrationruby-on-rails-3.1

提问by tquarton

Is it possible to create an attribute for a class that is an array? I tried reading thisbut I didn't get much out of it. I want to do something like this:

是否可以为作为数组的类创建属性?我试着阅读这篇文章,但我没有从中得到太多。我想做这样的事情:

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

such that when I call .thearray on an instance of Arch I get an array that I can add new elements to.

这样当我在 Arch 实例上调用 .thearray 时,我会得到一个可以添加新元素的数组。

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

回答by sorens

Create a model with a text field

创建带有文本字段的模型

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

edit your model to make the field serialized to an array

编辑您的模型以使字段序列化为数组

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

test it out

测试一下

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"] 

回答by Marnen Laibow-Koser

While you can use a serialized array as tokland suggested, this is rarely a good idea in a relational database. You have three superior alternatives:

虽然您可以按照 tokland 的建议使用序列化数组,但这在关系数据库中很少是一个好主意。您有三个更好的选择:

  • If the array holds entity objects, it's probably better modeled as a has_manyrelationship.
  • If the array is really just an array of values such as numbers, then you might want to put each value in a separate field and use composed_of.
  • If you're going to be using a lot of array values that aren't has_manys, you might want to investigate a DB that actually supports array fields. PostgreSQL does this (and array fields are supported in Rails 4 migrations), but you might want to use either a non-SQL database like MongoDB or object persistence such as MagLevis supposed to provide.
  • 如果数组包含实体对象,则最好将其建模为has_many关系。
  • 如果数组实际上只是一个值数组,例如数字,那么您可能希望将每个值放在一个单独的字段中并使用composed_of.
  • 如果您要使用很多不是has_manys的数组值,您可能需要调查一个实际支持数组字段的数据库。PostgreSQL 会这样做(Rails 4 迁移支持数组字段),但您可能想要使用非 SQL 数据库(如 MongoDB)或对象持久性(如MagLev应该提供)。

If you can describe your use case -- that is, what data you've got in the array -- we can try to help figure out what the best course of action is.

如果你能描述你的用例——也就是说,你在数组中得到了什么数据——我们可以尝试帮助找出最好的行动方案。

回答by tokland

Migration:

移民:

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

In the model use serialize:

在模型中使用serialize

class MyModel
  serialize :thearray, Array
  ...
end

As Marnen says in his answer, it would be good to know what kind of info you want to store in that array, a serialized attribute may not be the best option.

正如 Marnen 在他的回答中所说,最好知道您想在该数组中存储什么样的信息,序列化属性可能不是最佳选择。

[Marten Veldthuis' warning] Be careful about changing the serialized array. If you change it directly like this:

[Marten Veldthuis 的警告] 更改序列化数组时要小心。如果你像这样直接改变它:

my_model.thearray = [1,2,3]

That works fine, but if you do this:

这工作正常,但如果你这样做:

my_model.thearray << 4

Then ActiveRecord won't detect that the value of thearray has changed. To tell AR about that change, you need to do this:

那么 ActiveRecord 不会检测到数组的值已经改变。要告诉 AR 有关该更改,您需要执行以下操作:

my_model.thearray_will_change!
my_model.thearray << 4

回答by akz92

If using Postgres, you can use its Array feature:

如果使用 Postgres,你可以使用它的Array 特性

Migration:

移民:

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

And then just use it like an array:

然后像数组一样使用它:

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

This approach was mentioned by Marnen but I believe an example would be helpful here.

Marnen 提到了这种方法,但我相信这里有一个例子会有所帮助。