JJD*_*JJD 369 migration ruby-on-rails
我试图添加一个从四个相关表的外键创建的唯一索引:
add_index :studies,
["user_id", "university_id", "subject_name_id", "subject_type_id"],
:unique => true
Run Code Online (Sandbox Code Playgroud)
数据库对索引名称的限制会导致迁移失败.这是错误消息:
表'研究'上的索引名称'index_studies_on_user_id_and_university_id_and_subject_name_id_and_subject_type_id'太长; 限制为64个字符
我怎么处理这个?我可以指定不同的索引名称吗?
fl0*_*00r 560
提供:name选项add_index,例如:
add_index :studies,
["user_id", "university_id", "subject_name_id", "subject_type_id"],
:unique => true,
:name => 'my_index'
Run Code Online (Sandbox Code Playgroud)
如果在块中使用:index选项on ,则它采用与其值相同的选项hash :referencescreate_tableadd_index
t.references :long_name, index: { name: :my_index }
Run Code Online (Sandbox Code Playgroud)
Cra*_*ker 168
您还可以更改create_table块中列定义中的索引名称(例如,您从迁移生成器获取).
create_table :studies do |t|
t.references :user, index: {:name => "index_my_shorter_name"}
end
Run Code Online (Sandbox Code Playgroud)
eco*_*gic 36
在PostgreSQL,在默认情况下限制为63个字符.因为索引名称必须是唯一的,所以有一点约定是很好的.我使用(我调整了示例来解释更复杂的结构):
def change
add_index :studies, [:professor_id, :user_id], name: :idx_study_professor_user
end
Run Code Online (Sandbox Code Playgroud)
正常指数应该是:
:index_studies_on_professor_id_and_user_id
Run Code Online (Sandbox Code Playgroud)
逻辑是:
index 变 idx_id通常这项工作.
tom*_*rad 21
你也可以
t.index([:branch_id, :party_id], unique: true, name: 'by_branch_party')
Run Code Online (Sandbox Code Playgroud)
恐怕这些解决方案都不适合我。也许是因为我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
Run Code Online (Sandbox Code Playgroud)
这段代码对我有用:
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
Run Code Online (Sandbox Code Playgroud)
这是帮助我的 SO Q&A:https : //stackoverflow.com/a/30366460/3258059
与上一个答案类似:只需在常规add_index行中使用'name'键:
def change
add_index :studies, :user_id, name: 'my_index'
end
Run Code Online (Sandbox Code Playgroud)
我有一个经常使用生成器的项目,并且需要它是自动的,所以我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
Run Code Online (Sandbox Code Playgroud)
它会创建类似的索引ix_assignments_on_case_id__project_id,如果仍然太长,则将其截断为 63 个字符。如果表名很长,这仍然是不唯一的,但是您可以添加复杂性,例如与列名分开缩短表名或实际检查唯一性。
注意,这是来自 Rails 5.2 项目;如果您决定这样做,请从您的版本中复制源代码。
| 归档时间: |
|
| 查看次数: |
80834 次 |
| 最近记录: |