Saving and retrieving an Array in Rails

回眸只為那壹抹淺笑 提交于 2019-12-24 12:54:00

问题


I'm developing an e-learning in Rails and I want to save a set of Arrays to the database, with the aim of tracking a user's progress through the various sections of the e-learning.

I've come across this question and answer:
Storing arrays in database : JSON vs. serialized array
...which sounds like it might be useful, but I can't figure out how to integrate it into the Rails project I'm developing.

Given that I'm pretty much a Rails noob, could someone explain to me, in plain English (or alternatively plain code) how I would:
a) save to a database an Array which holds a sequence of 'false' Booleans when a user initially signs up.
b) retrieve and update that Array from various pages throughout the e-learning.

I would set out what I have tried, but it's just been wild stabs in the dark and I don't really know where to start. Should the Comment class be saved in the controllers folder? Or is it, in my example, actually the User class (which, similarly, extends ActiveRecord)?

Once again, any help (ideally explaining where the code belongs) much appreciated.

UPDATE

I've been asked to be more specific, so I will try:
I have a user table in the database, which (predictably) has several fields, including email, username, etc. I'd like to add 5 more fields to the user table, each storing an Array to track the user's progress through each of the 5 sections. I'm envisaging, when a user opens a piece of content, the Array would be updated and the appropriate index would be updated to 'true' to flag that THAT part of the section is complete.

I hope that helps...

RE-UPDATE

When a user first signs up I want the Arrays to be set with a sequence of 'false' Booleans. From which file would I set the Arrays? Is that done in User? At the moment I'm trying this, but I don't think the values are being set - although it's not throwing an error.

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  serialize :leadership_styles_progress
  serialize :skills_progress
  serialize :safeguarding_progress
  serialize :tools_progress

  before_create :set_progress_vars

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
  validates :age, presence: { :message => ": Please choose your age" }
  validates :section, presence: { :message => ": Please choose the section you belong to"}
  has_many :posts

  private

  def set_progress_vars
    self.leadership_styles_progress = [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
    self.skills_progress = [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
    self.safeguarding_progress = [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
    self.tools_progress = [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
  end

end

I have also checked which routes are mapped where, via 'rake routes'; users/sign_up is mapped to devise/registrations/new. So does the serialize code, suggested below, go there?


回答1:


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.



来源:https://stackoverflow.com/questions/25916449/saving-and-retrieving-an-array-in-rails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!