Как запретить rails вызывать next_seq для таблицы соединений без идентификатора?

Я работаю с Rails 3.2.13 и fb-адаптером (firebird, но я не думаю, что это уместно здесь).

У меня есть модель соединения, которую используют две другие модели с «has_many A, через: X».

Я создал таблицу без «id» (согласно руководствам по рельсам и здравому смыслу, потому что pk представляет собой комбинацию двух) следующим образом:

create table "X", id: false do |t|
  t.integer "a_id", null: false
  t.integer "b_id", null: false
end

Затем, когда я попытался создать модель, я получил «ActiveRecord:: UnknownPrimaryKey»; хорошо, я погуглил и нашел Почему я получаю исключение Unknown Primary Key для таблицы соединения в Rails 4?

Итак, в модели соединения я установил:

class X < ActiveRecord::Base
  self.primary_key = [:a_id, :b_id]
  ...
end

Теперь я могу создать новую модель, но когда я пытаюсь ее сохранить, я сталкиваюсь с "Fb::Error: Неверный генератор токенов X_SEQ не определен", поэтому в основном рельсы пытаются получить следующее значение для идентификатора, но поскольку столбец также не был создан генератор или последовательность для него.

Вот соответствующий код в activerecord/relation.rb:

def insert(values)
  primary_key_value = nil

  if primary_key && Hash === values
    primary_key_value = values[values.keys.find { |k|
      k.name == primary_key
    }]

    if !primary_key_value && connection.prefetch_primary_key?(klass.table_name)
      ### exception get's raised here in next_sequence_value ###
      primary_key_value = connection.next_sequence_value(klass.sequence_name)
      values[klass.arel_table[klass.primary_key]] = primary_key_value
    end
  end

  ...
end

Я не знаю, происходит ли это также с адаптерами sqlite3/mysql/postegres, но я считаю, что если ПК является составным рельсом, не следует пытаться получить «следующее значение для него».. или должен быть какой-то способ предотвратить это от попытки получить следующее значение. Любые идеи, как решить эту проблему (без исправления активной записи)? Спасибо


person pragmatic_programmer    schedule 21.11.2013    source источник


Ответы (1)


Для чистых отношений «многие ко многим» используйте has_and_belongs_to_many отношения в ваших моделях. Для вашей таблицы соединений модель не требуется. Используйте has_many:через отношения, где дополнительные данные ( например, порядок сортировки или временные метки) необходим в вашей таблице соединений. В таком случае подойдет полноценная модель, а для моделей требуется первичный ключ.

person Brent Rowland    schedule 21.11.2013
comment
Моя модель имеет другие данные, то, что я представил здесь, представляет собой упрощение, которое фокусируется на проблеме. Я снова прочитал руководство по рельсам, и похоже, что вы правы, руководство предлагает использовать id: false только в подразделе HABTM ... это не имеет для меня полного смысла, но похоже, что это путь рельсов, потому что он не поддерживает составной pk. - person pragmatic_programmer; 21.11.2013