• בלוג
  • טיפ ריילס: שתי דרכים ליצור פחות מיגרציות

טיפ ריילס: שתי דרכים ליצור פחות מיגרציות

24/08/2022

אחד הדברים הראשונים שאנחנו לומדים בעבודה עם ריילס הוא ליצור מיגרציות. מיגרציה היא בעצם קוד שמשנה משהו בבסיס הנתונים, למשל יוצר טבלה או משנה עמודות בטבלה. הנה דוגמה לקוד של מיגרציה:

class CreateProducts < ActiveRecord::Migration
  def change
    create_table :products do |t|
      t.string :name
      t.text :description

      t.timestamps
    end
  end
end

שורת הפקודה של ריילס מאפשרת להריץ מיגרציות עם הפקודה:

$ ./bin/rails db:migrate

להרצת מיגרציה יש מספר השלכות:

  1. קודם כל מיגרציה משנה משהו בבסיס הנתונים. בשביל זה כתבנו אותה.

  2. בנוסף, ריילס שומר בבסיס הנתונים את המזהה של המיגרציה האחרונה שהוא הריץ, כדי שהוא יידע להריץ רק מיגרציות חדשות כל הפעלה של db:migrate.

  3. בנוסף, ריילס שומר קובץ בשם db/schema.rb שבו הוא מחזיק את ״התוצאות״ של כל המיגרציות, כלומר סוג של תמונה של בסיס הנתונים.

לכן אם הרצנו מיגרציה שיש בה טעות לא יעזור לנו לחזור לקובץ, לעדכן אותו ואז להפעיל שוב db:migrate. ריילס לא יריץ את הקובץ הזה שוב כי בבסיס הנתונים מסומן לו שהקובץ כבר הורץ.

תוצאה עצובה של ההתנהגות הזאת יכולה להיות תיקיית מיגרציות עמוסה, אפילו בפרויקטים חדשים או שעוד לא עלו לפרודקשן. זה קורה כי מתכנתים לא יודעים איך לבטל מיגרציה שהריצו ולכן יוצרים מיגרציות חדשות עם התיקונים. בדוגמה שהדבקתי קודם, אם אני מגלה בזמן פיתוח שחסרה לי עמודה בטבלת המוצרים אחרי שכבר הרצתי db:migrate אני עלול להיבהל וליצור מיגרציה חדשה שתוסיף את העמודה.

שני רעיונות יותר טובים שיעזרו לכם לשמור את תיקיית המיגרציות קטנה לפחות כשהפרויקט בתחילת הדרך-

  1. הכי קל אם זו מיגרציה יחסית עדכנית להפעיל:
$ ./bin/rails db:rollback

הפקודה הזאת מבטלת את הרצת המיגרציה האחרונה, ואז אפשר לשנות את הקוד שלה ולהפעיל db:migrate מחדש.

  1. אם צריך לשנות משהו רוחבי בהרבה טבלאות או הרבה קבצי מיגרציה, אפשר ללכת בכיוון אחר ופשוט לזרוק את כל בסיס הנתונים. כל עוד לא עלינו לפרודקשן וממילא אנחנו בפיתוח נוכל להפעיל:
$ ./bin/rails db:drop

לשנות את כל קבצי המיגרציה שיתאימו למה שאנחנו צריכים ואז להפעיל מחדש:

$ ./bin/rails db:migrate
$ ./bin/rails db:seed

שימו לב שהפעלת db:migrate מעדכנת את הקובץ db/schema.rb, וקובץ זה משפיע על הפקודה db:reset. לכן אין טעם לשנות קובץ מיגרציה ולהפעיל אחרי זה ./bin/rails db:reset. פעולה כזאת פשוט תיצור את בסיס הנתונים מחדש באותו מבנה שהוא היה קודם. אחרי שמשנים קובץ מיגרציה חייבים להפעיל מחדש db:migrate כדי לשנות גם את db/schema.rb.

בעבודה עם db:rollback ו db:drop אנחנו יכולים לבנות כמעט את כל הגירסה הראשונה של הפרויקט עם תיקיית מיגרציות יחסית קטנה. אחרי העלייה לפרודקשן החיים הופכים יותר מסובכים וכמובן שלא כדאי לשנות קבצי migration שכבר הרצתם על בסיס הנתונים האמיתי.