使用Rails,我如何设置我的主键不是一个整数类型的列? [英] Using Rails, how can I set my primary key to not be an integer-typed column?

查看:175
本文介绍了使用Rails,我如何设置我的主键不是一个整数类型的列?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Rails迁移来管理数据库模式,我创建了一个简单的表,其中我想使用非整数值作为主键(特别是字符串)。为了抽象出我的问题,让我们假设有一个表 employees ,其中雇员通过字母数字字符串来标识。 134SNW

I'm using Rails migrations to manage a database schema, and I'm creating a simple table where I'd like to use a non-integer value as the primary key (in particular, a string). To abstract away from my problem, let's say there's a table employees where employees are identified by an alphanumeric string, e.g. "134SNW".

我已经尝试在迁移中创建表格,如下所示:

I've tried creating the table in a migration like this:

create_table :employees, {:primary_key => :emp_id} do |t|
    t.string :emp_id
    t.string :first_name
    t.string :last_name
end

这给我的是什么似乎完全忽略了 t.string:emp_id 行,并使它成为一个整数柱。有没有其他方法来让rails生成PRIMARY_KEY约束(我使用PostgreSQL)为我,而不必写在执行调用?

What this gives me is what seems like it completely ignored the line t.string :emp_id and went ahead and made it an integer column. Is there some other way to have rails generate the PRIMARY_KEY constraint (I'm using PostgreSQL) for me, without having to write the SQL in an execute call?

注意:我知道最好不要使用字符串列作为主键,所以请没有答案只是说添加一个整数主键。我可以添加一个,但这个问题仍然有效。

NOTE: I know it's not best to use string columns as primary keys, so please no answers just saying to add an integer primary key. I may add one anyway, but this question is still valid.

推荐答案

不幸的是,我确定它不可能不使用执行

Unfortunately, I've determined it's not possible to do it without using execute.

通过检查ActiveRecord源代码,我们可以找到 create_table 的代码:

By examining the ActiveRecord source, we can find the code for create_table:

schema_statements.rb code>

In schema_statements.rb:

def create_table(table_name, options={})
  ...
  table_definition.primary_key(options[:primary_key] || Base.get_primary_key(table_name.to_s.singularize)) unless options[:id] == false
  ...
end

所以我们可以看到,当你尝试在 create_table 选项,它创建具有指定名称的主键(或者如果没有指定名称,则 id )。它通过调用可以在表定义块中使用的相同方法来执行此操作: primary_key

So we can see that when you try to specify a primary key in the create_table options, it creates a primary key with that specified name (or, if none is specified, id). It does this by calling the same method you can use inside a table definition block: primary_key.

href =https://github.com/rails/rails/blob/a63f7a136401b59db52fb802180f6c9793d83bc2/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb#L89 =noreferrer> schema_statements.rb

In schema_statements.rb:

def primary_key(name)
  column(name, :primary_key)
end

这只是创建一个指定名称为:primary_key 。这在标准数据库适配器中设置如下:

This just creates a column with the specified name of type :primary_key. This is set to the following in the standard database adapters:

PostgreSQL: "serial primary key"
MySQL: "int(11) DEFAULT NULL auto_increment PRIMARY KEY"
SQLite: "INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL"



解决方法



因为我们坚持使用这些作为主键类型,我们必须使用 execute 创建不是整数的主键(PostgreSQL的 serial 是使用序列的整数):

The workaround

Since we're stuck with these as the primary key types, we have to use execute to create a primary key that is not an integer (PostgreSQL's serial is an integer using a sequence):

create_table :employees, {:id => false} do |t|
  t.string :emp_id
  t.string :first_name
  t.string :last_name
end
execute "ALTER TABLE employees ADD PRIMARY KEY (emp_id);"

并且 Sean McCleary提到,你的ActiveRecord模型应该设置主键 set_primary_key

And as Sean McCleary mentioned, your ActiveRecord model should set the primary key using set_primary_key:

class Employee < ActiveRecord::Base
  set_primary_key :emp_id
  ...
end

这篇关于使用Rails,我如何设置我的主键不是一个整数类型的列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆