Попытка настроить Rails для хранения сессий в базе данных Postgresql

У меня есть существующее приложение Rails 3.2, и я хотел бы хранить сеансы в базе данных Postgresql. Я нашел это руководство в Stackoverflow и следовал указаниям Диего Пино.

Однако, когда я дошел до шага rake db:migrate, я получил следующую ошибку:

PG::Error: ОШИБКА: ограничение внешнего ключа "sessions_session_id_fkey" не может быть реализовано. ПОДРОБНЕЕ: ключевые столбцы "session_id" и "id" имеют несовместимые типы: переменный символ и целое число.

Вот SQL, который он пытается выполнить:

CREATE TABLE "sessions" ("id" serial primary key, 
    "session_id" character varying(255) NOT NULL, 
    "data" text,
    "created_at" timestamp NOT NULL, 
    "updated_at" timestamp NOT NULL, 
    FOREIGN KEY ("session_id") REFERENCES "sessions" ("id"))

А вот миграция, которая была создана автоматически:

class AddSessionsTable < ActiveRecord::Migration                                    
  def change
    create_table :sessions do |t|
      t.string :session_id, :null => false
      t.text :date
      t.timestamps
    end
    add_index :sessions, :session_id
    add_index :sessions, :updated_at
  end
end

Меня сбивает с толку то, что я не вижу никаких объявлений ограничений внешнего ключа в миграции. Так почему же сгенерированный sql пытается связать текстовое поле и целочисленное поле?

ОБНОВЛЕНИЕ 1

Кевин запросил содержимое моего config/initializers/session_store.rb файла:

# Be sure to restart your server when you modify this file.

Calliope::Application.config.session_store :cookie_store, key: '_calliope_session'

# Use the database for sessions instead of the cookie-based default,
# which shouldn't be used to store highly confidential information
# (create the session table with "rails generate session_migration")
#Calliope::Application.config.session_store :active_record_store

Я попытался повторно запустить команду rake db:migrate после раскомментирования строки :active_record_store внизу, но это не изменило результат.

У меня также нет существующей таблицы sessions ни в моей базе данных Dev, ни в базе данных Test.


person Tom Purl    schedule 17.05.2012    source источник
comment
У вас есть гемы, которые автоматически добавляют внешние ключи?   -  person Andrew Marshall    schedule 17.05.2012
comment
Пожалуйста, опубликуйте содержимое /config/initializers/session_store.rb   -  person Kevin Bedell    schedule 17.05.2012
comment
Я использую schema_plus, но не знаю, автоматически ли он добавляет внешние ключи. Я проверю это сейчас.   -  person Tom Purl    schedule 17.05.2012
comment
Эндрю был прав. Проблема заключалась в том, что я использую schema_plus, и он автоматически пытается сделать поле внешним ключом, если оно заканчивается на _id. К счастью, schema_plus также позволяет переопределить это поведение.   -  person Tom Purl    schedule 19.05.2012
comment
Я знаю, что это просто опечатка, но вам, вероятно, следует обновить t.text :date при переходе с AddSessionsTable на t.text :data. Просто наблюдение.   -  person Dom    schedule 05.08.2012


Ответы (2)


Глядя на сгенерированный SQL, это выскакивает:

FOREIGN KEY ("session_id") REFERENCES "sessions" ("id"))

Имя вашей таблицы sessions, но оно ссылается на то, что выглядит как другая таблица с именем sessions. По какой-то причине это указывает, что столбец session_id в этой таблице является внешним ключом для столбца id в таблице с именем sessions.

Итак, ясно, что он не может сделать столбец session_id в вашей таблице сеансов внешним ключом для столбца id в той же таблице - как говорит вам ошибка:

Key columns "session_id" and "id" are of incompatible types: character varying and integer.

Согласно документам для ActiveRecord::SessionStore:

Хранилище сеансов, поддерживаемое классом Active Record. Предусмотрен класс по умолчанию, но достаточно любого объекта, утиного ввода в класс сеанса Active Record с текстом session_id и атрибутами данных.

Вот ссылка на страницу:

http://apidock.com/rails/ActiveRecord/SessionStore

Можете ли вы опубликовать содержимое вашего файла /config/initializers/session_store.rb?

person Kevin Bedell    schedule 17.05.2012
comment
Спасибо, Кевин, я обновил свой вопрос выше, указав содержимое этого файла. У меня уже есть контроллеры сеансов и представления, но нет моделей. Я создал их ранее, чтобы упростить управление сеансами. Могут ли эти файлы способствовать этим проблемам? - person Tom Purl; 17.05.2012
comment
Спасибо Кевину за понимание, но оказалось, что это функция библиотеки schema_plus, которую я использовал. - person Tom Purl; 19.05.2012

Я проверил документацию по библиотеке schema_plus, используя приведенный выше совет Эндрю, и вот корень моей проблемы:

SchemaPlus добавляет поддержку ограничений внешнего ключа. Фактически, для общепринятого соглашения о том, что вы называете столбец суффиксом _id, чтобы указать, что это внешний ключ, SchemaPlus автоматически определяет соответствующее ограничение.

К счастью, это поведение можно переопределить при миграции с помощью параметра :references => nil. Ознакомьтесь с README для получения дополнительной информации.

person Tom Purl    schedule 19.05.2012