在Rails中保存和检索数组

时间:2014-09-18 15:13:25

标签: ruby-on-rails ruby arrays serialization deserialization

我正在开发Rails中的电子学习,我想将一组数据保存到数据库中,目的是通过电子学习的各个部分跟踪用户的进度。

我遇到过这个问题并回答:
Storing arrays in database : JSON vs. serialized array
...听起来它可能有用,但我无法弄清楚如何将它集成到我正在开发的Rails项目中。

鉴于我几乎是一个Rails noob,有人可以用简单的英语(或简单的代码)向我解释我将如何:
a)将用户最初注册时保存一系列“假”布尔值的数据保存到数据库中 b)在整个电子学习过程中从各个页面检索和更新该数组。

我会列出我尝试过的东西,但它只是在黑暗中疯狂刺伤,我真的不知道从哪里开始。 Comment类应该保存在controllers文件夹中吗?或者,在我的例子中,它实际上是User类(类似地,它扩展了ActiveRecord)?

再一次,任何帮助(理想地解释代码所属的位置)都非常感激。

更新

我被要求更具体,所以我会尝试:
我在数据库中有一个用户表,它(可预见地)有几个字段,包括电子邮件,用户名等。我想在用户表中再添加5个字段,每个字段都存储一个数组来跟踪用户的每个进度。 5个部分。我设想,当用户打开一段内容时,将更新数组并将相应的索引更新为“true”以标记该部分的部分已完成。

我希望有帮助...

重新更新

当用户首次注册时,我希望使用一系列“假”布尔值来设置数组。我将从哪个文件设置数组?用户完成了吗?目前我正在尝试这个,但我不认为这些值正在设定 - 尽管它没有抛出错误。

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

我还通过'rake routes'检查了哪些路线被映射到哪里; users / sign_up映射到devise / registrations / new。那么下面建议的序列化代码也会去那里吗?

1 个答案:

答案 0 :(得分:0)

您提到了Comment和User类扩展ActiveRecord。这些是模型,它们位于app / models文件夹中。

将数组保存到数据库非常简单,如您链接的答案中所述。要将它集成到项目中所需要做的就是声明要存储数组的属性,并在保存或更新时自动序列化,并在想要读取它们时反序列化。

你一定要发布你已经拥有的任何代码。我假设您要序列化的属性在Comment模型中,它被称为choices(但当然它可以是任何东西)并且它是一个文本字段(不是字符串字段,因为如果它可能太短,如果序列化时,您的数组增长超过255个字符):

# app/models/comment.rb
class Comment < ActiveRecord::Base
  serialize :choices
end

就是这样!现在,当您为该属性@comment.choices = [false, false]分配一个值时,它将在您保存时自动序列化为YAML,然后在您阅读时将其反序列化:

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

当您使用分配给choices字段的数组值保存记录时,要解释“幕后”的内容ActiveRecord知道您要序列化它,因为您在评论中声明了serialize :choices类。它将采用该数组值并将其序列化为:

YAML.dump(choices)

这会将数组转换为此字符串:

"---\n- false\n- false\n- true\n- stuff\n- whatever\n"

这是数组的YAML表示(序列化)。要重读(当你调用comment.choices时)ActiveRecord将获取序列化字符串并反序列化它:

YAML.load(choices)

然后将YAML字符串转换回Ruby数组。

总结:

  • 在模型中添加文字字段,例如创建迁移时choices:text
  • 在您的模型中声明serialize :choices
  • 正常使用。

希望有所帮助。