Bash имеет выбор с этой целью.
select result in Yes No Cancel
do
echo $result
done
Unfortunately, I've determined it's not possible to do it without using execute
.
By examining the ActiveRecord source, we can find the code for create_table
:
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
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
.
def primary_key(name)
column(name, :primary_key)
end
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"
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);"
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
, вы должны использовать опцию: id => false
create_table :employees, :id => false, :primary_key => :emp_id do |t|
t.string :emp_id
t.string :first_name
t.string :last_name
end
Похоже, что это можно сделать, используя такой подход:
create_table :widgets, :id => false do |t|
t.string :widget_id, :limit => 20, :primary => true
# other column definitions
end
class Widget < ActiveRecord::Base
set_primary_key "widget_id"
end
Это сделает столбец widget_id первичным ключом для класса Widget, после чего вы должны заполнить поле при создании объектов. У вас должна быть возможность сделать это с помощью обратного вызова before create.
Итак, что-то вроде
class Widget < ActiveRecord::Base
set_primary_key "widget_id"
before_create :init_widget_id
private
def init_widget_id
self.widget_id = generate_widget_id
# generate_widget_id represents whatever logic you are using to generate a unique id
end
end
У меня есть один способ справиться с этим. Выполняемый SQL - это ANSI SQL, поэтому он, скорее всего, будет работать в большинстве реляционных баз данных, совместимых с ANSI SQL. Я проверил, что это работает для MySQL.
Миграция:
create_table :users, :id => false do |t|
t.string :oid, :limit => 10, :null => false
...
end
execute "ALTER TABLE users ADD PRIMARY KEY (oid);"
В вашей модели сделайте следующее:
class User < ActiveRecord::Base
set_primary_key :oid
...
end
Я использую Rails 2.3.5, и мой следующий способ работает с SQLite3
create_table :widgets, { :primary_key => :widget_id } do |t|
t.string :widget_id
# other column definitions
end
Нет необходимости в : id => ложь.