2

Den Versuch, den Wert einer Postgres ENUM Spalte wirft die folgende Ausnahme zu aktualisieren:Mit Postgres ENUM mit Schienen ergibt `PG :: DatatypeMismatch`

ActiveRecord::StatementInvalid Exception: PG::DatatypeMismatch: ERROR: column "interesting_column" is of type interesting_thing but expression is of type integer

LINE 1: UPDATE "interesting_table" SET "interesting_column" = 0, "updated_a...

HINT: You will need to rewrite or cast the expression.

InterestingTable.first.update_attributes!(normal_column: 'food') 
    # => perfectly fine 
InterestingTable.first.update_attributes!(interesting_column: 'foo') 
    # => above exception 

Hier ist die Migration der Tabelle zu erstellen:

Antwort

3

Das Problem ist, dass, während die Spalte den richtigen Typ in der Datenbank hat, der aktive Datensatz versucht, es als integer zu interpretieren. Sie können das überprüfen, indem Sie:

InterestingTable.columns 
# => [#<ActiveRecord::ConnectionAdapters::PostgreSQLColumn:0x007f7567f82260 
#  @coder=nil, 
#  @default=nil, 
#  @limit=nil, 
#  @name="id", 
#  @null=false, 
#  @precision=nil, 
#  @primary=true, 
#  @scale=nil, 
#  @sql_type="integer", 
#  @type=:integer>, 
#  #<ActiveRecord::ConnectionAdapters::PostgreSQLColumn:0x007f7568075690 
#  @coder=nil, 
#  @default=nil, 
#  @limit=nil, 
#  @name="normal_column", 
#  @null=true, 
#  @precision=nil, 
#  @primary=false, 
#  @scale=nil, 
#  @sql_type="normal_thing", 
#  @type=nil>, 
#  #<ActiveRecord::ConnectionAdapters::PostgreSQLColumn:0x007f7568075668 
#  @coder=nil, 
#  @default=nil, 
#  @limit=nil, 
#  @name="interesting_column", 
#  @null=true, 
#  @precision=nil, 
#  @primary=false, 
#  @scale=nil, 
#  @sql_type="interesting_thing", 
#  @type=:integer>] 

Beachten Sie, wie der Typ für die zweite Spalte nil ist, während die der letzten integer ist. String#to_i gibt 0 zurück, wenn Ihre Zeichenfolge nicht mit einer Zahl beginnt. Daher erhalten Sie den Fehler, den Sie versuchen, 0 zuzuweisen.


Aber warum ist das? Der Grund - interesting_thing enthält den Teilstring int, den der Adapter als integer betrachtet. Dies scheint ein lang existierender Bug zu sein, der bis zum 4.2. The offending method.


Mögliche Lösungen:

  • Migrate auf Schienen 4.2+
  • Benennen Sie Ihre ENUM zu etwas, das wird nicht
  • Affe Patch den Adapter angepasst werden. Hier ist eine quick fix.
Verwandte Themen