Postgres数据类型为ruby中的integer []

时间:2013-06-06 20:42:13

标签: ruby-on-rails ruby arrays ruby-on-rails-3 postgresql

ruby​​:ruby 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的数据类型是整数[] 我不明白为什么我收到错误。 (如下所示)

 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" = '---

1 个答案:

答案 0 :(得分:1)

看起来你正在放弃你的阵列方法,但我会留下一些笔记给后人。


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

如果没有东西支持数组,ActiveRecord会尝试YAMLize它不理解的任何输入,因此奇怪的字符串:

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
# => []
     

因此,不鼓励操作员,也不会   目前在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,......)应该按预期工作。