1

我有一个现有的 Rails 3.2 应用程序,我想将会话存储在 Postgresql 数据库中。我在 Stackoverflow 上找到了本教程,并按照 Diego Pino 的指示进行操作。

但是,当我到达该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

4

2 回答 2

1

查看生成的 SQL,跳出:

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

您的表名是sessions,但它引用的是另一个名为 的表sessions。出于某种原因,它表明此表中的列是名为 的表中列session_id的外键。idsessions

所以很明显,它不能使session_id您的会话表中的列成为同一个表中列的外键id- 正如错误告诉您的那样:

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

根据ActiveRecord::SessionStore的文档:

由 Active Record 类支持的会话存储。提供了一个默认类,但是任何对象鸭式键入到带有文本 session_id 和数据属性的 Active Record 会话类就足够了。

这是该页面的链接:

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

你能发布你的/config/initializers/session_store.rb文件的内容吗?

于 2012-05-17T02:40:43.227 回答
1

我使用上面 Andrew 的建议检查了schema_plus库的文档,这是我问题的根源:

SchemaPlus 添加了对外键约束的支持。事实上,对于使用后缀 _id 来表示它是外键的列命名的常见约定,SchemaPlus 会自动定义适当的约束。

值得庆幸的是,可以通过使用:references => nil设置在迁移中覆盖此行为。查看自述文件以获取更多信息。

于 2012-05-19T17:52:19.963 回答