Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Array Attribute for Ruby Model

People also ask

Can you add arrays in Ruby?

This can be done in a few ways in Ruby. The first is the plus operator. This will append one array to the end of another, creating a third array with the elements of both. Alternatively, use the concat method (the + operator and concat method are functionally equivalent).

What is a array in Ruby?

An array is a data structure that represents a list of values, called elements. Arrays let you store multiple values in a single variable. In Ruby, arrays can contain any data type, including numbers, strings, and other Ruby objects. This can condense and organize your code, making it more readable and maintainable.

Is an array an object in Ruby?

What are array methods in Ruby? Array methods in Ruby are essentially objects that can store other objects. You can store any kind of object in an array. You can create an array by separating values by commas and enclosing your list with square brackets.


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

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:

  • If the array holds entity objects, it's probably better modeled as a has_many relationship.
  • 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 MagLev is supposed to provide.

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.


Migration:

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

In the model use 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.

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

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:

my_model.thearray_will_change!
my_model.thearray << 4

If using Postgres, you can use its Array feature:

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.