27

私はジュニア Rails 開発者で、職場で次の問題に直面しました。

1 つのレコードのみの列の値を更新する必要がありました。私たちが行ったことは、次のような移行を作成することです。

class DisableAccessForUser < ActiveRecord::Migration
  def change
    User.where(name: "User").first.update_column(:access, false)
  end
end

移行はスキーマの変更のみですか?

他にどのような解決策を提案しますか?

PS: コードでしか変更できません。コンソールにアクセスできません。

4

7 に答える 7

22

短いバージョンは、移行はスキーマの変更のみであるため、データベース内の実際のデータを変更するために移行を使用したくないということです。

rake db:schema:load主な問題は、他の開発者がまたはを使用して DB 構造をロードすると、データ操作の移行が無視される可能性があることrake db:resetです。どちらも、schema.rbファイルを使用して構造の最新バージョンをロードするだけで、移行には触れません。

Nikita Singh もコメントで指摘しているように、行データを変更する最善の方法は、移行構造に関係なく、必要に応じて実行できる単純な rake タスクを実装することだと私も思います。または、初めてインストールする場合、seed.rbファイルは初期システム データをロードするのに最適です。

とりとめのないことが役立つことを願っています。

アップデート

いくつかの「公式」ソースでいくつかのドキュメントを見つけました:

  • 移行のための Rails ガイド - 移行でのモデルの使用。このセクションでは、移行ファイルでのデータ操作が他の開発者に問題を引き起こすシナリオについて説明します。
  • 移行のための Rails ガイド - 移行とシード データseed.rd上記と同じドキュメントでは、シードやデータ操作を移行に含めることがなぜ悪いのかを実際には説明しておらず、すべてをファイルに入れるように言っているだけです。
  • このSOの答えこの人物は、Rails の作成者であるDavid Heinemeier Hanssonによって部分的に書かれた本Agile Web Development with Rails (3rd edition)からの引用を提供することを除いて、基本的に私が上で書いたのと同じことを言っています。その投稿で読むことができるので、引用をコピーしませんが、移行でのシードまたはデータ操作が悪い習慣と見なされる理由をよりよく理解できると思います.
于 2013-10-28T12:49:03.827 に答える
2

マイグレーションでクラスを使用してデータを変更することは危険です。クラスを変更すると、将来、移行が簡単に中断される可能性があります。

たとえば、ユーザー (sample_group) に新しい列を追加し、オブジェクトのロード時に実行される Rails ライフサイクル コールバック (after_initialize など) でその列にアクセスするとします。それはこの移行を中断します。(update_column を使用して) 保存時にコールバックと検証をスキップしていなければ、この移行を中断する方法が他にもあります。

移行でデータを変更したい場合、通常は SQL にフォールバックします。execute() メソッドを使用して、移行で任意の SQL ステートメントを実行できます。使用する正確な SQL は、使用中のデータベースによって異なりますが、db に適したクエリを考え出すことができるはずです。たとえば、MySQL では、次のように動作するはずです。

 execute("UPDATE users SET access = 0 WHERE id IN (select id from users order by id limit 1);")

これははるかに将来の証拠です。

于 2013-10-31T07:02:18.033 に答える
1

移行を使用してデータベース内のデータを移行することは、適切な状況で適切に行えば何の問題もありません。

移行で避けるべき 2 つの関連する事柄があり (多くの人が言及しているように)、どちらもデータの移行を妨げません。

  1. 移行でモデルを使用するのは安全ではありません。モデル内のコードUserが変更される可能性があり、その場合誰も移行を更新しません。そのため、同僚が 3 か月間休暇を取って戻ってきて、不在中に発生したすべての移行を実行しようとすると、しかし、その間に誰かがUserモデルの名前を変更すると、移行が中断され、彼女が追いつくことができなくなります。これは、SQL を使用するか、または (移行の実装にとらわれずに維持することに決めた場合) ActiveRecord モデルの独立したコピーを移行ファイル (移行クラスの下にネスト) に直接含める必要があることを意味します。

  2. また、シード データに移行を使用することも意味がありません。シード データとは、具体的には、誰かが初めてアプリをセットアップしてアプリを実行する (またはアプリの新しいインスタンスで期待されるデータ)。初めてデータベースをセットアップするときに移行を実行しないため、これには移行を使用できませんdb:schema:load。したがって、シード データを維持するための特別なファイル: seeds.rb. これは、移行にデータを追加する必要があり(本番データとすべての開発データを高速化するために)、シード データ (アプリの実行に必要) としての資格がある場合は、それをに追加する必要があることを意味します。seeds.rbそれも!

ただし、どちらも既存のデータベースのデータを移行するために移行を使用すべきではないという意味ではありません。それが彼らの目的です。あなたはそれらを使うべきです!

于 2016-12-12T20:42:54.527 に答える
0

私の記憶が正しければ、特定のレコードを変更するとうまくいくかもしれませんが、それについてはわかりません。

いずれにせよ、それは良い習慣ではありません。移行は、スキーマの変更のみのユーザーにする必要があります。1 つのレコードを更新するには、コンソールを使用します。ターミナルに「rails console」と入力し、コードを入力して属性を変更するだけです。

于 2013-10-15T20:09:37.023 に答える