Programing

Rails 3.1.0 마이그레이션에서 remove_index의 올바른 구문은 무엇입니까?

crosscheck 2020. 11. 19. 07:50
반응형

Rails 3.1.0 마이그레이션에서 remove_index의 올바른 구문은 무엇입니까?


사용자 테이블이 이미 정의 된 기존 Rails 앱에 Devise를 추가하는 중입니다. 장치 생성기는 다음 마이그레이션을 추진했습니다.

class AddDeviseToUsers < ActiveRecord::Migration
  def self.up
    change_table(:users) do |t|

     ## Database authenticatable
     t.string :email,              :null => false, :default => ""
     t.string :encrypted_password, :null => false, :default => ""

     ## Recoverable
     t.string   :reset_password_token
     t.datetime :reset_password_sent_at

     ## Rememberable
     t.datetime :remember_created_at

     ## Trackable
     t.integer  :sign_in_count, :default => 0

     blah blah blah....

   end

   add_index :users, :email,                :unique => true
   add_index :users, :reset_password_token, :unique => true
 end

하향 마이그레이션이 생성되지 않으며 해당 인덱스를 제거하는 데 시간이 많이 걸립니다. 설명서에서 다른 제안 된 표기법과 온라인에서 다른 제안 사항을보고 있지만 어느 것도 나를 위해 작동하지 않는 것 같습니다. 예를 들면 ...

def self.down
  change_table(:users) do |t|
    t.remove  :email
    t.remove  :encrypted_password

    t.remove  :reset_password_token

    blah blah blah...
  end

  remove_index :users, :email
  remove_index :users, :reset_password_token
end

결과 ...

An error has occurred, this and all later migrations canceled:

Index name 'index_users_on_email' on table 'users' does not exist

이상하게도 데이터베이스를 확인하면 'index_users_on_email'이 바로 거기에 있습니다.

다음을 포함한 다른 변형을 시도했습니다.

remove_index :users, :column => :email

remove_index :users, 'email'

또는:

change_table(:users) do |t|
  t.remove_index :email
end

...하지만 주사위는 없습니다. 저는 Postgres와 함께 Rails 3.1.0, Ruby 1.9.2, 레이크 0.9.2.2를 실행하고 있습니다.

나를 실망시키는 명령은 다음과 같습니다.

bundle exec rake db:rollback STEP=1

마이그레이션을 성공적으로 적용한 후. 어떤 충고?


데이터베이스 유형에 따라 self.down메서드 에서 인덱스 제거에 대해 걱정할 필요가 없습니다 . 열을 삭제하면 인덱스가 데이터베이스에서 자동으로 제거되기 때문입니다.

self.down메서드 에서이 구문을 사용할 수도 있습니다 .

def self.down
   remove_column :users, :email
   remove_column :users, :encrypted_password
   remove_column :users, :reset_password_token
end

레코드의 경우 이름으로 색인을 제거하는 방법은 다음과 같습니다.

remove_index(:table_name, :name => 'index_name')

그래서 당신의 경우

remove_index(:users, :name => 'index_users_on_email')

내 관점에서 이름을 쓰는 것보다 오류가 덜 발생하는 열을 지정하는 색인을 제거 할 수도 있습니다.

remove_index :actions, :column => [:user_id, :action_name]

@iWasRobbed의 답변을 확장하고 싶습니다. 단일 열에 인덱스가있는 경우 remove_index(가정 일뿐입니다!) DB가 해당 인덱스에서 사용하는 리소스를 정리할 수있을만큼 똑똑해야하므로 걱정하는 것이 의미가 없습니다. 그러나 여러 열 인덱스가있는 경우 열을 제거하면 인덱스가 여전히 존재하는 열로 축소됩니다. 이것은 완전히 현명한 작업이지만 remove_index명시 적으로 사용하려는 위치를 보여줍니다 .

예시를 위해-아래 마이그레이션에는 위아래로 적용된 후 고유 인덱스가 유지되는 결함이 있습니다 email( down부품이 제대로 작동하지 않음을 의미 함 ).

class AddIndexes < ActiveRecord::Migration
  def up
    add_column :users, :action_name, :string
    add_index  :users, [:email, :action_name], unique: true
  end

  def down
    remove_column :users, :action_name
  end
end

down블록을 다음으로 변경

  def down
    remove_index :users, [:email, :action_name]
    remove_column :users, :action_name
  end

이 결함을 수정하고 마이그레이션이 DB를 이전 상태로 올바르게 되돌릴 수 있도록합니다. rake db:rollback


To alter a table and/or its indeces use #change_table inside #change action of a migration. Then you be able to create reversable index removal as follows:

def change
   change_table :users do |t|
      t.index :email, :unique => true
      t.index :reset_password_token, :unique => true
   end
end

When you have to drop a table with its index of course with reversable action you can use #drop_table method for SchemaStatements with the #index method of Table class for ConnectionAdapter:

def change
   drop_table :users do |t|
      t.index :email, :unique => true
      t.index :reset_password_token, :unique => true
   end
end

In case you have need exactly the #up/down pair in a migration. Use just a #change_table method along with #remove_index method of Table class for ConnectionAdapter:

def up
   change_table :users do |t|
      t.index :email, :unique => true
      t.index :reset_password_token, :unique => true
   end
end

def down
   change_table :users do |t|
      t.remove_index :email, :unique => true
      t.remove_index :reset_password_token, :unique => true
   end
end

All of the methods are available in Rails version of 2.1.0 or of earlier ones.


Here is my full run of this(in Rails 5):

I have team_id as an index in table vendors. I no longer need this relation. To get rid of it. Did the following:

1) create the migration.

  $ rails generate migration RemoveTeam_idFromVendor team_id:integer

2) Running the migration, give me this error. And that is because vendor table has rows whose foreign key references the primary key value of the team table

== 20170727202815 RemoveTeamIdFromVendor: migrating ===========================
-- remove_column(:vendors, :team_id, :integer)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

SQLite3::ConstraintException: FOREIGN KEY constraint failed: DROP TABLE "vendors"

3) To solve this and get the migration running, I did the following(Note: i am in dev):

$ rake db:drop


Dropped database 'db/development.sqlite3'
Dropped database 'db/test.sqlite3'


$ rake db:create
Created database 'db/development.sqlite3'
Created database 'db/test.sqlite3'

$ rake db:migrate
~
~
~

== 20170727202815 RemoveTeamIdFromVendor: migrating ===========================
-- remove_column(:vendors, :team_id, :integer)
   -> 0.0185s
== 20170727202815 RemoveTeamIdFromVendor: migrated (0.0185s) ==================

참고URL : https://stackoverflow.com/questions/9028387/whats-the-correct-syntax-for-remove-index-in-a-rails-3-1-0-migration

반응형