1

红宝石:红宝石2.0.0p195(2013-05-14修订版40734)[x86_64-darwin12.3.0]

@user = User.find(1)
User Load (0.8ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 1]]
=> #<User id: 1, first_name: "d", last_name: "g", crypted_password: "$2a$10$h4Bil49Pw.bxf0jXvw4mEeYzKh2tgL9kUx/CtBeTg2HB...", salt: "3r3xXr3oqHGP5MpzdxAE", in_games: nil>

我正在加载一个用户,如上图所示。postrges 中 in_games 的数据类型是 integer[] 我不明白为什么会收到错误消息。(如下图)

 if @user.in_games.nil?
    array = []
    @user.in_games = array.push(@game.id)
  else
    @user.in_games << @game.id
  end
 @user.save


ActiveRecord::StatementInvalid: PGError: ERROR:  array value must start with "{" or dimension information
LINE 1: UPDATE "users" SET "in_games" = '---
                                    ^
: UPDATE "users" SET "in_games" = '---
4

1 回答 1

1

看起来你正在放弃你的数组方法,但我会在这里留下一些笔记以供后代使用。


Rails3 不理解 PostgreSQL 的开箱即用数组类型(AFAIK 这在 Rails4 中得到了补救),您需要包含postgres_ext或类似的 gem 以使 PostgreSQL 数组与 Rails3 一起使用。

如果没有支持数组的东西,ActiveRecord 将尝试对它不理解的任何输入进行 YAML 化,因此看起来很奇怪的字符串:

UPDATE "users" SET "in_games" = '---
                                ^^^^

最终出现在您的 SQL 中。如果您查看整个 SQL 语句,您应该会看到数组的 YAML 版本。


顺便说一句,一旦您使阵列支持工作,这将不会按您期望的方式工作:

@user.in_games << @game.id

文档有这样的postgres_ext说法:

下面将修改names属性的默认值。

a = Item.new
a.names << 'foo'

b = Item.new
puts b.names
# => ['foo']

支持的修改方式a.names

a = Item.new
a.names += ['foo']

b = Item.new
puts b.names
# => []

因此,不鼓励 in place 运算符,并且此时 postgres_ext 将不支持。

如果您说@user.in_games << @game.id您正在in_games就地修改,并且 ActiveRecord 不会注意到任何更改,如果您为其分配一个全新的数组:

@user.in_games += [ @game.id ]
# equivalent to @user.in_games = @user.in_games + [ @game.id ]

然后 ActiveRecord 会注意到in_games发生了变化,并且一切(_changed?方法、SQL UPDATE、...)都应该按预期工作。

于 2013-06-06T22:03:38.480 回答