Ruby模型的数组属性

tqu*_*ton 28 ruby migration attributes database-design ruby-on-rails-3.1

是否可以为作为数组的类创建属性?我试过读这个,但我没有太多的东西.我想做这样的事情:

class CreateArches < ActiveRecord::Migration
  def change
    create_table :arches do |t|
      t.string :name
      t.array :thearray
      t.timestamps
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

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

ruby-1.9.2-p290 :006 > arc = Arch.new
ruby-1.9.2-p290 :007 > arc.thearray
 => [] 
Run Code Online (Sandbox Code Playgroud)

sor*_*ens 48

使用文本字段创建模型

> 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) ==========================================
Run Code Online (Sandbox Code Playgroud)

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

class Arches < ActiveRecord::Base
  serialize :thearray,Array
end
Run Code Online (Sandbox Code Playgroud)

测试一下

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"] 
Run Code Online (Sandbox Code Playgroud)


Mar*_*ser 10

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

  • 如果数组包含实体对象,则可能更好地建模为has_many关系.
  • 如果数组实际上只是一个值数组(如数字),那么您可能希望将每个值放在一个单独的字段中并使用composed_of.
  • 如果您要使用许多非has_manys 的数组值,您可能需要调查实际支持数组字段的数据库.PostgreSQL执行此操作(并且Rails 4迁移中支持数组字段),但您可能希望使用像MongoDB这样的非SQL数据库或者像MagLev应该提供的对象持久性.

如果您可以描述您的用例 - 即您在阵列中获得的数据 - 我们可以尝试帮助确定最佳行动方案.

  • 我最初写道,我不知道任何存储数组或哈希本地的SQL数据库.事实证明Postgres原生处理这两种类型,Rails 4在迁移和ActiveRecord中支持它们.使用Postgres的另一个原因.:) (3认同)

tok*_*and 6

移民:

t.text :thearray, :default => [].to_yaml
Run Code Online (Sandbox Code Playgroud)

在模型中使用序列化:

class MyModel
  serialize :thearray, Array
  ...
end
Run Code Online (Sandbox Code Playgroud)

正如Marnen在他的回答中所说,知道要在该数组中存储什么类型的信息会很好,序列化属性可能不是最佳选择.

[Marten Veldthuis的警告]小心改变序列化阵列.如果你直接改变它:

my_model.thearray = [1,2,3]
Run Code Online (Sandbox Code Playgroud)

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

my_model.thearray << 4
Run Code Online (Sandbox Code Playgroud)

然后ActiveRecord将不会检测到该阵列的值已更改.要告诉AR有关此更改,您需要这样做:

my_model.thearray_will_change!
my_model.thearray << 4
Run Code Online (Sandbox Code Playgroud)