2013-07-18 3 views
3

Я использую ActiveRecord с адаптером oracle на Ruby on Rails. При попытке удалить строку я получаю StatementInvalid Exception.ActiveRecord destroy_all throws StatementInvalid

Вот как моя таблица выглядит следующим образом: room_user_table

room | user 
1010 | a 
1010 | b 
1011 | a 
1011 | c 
1011 | d 

Мой рубиновый ActiveRecord класс:

class RoomUserTable < ActiveRecord:Base 
    self.table_name = 'room_user_table' 
end 

Теперь я хочу, чтобы удалить 2-ю строку, например, таким образом, я выдавать

RoomUserTable.destroy_all(:room => 1010, :user => 'b') 

Но это бросание ActiveRecord :: StatementInvalid Exception

OCIError: ORA-01741: illegal zero-length identifier: DELETE FROM "ROOM_USER_TABLE" WHERE "ROOM_USER_TABLE"."" = :a1 

Любая помощь будет очень признательна.

Мой test_controller.rb

class TestController < ActionController::Base 
    def test 
     RoomUserTable.destroy_all(:room => 1010, :user => 'b') 
    end 
end 
+1

RoomUserTable.where (: room => 1010,: user => 'b'). First.destroy – Debadatt

+1

Это порождает одно и то же исключение «ORA-01741: незаконный идентификатор нулевой длины» – gnuger

ответ

1

Вашего RoomUserTable не имеет первичный ключ, который вызывает ее для выполнения запроса, что у вас есть в вашем вопросе WHERE "ROOM_USER_TABLE"."" = ..., который, в свою очередь, вызывает Oracle, чтобы бросить шаткий. Модели Rails должны иметь первичные ключи.

Таблица выглядит как таблица соединений, поэтому вам не нужно создавать модель для нее или напрямую запрашивать ее. Вы можете использовать связь has_and_belongs_to_many между User и Room и указать таблицу соединений.

class Room < ActiveRecord::Base 
    has_and_belongs_to_many :users, join_table: :room_user_table 
end 

class User < ActiveRecord::Base 
    has_and_belongs_to_many :rooms, join_table: :room_user_table 
end 

Или аналогичный.

Редактировать - говоря, что у вас есть a, b и т. Д. В столбце пользователя, поэтому я понятия не имею, что это за таблица, но проблема все та же, у вас нет первичного ключа.

+0

На самом деле room_user_table имел составной первичный ключ (пользователь, номер), который не имеет встроенной поддержки в ror. Я пытаюсь установить http://compositekeys.rubyforge.org/ для преодоления этого – gnuger

+0

По какой-то причине плагин составных клавиш не работал для меня. Таким образом, я создал дополнительный столбец идентификатора в качестве первичного ключа, установленного для auto_increment, следующего за http://stackoverflow.com/questions/11296361/how-to-create-id-with-auto-increment-on-oracle. Теперь все работает нормально. Спасибо Майку – gnuger

0

Для удаления simgle записи вы должны сделать

RoomUserTable.where(:room => 1010, :user => 'b').first.destroy 

причина, почему я предлагаю это потому, что это безопаснее, чем destroy_all, но имеет смысл только тогда, когда вы пытаясь удалить одну запись.

Лучшим было бы найти запись по идентификатору, конечно.

Это также должно работать, но, учитывая вашу проблему, я не уверен.

RoomUserTable.where(:room => 1010, :user => 'b').destroy_all 
+0

Я попробовал, что тоже получил 'ArgumentError':' неправильное количество аргументов (0 для 1) 'Я не уверен, почему я получаю это – gnuger

+0

Может быть, попробуйте со старым хэш-обозначением? Можете ли вы вставить трассировку этого объекта ArgumentError где-нибудь (pastie.org)? –

+0

Вот полный след http://pastie.org/8151889 – gnuger

0

Попробуйте

RoomUserTable.where(:room => 1010, :user => 'b').first.destroy 
+1

Это то же исключение «ORA-01741: незаконный идентификатор нулевой длины» – gnuger