【发布时间】:2015-08-09 22:32:02
【问题描述】:
在 Ruby on Rails 中,具有序列化数组字段的模型将不会在 .save() 上更新,如果该数组为空,则它之前有数据。
我正在使用:
-
Ruby 2.2.1
-
Rails 4.2.1
-
sqlite3 1.3.10
我创建了一个新模型,其中一个字段设置为文本:
rails g model 用户名:字符串示例:文本
在我添加的 User.rb 文件中:
serialize :example, Array
我实例化了 User 类的一个新实例:
test = User.new
<User id: nil, name: nil, example: [], created_at: nil, updated_at: nil>
然后我保存用户以确保它正确保存:
test.save()
(0.1ms) begin transaction
SQL (0.4ms) INSERT INTO "users" ("created_at", "updated_at") VALUES (?, ?) [["created_at", "2015-05-27 16:17:31.902342"], ["updated_at", "2015-05-27 16:17:31.902342"]]
(0.7ms) commit transaction
=> true
并在其中添加了一些数据,以使其感到快乐和有目的:
test.example.push(1)
test.example.push(2)
然后保存起来:
test.save()
(0.1ms) begin transaction
SQL (0.3ms) UPDATE "users" SET "example" = ?, "updated_at" = ? WHERE "users"."id" = ? [["example", "---\n- 1\n- 2\n"], ["updated_at", "2015-05-27 16:17:50.331777"], ["id", 1]]
(0.8ms) commit transaction
=> true
并确保一切都保存完好:
test
<User id: 1, name: nil, example: [1, 2], created_at: "2015-05-27 16:17:31", updated_at: "2015-05-27 16:17:50">
我删除了一项,验证它已被删除,然后保存它,确保 SQL 输出显示 UPDATE:
test.example.delete(1)
=> 1
test
<User id: 1, name: nil, example: [2], created_at: "2015-05-27 16:17:31", updated_at: "2015-05-27 16:17:50">
test.save()
(0.1ms) begin transaction
SQL (0.9ms) UPDATE "users" SET "example" = ?, "updated_at" = ? WHERE "users"."id" = ? [["example", "---\n- 2\n"], ["updated_at", "2015-05-27 16:18:30.148553"], ["id", 1]]
(8.9ms) commit transaction
=> true
我从数组中删除了最后一条数据,验证了空数组并保存了它。请注意缺少 UPDATE 操作并且它返回 true:
test.example.delete(2)
=> 2
test
<User id: 1, name: nil, example: [], created_at: "2015-05-27 16:17:31", updated_at: "2015-05-27 16:18:30">
test.save()
(0.1ms) begin transaction
(0.1ms) commit transaction
=> true
多次保存得到相同的结果。一个新的 User 对象中仍然有最后一条数据:
test = User.find(1)
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
<User id: 1, name: nil, example: [2], created_at: "2015-05-27 16:17:31", updated_at: "2015-05-27 16:18:30">
解决方法是从模型中的序列化行中删除“数组”,将字段初始化为 nil。但这意味着我第一次将数据添加到新实例时,我必须手动将字段设置为空数组 (test.example = []) 以便在其上调用 .push()。在此设置中一切正常,新清空的数组愉快地保存到数据库中。
我在 Rails Github 上看到一个已关闭的问题,表明应始终保存序列化的列,但不知道这是否相关:
https://github.com/rails/rails/issues/8328
我无法从序列化源代码中辨别出任何可以启发我的东西:
http://apidock.com/rails/ActiveModel/Serializers/Xml/Serializer/serialize
为什么在序列化行末尾添加“Array”会导致空数组无法保存到数据库中?
【问题讨论】:
-
欢迎来到 Stack Overflow。以下是一些编写问题的技巧: 不要添加“Ruby on Rails”或类似标签。 Stack Overflow(和搜索引擎)使用您为问题定义的标签。相反,只需写一个简短的描述性句子。在正文中,不必使用标题。取而代之的是正常写作,就像给同事写信一样。 Stack Overflow 有点像编程问答的百科全书,但风格不那么正式。模仿其他问题的风格以保持共同的外观和感觉。还可以学习内联代码格式。
-
感谢您的建议和编辑!我会记住这个建议以备将来查询。您能详细说明内联代码格式吗?我在帖子中使用控制台输出,因为我认为它最能展示问题。
标签: ruby-on-rails arrays ruby serialization