Answers:
提供的:name
选项add_index
,例如:
add_index :studies,
["user_id", "university_id", "subject_name_id", "subject_type_id"],
:unique => true,
:name => 'my_index'
如果在块中使用:index
选项on ,它将使用与其值相同的选项哈希:references
create_table
add_index
t.references :long_name, index: { name: :my_index }
remove_index :studies, :name => 'my_index'
于需要它的任何人
4.2.6
与index: { name: :my_index }
。只有name
没有工作。
您还可以在create_table
块内的列定义中更改索引名称(例如从迁移生成器获取的名称)。
create_table :studies do |t|
t.references :user, index: {:name => "index_my_shorter_name"}
end
create_table
t.references :searchable, polymorphic:true, index: {:name => "index_searches_on_searchable"}
在这种情况下,指数实际上是一个多列(searchable_id和searchable_type)和生成的名称,即命名空间的很长成了。
foreign_key: true
和方式,这是一个很好的解决方案,因为它是最简单的,当你有创建的迁移文件中使用Rails生成model:references
格式
在PostgreSQL,在默认情况下限制为63个字符。因为索引名称必须唯一,所以有一些约定是很好的。我使用(我调整了示例以解释更复杂的结构):
def change
add_index :studies, [:professor_id, :user_id], name: :idx_study_professor_user
end
正常的索引应该是:
:index_studies_on_professor_id_and_user_id
逻辑将是:
index
变成 idx
_id
通常是哪个工作。
你也可以
t.index([:branch_id, :party_id], unique: true, name: 'by_branch_party')
恐怕这些解决方案都不适合我。也许是因为我belongs_to
在create_table迁移中使用了多态关联。
我将在下面添加我的代码,并提供指向该解决方案的链接,该链接可以帮助我,以防其他人在搜索与多态关联有关的“索引名太长”时偶然发现。
以下代码对我不起作用:
def change
create_table :item_references do |t|
t.text :item_unique_id
t.belongs_to :referenceable, polymorphic: true
t.timestamps
end
add_index :item_references, [:referenceable_id, :referenceable_type], name: 'idx_item_refs'
end
此代码DID对我有用:
def change
create_table :item_references do |t|
t.text :item_unique_id
t.belongs_to :referenceable, polymorphic: true, index: { name: 'idx_item_refs' }
t.timestamps
end
end
这是帮助我解决问题的SO问答:https : //stackoverflow.com/a/30366460/3258059
我有这个问题,但timestamps
功能。它是在updated_at上自动生成一个超过63个字符限制的索引:
def change
create_table :toooooooooo_loooooooooooooooooooooooooooooong do |t|
t.timestamps
end
end
表“ toooooooooo_loooooooooooooooooooooooooooooooooooong”上的索引名“ index_toooooooooo_looooooooooooooooooooooooooooooooooooong_on_updated_at”太长;限制为63个字符
我试图用来timestamps
指定索引名称:
def change
create_table :toooooooooo_loooooooooooooooooooooooooooooong do |t|
t.timestamps index: { name: 'too_loooooooooooooooooooooooooooooong_updated_at' }
end
end
但是,这试图将索引名称同时应用于updated_at
和created_at
字段:
表“ toooooooooo_loooooooooooooooooooooooooooooooooong”上的索引名称“ too_long_updated_at”已存在
最后,我放弃了timestamps
,只是创建了很长的时间戳记:
def change
create_table :toooooooooo_loooooooooooooooooooooooooooooong do |t|
t.datetime :updated_at, index: { name: 'too_long_on_updated_at' }
t.datetime :created_at, index: { name: 'too_long_on_created_at' }
end
end
这行得通,但我很想听听这种timestamps
方法是否可行!
create_table:you_table_name做| t | t.references:学生,索引:{名称:'name_for_studant_index'} t.references:教师,索引:{name:'name_for_teacher_index'}结尾
我有一个项目,该项目经常使用生成器,并且需要自动生成,因此我index_name
从rails源复制了该函数以覆盖它。我在添加此config/initializers/generated_index_name.rb
:
# make indexes shorter for postgres
require "active_record/connection_adapters/abstract/schema_statements"
module ActiveRecord
module ConnectionAdapters # :nodoc:
module SchemaStatements
def index_name(table_name, options) #:nodoc:
if Hash === options
if options[:column]
"ix_#{table_name}_on_#{Array(options[:column]) * '__'}".slice(0,63)
elsif options[:name]
options[:name]
else
raise ArgumentError, "You must specify the index name"
end
else
index_name(table_name, index_name_options(options))
end
end
end
end
end
它创建像这样的索引ix_assignments_on_case_id__project_id
,如果仍然太长,则将其截断为63个字符。如果表名很长,那仍然是不唯一的,但是您可能会增加一些复杂性,例如将表名与列名分开缩短或实际检查唯一性。
注意,这来自Rails 5.2项目。如果您决定这样做,请从您的版本中复制源。