1

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 のデータ型は 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 の配列型を理解できません (これは Rails4 で修正されています) postgres_ext

配列をサポートするものがないと、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
# => []

その結果、インプレース演算子は推奨されず、現時点では 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 に答える