البحث في الموقع
المحتوى عن 'أون'.
-
إن التهجير من أهم مزايا Active Record، حيث يسمح لك بتطوير قاعدة البيانات بسهولة مع مرور الزمن. فبدلًا من إعادة كتابة مُخططات قاعدة البيانات بسطور SQL من جديد، سيسمح لك التهجير باستعمال كود Ruby موحد المجال Domain – specific language لوصف التعديلات اللازمة التي ستقوم بها على جداولك. 1 نظرة عامة على التهجير التهجير هو الطريقة الملائمة لتبديل أجزاء و مُخططات قاعدة البيانات بمرور الزمن بطريقة سهلة و متناسقة. ونقوم بإستعمال لُغة Ruby موحدة المجال DSL بدلًا من كتابة العديد من سطور SQL مما يسمح للتغيرات بأن تكون مُستقلة تمامًا عن قاعدة البيانات و لا تؤثر عليها سلبًا. يُمكنك التفكير في التهجير على أنه عمل تحديث جديد لقاعدة البيانات. ففي بداية الإسكيما تكون فارغة، ثُم بعد ذلك تقوم عمليات التهجير بإضافة الجداول، العواميد، أو المدخلات. و Active Record يقوم بعمل هذه التحديثات على الإسكيما من الحالة التي كانت عليها قبل التحديث (أو في النُسخة السابقة). كما سيقوم Active Record بتحديث ملف db/schema.rb ليُناسب بناء قاعدة البيانات بعد التحديث. مثال على التهجير class CreateProducts < ActiveRecord::Migration[5.0] def change create_table :products do |t| t.string :name t.text :description t.timestamps end end end في المثال السابق، قُمنا بعملية تهجير حيث أضفنا جدول جديد يُسمى products يحتوي على عامود نصي يُسمى name و عامود آخر يُسمى description. وسيتم إضافة عامود مفتاح أساسي يُسمى id ضمنيًا، لأنه –كما علمنا من قبل- المفتاح الرئيسي الإفتراضي لجميع نماذج Active Record. آما أمر timestamps يُضيف عامودين، صُنع في created_at وتم تحديثه في updated_at. و تلك العواميد الخاصة يتم إدارتها و تحديثها تلقائيًا بواسطة Active Record. لاحظ أن عملية التغير التي نقوم بها تتحرك أمامًا مع مرور الوقت، فقبل تشغيل التهجير run migration لن يوجد لدينا ذلك الجدول، و بمجرد تشغيل كود التهجير سنحصل على الجدول، و العكس صحيح! فإن Active Record يُمكنه عكس عملية التهجير بإستخدام أمر العودة Roll back و سيُحذف الجدول الجديد. بعض قواعد البيانات تدعم الصفقات Transactions* مع التغيرات التي تحدث للإسكيما. خاصية التهجير مُحاطة بتلك الصفقات Transactions. و لكن إذا كانت قاعدة البيانات لا تسمح بالصفقات، فإن التهجير سيقوم بإلغاء الأجزاء التي لم تطرأ عليها تلك التغيرات. class ChangeProductsPrice < ActiveRecord::Migration[5.0] def change reversible do |dir| change_table :products do |t| dir.up { t.change :price, :string } dir.down { t.change :price, :integer } end end end end و بدلًا من إستخدام أمر change ستستخدم أوامر up و down. class ChangeProductsPrice < ActiveRecord::Migration[5.0] def up change_table :products do |t| t.change :price, :string end end def down change_table :products do |t| t.change :price, :integer end end end 2 إنشاء التهجير 2.1 إنشاء تهجير مُستقل و مُنفرد بنفسه إن عمليات التهجير تكون مُخزنة داخل ملف يوجد في db/migrate، و يوجد ملف لكل عملية تهجير حدثت على فئة مُعينة class. إسم الملف يتخذ الصيغة الآتية YYYYMMDDHHMMSS_creat_products.rb و هي تحتوي على صيغة الوقت التي حدث فيه التهجير، ثم علامة “_” ثم إسم عملية التهجير. إن هذا الإسم يجب أن يُطابق إسم الفئة class التي لحق بها, فعلى سبيل المثال، إن كان إسم التهجير 20080906120000_creat_products.rb فيجب أن يُعرف فئة class إسمها CreatProducts. آما بالنسبة للوقت المُلحق بالإسم، فإن Rails تستعمله لترتيب التهجيرات و ترتيب كيفية عملها. لذلك إذا قُمت بنسخ تهجير ما من تطبيق آخر. فيجب أن تلتفت لهذا الأمر. و حساب الوقت بالضبط أي الدقيقة و الثانية لأمرٌ صعب. لذلك يوفر Active Record مولد لصُنع هذا الأمر. $ bin/rails generate migration AddPartNumberToProducts سيصنع الكود أعلاه تهجير فارغ، لكنه مُسمى بتسمية صحيحة. class AddPartNumberToProducts < ActiveRecord::Migration[5.0] def change end end إذا كان التهجير على هيئة AddXXXToYYY أو RemoveXXXfromYYY أي يحتوي على أوامر إضافة أو حذف و يحتوي أيضًا على عواميد تحتوي على الأسماء names و الأنواع types، فسيتم صُنع عواميد مُناسبة مثل add_column و remove_column. و الكود أدناه مثال على ذلك. $ bin/rails generate migration AddPartNumberToProducts part_number:string سينتج عنه: class AddPartNumberToProducts < ActiveRecord::Migration[5.0] def change add_column :products, :part_number, :string end end و يُمكنك أيضًا عمل فهرسة للعواميد الجديدة. $ bin/rails generate migration AddPartNumberToProducts part_number:string:index سينتج عنه: class AddPartNumberToProducts < ActiveRecord::Migration[5.0] def change add_column :products, :part_number, :string add_index :products, :part_number end end و بنفس الطريقة يُمكنك عمل تهجير ليزيل عامود بإستخدام هذا الكود. $ bin/rails generate migration RemovePartNumberFromProducts part_number:string سينتج عنه: class RemovePartNumberFromProducts < ActiveRecord::Migration[5.0] def change remove_column :products, :part_number, :string end end كما أنك لست مُقيد بنوع واحد من العواميد لإنتاجه، مثال على ذلك $ bin/rails generate migration AddDetailsToProducts part_number:string price:decimal سينتج عنه class AddDetailsToProducts < ActiveRecord::Migration[5.0] def change add_column :products, :part_number, :string add_column :products, :price, :decimal end end لاحظ هُنا تحديد نوع البيانات الذي قُمنا به أما إذا كان التهجير يتخذ صيغة CreateXXX و مُتبع بقائمة بأسماء و أنواع العواميد، فإن التهجير سيقوم بعمل جدول XXX يحتوي على تلك العواميد، مثال: $ bin/rails generate migration CreateProducts name:string part_number:string و هذا سينتج عنه: class CreateProducts < ActiveRecord::Migration[5.0] def change create_table :products do |t| t.string :name t.string :part_number end end end وكالعادة، فإنه يُمكنك تعديل ما يتم توليده من قبل التهجير عن طريق الإضافة و الحذف. عند طريق التعديل على هذا الملف db/migrate/YYYMMDDHHMMSS_add_details_to_products.rb، على سبيل المثال: $ bin/rails generate migration AddUserRefToProducts user:references و هذا سينتج عنه: class AddUserRefToProducts < ActiveRecord::Migration[5.0] def change add_reference :products, :user, foreign_key: true end end هذا التهجير سوف يصنع عامود user_id مع فهرس مُناسب. و هُناك أيضًا العديد من الخيارات الأخرى لدالة add_reference سنتطرق إليها فيما بعد. هذا الكود سيولد جداول مُدمجة Join tables إذا إستعملت JoinTable كجزء من إسم التهجير، مثال: الجداول المُدمجة Join Tables هي تجميع لعدد معين من العواميد من جدول واحد أو أكثر من جدول. $ bin/rails g migration CreateJoinTableCustomerProduct customer product و هذا سوف ينتج التهجير الآتي: class CreateJoinTableCustomerProduct < ActiveRecord::Migration[5.0] def change create_join_table :customers, :products do |t| # t.index [:customer_id, :product_id] # t.index [:product_id, :customer_id] end end end 2.2 موالدات النماذج إن مولدات النماذج و الإسكافولد Model and Scaffold Generators يُمكنها صُنع التهجير المُناسب لإضافة نموذج جديد. حيث سيحتوي التهجير على التعليمات اللازمة لصناعة الجداول المُناسبة. فإذا حددت العواميد التي تريدها، سيتم إضافة سطور الكود اللازمة لإضافة تلك العواميد، مثال: $ bin/rails generate model Product name:string description:text و ذلك سوف يصنع هذا التهجير: class CreateProducts < ActiveRecord::Migration[5.0] def change create_table :products do |t| t.string :name t.text :description t.timestamps end end end و بالطبع يُمكنك إضافة أي عدد تشاءه 2.3 تعدية المُعدلات يُمكنك كتابة كود لتعدي المُعدلات Modifiers لأنهم قد تُقيدك. فإذا قُمت بتشغيل هذا الكود: $ bin/rails generate migration AddDetailsToProducts 'price:decimal{5,2}' supplier:references{polymorphic} سوف يُنتج هذا التهجير: class AddDetailsToProducts < ActiveRecord::Migration[5.0] def change add_column :products, :price, :decimal, precision: 5, scale: 2 add_reference :products, :supplier, polymorphic: true end end سنتابع في الدروس القادمة بقية أجزاء دليل تعليم Active Record Migrations.. المصدر: توثيقات Ruby on Rails.