save an active records array
a.each(&:save)
This will call B#save
on each item in the array.
Save an array of ActiveRecords objects
Well, you should call save
method on each of them:
@reservations.each(&:save)
Or install some third party gem that provides a multiple insert
feature. You should also rewrite your if
statement, since the expression above will always return the collection itself, thus evaluating to true
.
Ruby convert array of active records or objects into array of hashes
The create
method actually persists each hash individually, as shown in the source code, so probably it's not what you are looking for. Either way the following code would do the job:
Account.create!(persons.map { |person| Hash[:person_id, person.id] })
If you need to create all records in the same database operation and are using rails 6+ you could use the insert_all method.
Account.insert_all(persons.map { |person| Hash[:person_id, person.id] })
For previous versions of rails you should consider using activerecord-import gem.
# Combination(1).to_a converts [1, 2, 3] to [[1], [2], [3]]
Account.import [:person_id], persons.pluck(:id).combination(1).to_a
Saving and retrieving an Array in Rails
You mentioned the Comment and User class extend ActiveRecord. These are models and they go in the app/models folder.
Saving arrays to the database is very straightforward as explained in the answer you linked to. All you have to do to integrate it into your project is declare which attribute you want to store Arrays in and they will be automagically serialized upon saving or updating and deserialized when you want to read them back.
You should definitely post any code you have already. I'll assume the attribute you want to serialize is in the Comment model and it's called choices
(but of course it can be anything) and it is a text field (not a string field as this might be too short if your arrays grow more than 255 characters when serialized):
# app/models/comment.rb
class Comment < ActiveRecord::Base
serialize :choices
end
That's it! Now when ever you assign a value to that attribute @comment.choices = [false, false]
it will be automatically serialized as YAML when you save and then it'll be deserialized when you read it:
class CommentController < ApplicationController
def create
@comment = Comment.new choices: [false, false, true, 'stuff', 'whatever']
end
def show
@comment = Comment.find params[:id]
@comment.choices # returns [false, false, true, 'stuff', 'whatever']
end
end
To explain what's going on "under the hood" when you save the record with an array value assigned to the choices
field ActiveRecord knows that you want to serialize it since you declared serialize :choices
in your Comment class. It will take that array value and serialize it like this:
YAML.dump(choices)
this will convert the array into this string:
"---\n- false\n- false\n- true\n- stuff\n- whatever\n"
That is the YAML representation (serialization) of the array. To read it back in (when you call comment.choices
) ActiveRecord will take the serialized string and deserialize it:
YAML.load(choices)
That will then convert the YAML string back into a Ruby array.
To summarize:
- Add a text field to your model e.g.
choices:text
when you create the migration. - Declare
serialize :choices
in your model. - Use as normal.
Hope that helps.
Storing arrays in database using ActiveRecord
If you use serialize
then you shouldn't have to worry about how the data is stored within the text field, although it's actually YAML.
serialize
is documented in the Rails/ActiveRecord API (scroll down to the section headed "Saving arrays, hashes, and other non-mappable objects in text columns")
For display, you need a format that is understandable to users and that can be easily converted back into an array in your code. Comma- or space-delimited?
Formatting for output:
delim = ',' # or ' ' for spaces, or whatever you choose
array.join(delim)
Converting back into an array might work as follows:
num_array = nums.split(delim).map(&:to_i) # or to_f if not integers
or perhaps using String#scan?
num_array = nums.scan(/\d+/).map(&:to_i) # for positive integers
Related Topics
Does Rails Come with a "Not Authorized" Exception
Have Devise Create a Subdomain on Registration
In Ruby What Is the Meaning of Colon After Identifier in a Hash
Datetime with Mongodb/Mongoid and Rails 3 Not Populating
Retrieving Image Height with Carrierwave
How to Select the Longest String from a Ruby Array
Examples of 'Things' That Are Not Objects in Ruby
Rake Db:Migration Not Working on Travis-Ci Build
How to Sort a Ruby Hash Alphabetically by Keys
Iterate Over Days, Starting from X Date Through an End Date
Map an Array Modifying Only Elements Matching a Certain Condition
Memorable Name Generator Gem for Ruby