الفرق بين المراجعتين لصفحة: «Rails/routing»

من موسوعة حسوب
إنشاء الصفحة؛ هذه الصفحة من مساهمات دعاء فرح
 
طلا ملخص تعديل
 
(2 مراجعات متوسطة بواسطة نفس المستخدم غير معروضة)
سطر 1: سطر 1:
يغطي هذا الدليل الميزات التي يواجهها المستخدم في عمليات التوجيه في Rails.
<noinclude>{{DISPLAYTITLE:التوجيه من الخارج إلى الداخل في ريلز}}</noinclude>
[[تصنيف:Rails]]
[[تصنيف:Rails Controllers]]
يغطي هذا الدليل الميزات التي يواجهها المستخدم في عمليات التوجيه في ريلز.


بعد قراءة هذا الدليل، ستعرف:
بعد قراءة هذا الدليل، ستعرف:
* كيفية تفسير الشيفرة في config/routes.rb.
* كيفية تفسير الشيفرة في config/routes.rb.
* كيفية بناء المسارات الخاصة بك باستخدام إما أسلوب الحيلة (resourceful style) المفضل أو طريقة المطابقة (match method).
* كيفية بناء المسارات الخاصة بك باستخدام إما أسلوب الحيلة (resourceful style) المفضل أو طريقة المطابقة (match method).
* كيفية الإعلان عن معاملات المسار الموجه، والتي تمرر إلى إجراءات وحدة التحكم (controller actions).
* كيفية الإعلان عن معاملات المسار الموجه، والتي تمرر إلى إجراءات [[Rails/action controller overview|وحدة التحكم]] (controller actions).
* كيفية إنشاء المسارات وعناوين URL تلقائيًا باستخدام مساعدي المسار الموجه.
* كيفية إنشاء المسارات وعناوين URL تلقائيًا باستخدام مساعدي المسار الموجه.
* التقنيات المتقدمة مثل إنشاء قيود وتثبيت نقاط نهاية Rack.
* التقنيات المتقدمة مثل إنشاء قيود وتثبيت نقاط نهاية Rack.


== الغرض من توجيه المسارات في Rails ==
== الغرض من توجيه المسارات في ريلز ==
يتعرف جهاز التوجيه في Rails على عناوين URL ويرسلها إلى إجراء وحدة التحكم، أو إلى تطبيق Rack. ويمكنه أيضًا إنشاء مسارات وعناوين URL، مع تجنب الحاجة إلى استخدام رموز ثابتة في الواجهة الخاصة بك.
يتعرف جهاز التوجيه في ريلز على عناوين URL ويرسلها إلى إجراء وحدة التحكم [[Rails/action controller overview|Action Controller]]، أو إلى تطبيق Rack. ويمكنه أيضًا إنشاء مسارات وعناوين URL، مع تجنب الحاجة إلى استخدام رموز ثابتة في الواجهة الخاصة بك.


=== توصيل عناوين URL بالشيفرة ===
=== توصيل عناوين URL بالشيفرة ===
عندما يتلقى تطبيق Rails طلبًا واردًا لما يلي: GET /patients/17  
عندما يتلقى تطبيق ريلز طلبًا واردًا مثل: <code>GET /patients/17</code> يطلب من جهاز التوجيه مطابقته مع إجراء وحدة تحكم [[Rails/action controller overview|Action Controller]]. إذا كان أول مسار مطابق هو:<syntaxhighlight lang="rails">
 
يطلب من جهاز التوجيه مطابقته مع إجراء وحدة تحكم. إذا كان أول مسار مطابق هو:<syntaxhighlight lang="rails">
get '/patients/:id', to: 'patients#show'
get '/patients/:id', to: 'patients#show'
</syntaxhighlight>
</syntaxhighlight>يرسل الطلب إلى وحدة التحكم <code>patients</code> الخاص بالإجراء <code>show</code> مع <code>{ id: '17' }</code> في <code>params</code>.
 
يرسل الطلب إلى وحدة التحكم patients الإجراء show مع { id: '17' } في params.
 
=== إنشاء مسارات وعناوين URL من الشيفرة ===
=== إنشاء مسارات وعناوين URL من الشيفرة ===
يمكنك أيضًا إنشاء مسارات وعناوين URL. إذا تم تعديل المسار الموجه أعلاه ليكون:
يمكنك أيضًا إنشاء مسارات وعناوين URL. إذا تم تعديل المسار الموجه أعلاه ليكون:<syntaxhighlight lang="rails">
 
get '/patients/:id', to: 'patients#show', as: 'patient'
get '/patients/:id', to: 'patients#show', as: 'patient'
 
</syntaxhighlight>ويحتوي التطبيق الخاص بك على هذا الرمز في وحدة التحكم:<syntaxhighlight lang="rails">
ويحتوي التطبيق الخاص بك على هذا الرمز في وحدة التحكم:
 
@patient = Patient.find(params[:id])
@patient = Patient.find(params[:id])
 
</syntaxhighlight>وهذا في الواجهة يقابل:<syntaxhighlight lang="rails">
وهذا في الواجهة يقابل:
 
<%= link_to 'Patient Record', patient_path(@patient) %>
<%= link_to 'Patient Record', patient_path(@patient) %>
</syntaxhighlight>ثم ينشئ جهاز التوجيه المسار /patients/17. هذا يقلل من هشاشة الواجهة الخاص بك ويجعل التعليمات البرمجية الخاصة بك أسهل للفهم. لاحظ أن الهوية <code>id</code> لا تحتاج إلى التحديد في مساعد المسار الموجه.


ثم ينشئ جهاز التوجيه المسار /patients/17. هذا يقلل من هشاشة الواجهة الخاص بك ويجعل التعليمات البرمجية الخاصة بك أسهل للفهم. لاحظ أن الهوية id لا تحتاج إلى التحديد في مساعد المسار الموجه.
=== تهيئة جهاز توجيه المسارات في ريلز ===
 
توجد المسارات الموجهة للتطبيق أو المحرك (engine) في الملف config/routes.rb وعادةً ما تبدو كالتالي:<syntaxhighlight lang="rails">
=== تهيئة جهاز توجيه المسارات في Rails ===
توجد المسارات الموجهة للتطبيق أو المحرك (engine) في الملف config/routes.rb وعادةً ما تبدو كالتالي:
 
Rails.application.routes.draw do
Rails.application.routes.draw do
  resources :brands, only: [:index, :show] do
    resources :products, only: [:index, :show]
  end
  resource :basket, only: [:show, :update, :destroy]
  resolve("Basket") { route_for(:basket) }
end
</syntaxhighlight>نظرًا لأن هذا ملف مصدر روبي منتظم، يمكنك استخدام جميع ميزاته لمساعدتك في تحديد مساراتك الموجهة، لكن كن حذرًا مع أسماء المتغيرات، إذ إنها يمكن أن تتعارض مع توابع DSL الخاصة بالموجه.


<nowiki> resources :brands, only: [:index, :show] do</nowiki>
'''ملاحظة''': تقوم الكتلة <code>Rails.application.routes.draw do… end</code> التي تلتزم بتعريفات المسار الموجه الخاصة بك بإنشاء النطاق الخاص بجهاز التوجيه DSL ويجب عدم حذفه.


<nowiki>   resources :products, only: [:index, :show]</nowiki>
== توجيه المورد: الافتراضي في ريلز ==
 
يتيح لك توجيه الموارد إمكانية الإعلان بسرعة عن جميع المسارات الشائعة لوحدة التحكم كثيرة الموارد. بدلًا من الإعلان عن مسارات موجهة منفصلة للإجراءات <code>index</code>، و <code>show</code>، و <code>new</code>، و <code>edit</code>، و <code>create</code>، و <code>update</code> و <code>destroy</code> الخاصة بك، فإن المسار كثير المورد يعلن عنه في سطر واحد من الشيفرة.
 end
 
<nowiki> resource :basket, only: [:show, :update, :destroy]</nowiki>
 
 resolve("Basket") { route_for(:basket) }
 
End
 
نظرًا لأن هذا ملف مصدر روبي منتظم، يمكنك استخدام جميع ميزاته لمساعدتك في تحديد مساراتك الموجهة، لكن كن حذرًا مع أسماء المتغيرات، إذ إنها يمكن أن تتعارض مع توابع DSL الخاصة بالموجه.
 
ملاحظة: تقوم كتلة Rails.application.routes.draw do… end التي تلتزم بتعريفات المسار الموجه الخاصة بك بإنشاء النطاق الخاص بجهاز التوجيه DSL ويجب عدم حذفه.
 
== توجيه المورد: الافتراضي في Rails ==
يتيح لك توجيه الموارد إمكانية الإعلان بسرعة عن جميع المسارات الشائعة لوحدة التحكم كثيرة الموارد. بدلًا من الإعلان عن مسارات موجهة منفصلة للإجراءات index، و show، و new، و edit، و create، و update و destroy الخاصة بك، فإن المسار كثير المورد يعلن عنه في سطر واحد من الشيفرة.


=== الموارد على الويب ===
=== الموارد على الويب ===
تطلب صفحات المتصفحات من Rails عن طريق تقديم طلب لعنوان URL باستخدام تابع HTTP محدد، مثل GET و POST و PATCH و PUT و DELETE. كل تابع هو طلب لتنفيذ عملية على المورد. يحدد مسار المورد الموجه عددًا من الطلبات ذات الصلة بالإجراءات في وحدة التحكم الواحدة.
تطلب صفحات المتصفحات من ريلز عن طريق تقديم طلب لعنوان URL باستخدام تابع HTTP محدد، مثل GET و POST و PATCH و PUT و DELETE. كل تابع هو طلب لتنفيذ عملية على المورد. يحدد مسار المورد الموجه عددًا من الطلبات ذات الصلة بالإجراءات في وحدة التحكم الواحدة.
 
عندما يتلقى تطبيق Rails طلبًا واردًا لما يلي:


عندما يتلقى تطبيق ريلز طلبًا واردًا لما يلي:<syntaxhighlight lang="http">
DELETE /photos/17
DELETE /photos/17
 
</syntaxhighlight>يطلب من جهاز التوجيه لتعيينه إلى إجراء وحدة تحكم [[Rails/action controller overview|Action Controller]]. إذا كان أول مسار مطابق هو:<syntaxhighlight lang="rails">
يطلب من جهاز التوجيه لتعيينه إلى إجراء وحدة تحكم. إذا كان أول مسار مطابق هو:
resources :photos
 
</syntaxhighlight>سترسل ريلز ذلك الطلب للإجراء <code>destroy</code> على وحدة التحكم <code>photos</code> مع <code>{id: '17'}</code> في <code>params</code>.
resources :photos
 
سترسل Rails ذلك الطلب للإجراء destroy على وحدة التحكم photos مع {id: '17'} في params.


=== CRUD والأفعال والإجراءات ===
=== CRUD والأفعال والإجراءات ===
في Rails، يوفر المسار كثير المورد تخطيطًا بين أفعال HTTP وعناوين URL لإجراءات التحكم. من خلال الاتفاقية، كل إجراء يخطط أيضًا لعملية CRUD محددة في قاعدة البيانات. إدخال فردي في ملف التوجيه يكون مثل:
في ريلز، يوفر المسار كثير المورد تخطيطًا بين أفعال HTTP وعناوين URL لإجراءات التحكم. من خلال الاتفاقية، كل إجراء يخطط أيضًا لعملية CRUD محددة في قاعدة البيانات. إدخال فردي في ملف التوجيه يكون مثل:<syntaxhighlight lang="rails">
 
resources :photos
resources :photos
</syntaxhighlight>ينشئ سبعة مسارات مختلفة في التطبيق الخاص بك معيَّنةً جميعها إلى وحدة التحكم <code>Photos</code>:
 
ينشئ سبعة مسارات مختلفة في التطبيق الخاص بك معيَّنةً جميعها إلى وحدة تحكم Photos:
{| class="wikitable"
{| class="wikitable"
|فعل HTTP
!فعل HTTP
|المسار
!المسار
|وحدة التحكم # الإجراء
!وحدة التحكم # الإجراء
|الإستخدامات
!الاستخدامات
|-
|-
|GET
|GET
|‎/photos
|‎/photos
|photos#index
|<code>photos#index</code>
|عرض قائمة بجميع الصور.
|عرض قائمة بجميع الصور.
|-
|-
|GET
|GET
|‎/photos/new
|‎/photos/new
|photos#new
|<code>photos#new</code>
|إرجاع نموذج HTML لإنشاء صورة جديدة.
|إرجاع نموذج HTML لإنشاء صورة جديدة.
|-
|-
|POST
|POST
|‎/photos
|‎/photos
|photos#create
|<code>photos#create</code>
|خلق صورة جديدة.
|خلق صورة جديدة.
|-
|-
|GET
|GET
|‎/photos/:id
|‎/photos/:id
|photos#show
|<code>photos#show</code>
|عرض صورة محددة.
|عرض صورة محددة.
|-
|-
|GET
|GET
|‎/photos/:id/edit
|‎/photos/:id/edit
|photos#edit
|<code>photos#edit</code>
|إرجاع نموذج HTML لتحرير صورة.
|إرجاع نموذج HTML لتحرير صورة.
|-
|-
|PATCH/PUT
|PATCH/PUT
|‎/photos/:id
|‎/photos/:id
|photos#update
|<code>photos#update</code>
|تحديث صورة معينة.
|تحديث صورة معينة.
|-
|-
|DELETE
|DELETE
|‎/photos/:id
|‎/photos/:id
|photos#destroy
|<code>photos#destroy</code>
|حذف صورة معينة.
|حذف صورة معينة.
|}
|}
ملاحظة: نظرًا لأن جهاز التوجيه يستخدم الفعل HTTP وعنوان URL لمطابقة الطلبات الواردة، فإن أربعة عناوين URL تتحول إلى سبعة إجراءات مختلفة.
'''ملاحظة''': نظرًا لأن جهاز التوجيه يستخدم الفعل HTTP وعنوان URL لمطابقة الطلبات الواردة، فإن أربعة عناوين URL تتحول إلى سبعة إجراءات مختلفة.


ملاحظة: تُطابَق مسارات Rails بالترتيب المحدد لها، لذلك إذا كانت لديك resources :photos الموجودة أعلى get photos/poll، فسيطابق مسار الإجراء show السطر resources قبل سطر get. لحل هذه المشكلة، قم بتحريك سطر get فوق سطر resources بحيث يطابقه أولًا.
'''ملاحظة''': تُطابَق مسارات ريلز بالترتيب المحدد لها، لذلك إذا كانت لديك <code>resources :photos</code> الموجودة أعلى <code>get photos/poll</code>، فسيطابق مسار الإجراء <code>show</code> السطر <code>resources</code> قبل سطر <code>get</code>. لحل هذه المشكلة، قم بتحريك سطر <code>get</code> فوق سطر <code>resources</code> بحيث يطابقه أولًا.


=== المسار ومساعد URL ===
=== المسار ومساعد URL ===
سيؤدي إنشاء مسار موجه كثير المورد إلى كشف عدد من المساعدين إلى وحدات التحكم في تطبيقك. في حالة resources :photos:
سيؤدي إنشاء مسار موجه كثير المورد إلى كشف عدد من المساعدين إلى وحدات التحكم في تطبيقك. في حالة <code>resources :photos</code>:
* photos_path returns /photos
* <code>photos_path returns /photos</code>
* new_photo_path returns /photos/new
* <code>new_photo_path returns /photos/new</code>
* edit_photo_path(:id) returns /photos/:id/edit (for instance, edit_photo_path(10) returns /photos/10/edit)
* <code>edit_photo_path(:id) returns /photos/:id/edit (for instance, edit_photo_path(10) returns /photos/10/edit)‎</code>
* photo_path(:id) returns /photos/:id (for instance, photo_path(10) returns /photos/10)
* <code>photo_path(:id) returns /photos/:id (for instance, photo_path(10) returns /photos/10)‎</code>
كل من هؤلاء المساعدين لديه مساعد ‎_url مقابل (مثل photos_url) الذي يعيد نفس المسار مسبوقًا ببادئة المضيف والمنفذ والمسار الحالي.
كل من هؤلاء المساعدين لديه مساعد ‎<code>_url</code> مقابل (مثل <code>photos_url</code>) الذي يعيد نفس المسار مسبوقًا ببادئة المضيف والمنفذ والمسار الحالي.


=== تحديد موارد متعددة في نفس الوقت ===
=== تحديد موارد متعددة في نفس الوقت ===
إذا كنت بحاجة إلى إنشاء مسارات توجيه لأكثر من مورد واحد، فيمكنك توفير جزء من الكتابة عن طريق تعريفهم جميعًا باستدعاءٍ واحدٍ إلى resources:
إذا كنت بحاجة إلى إنشاء مسارات توجيه لأكثر من مورد واحد، فيمكنك توفير جزء من الكتابة عن طريق تعريفهم جميعًا باستدعاءٍ واحدٍ إلى <code>resources</code>:<syntaxhighlight lang="rails">
 
resources :photos, :books, :videos
resources :photos, :books, :videos
</syntaxhighlight>هذا يعمل بالضبط بطريقة مشابهة للشيفرة التالية:<syntaxhighlight lang="rails">
 
هذا يعمل بالضبط بطريقة مشابهة للشيفرة التالية:
 
resources :photos
resources :photos
resources :books
resources :books
resources :videos
resources :videos
</syntaxhighlight>


=== الموارد الفردية ===
=== الموارد الفردية ===
في بعض الأحيان، يكون لديك مورد يبحث عنه العملاء دائمًا دون الإشارة إلى معرف ID. على سبيل المثال، ترغب في أن يعرض ‎/profile دائمًا ملف تعريف المستخدم الذي قام بتسجيل الدخول حاليًا. في هذه الحالة، يمكنك استخدام مورد مفرد لتعيين ‎/profile (بدلًا من ‎/profile/:id) إلى الإجراء show:
في بعض الأحيان، يكون لديك مورد يبحث عنه العملاء دائمًا دون الإشارة إلى معرف ID. على سبيل المثال، ترغب في أن يعرض ‎/profile دائمًا ملف تعريف المستخدم الذي قام بتسجيل الدخول حاليًا. في هذه الحالة، يمكنك استخدام مورد مفرد لتعيين ‎/profile (بدلًا من ‎/profile/:id) إلى الإجراء <code>show</code>:<syntaxhighlight lang="rails">
 
get 'profile', to: 'users#show'
get 'profile', to: 'users#show'
 
</syntaxhighlight>تمرير سلسلة نصية (String) إلى <code>to:‎</code> ستتوقع أن تكون بالتنسيق <code>controller#action</code>. عند استخدام [[Ruby/Symbol|رمز]] (Symbol)، يجب استبدال الخيار <code>to:</code>‎ بالقيمة <code>action:‎</code>. عند استخدام سلسلة نصية دون الرمز <code>#</code>، يجب استبدال الخيار <code>to:‎</code> بـ <code>controller:‎</code> بالشكل التالي:<syntaxhighlight lang="rails">
تمرير سلسلة نصية (String) إلى to:‎ ستتوقع أن تكون بالتنسيق controller#action. عند استخدام رمز (Symbol)، يجب استبدال الخيار to:‎ بالقيمة action:‎. عند استخدام سلسلة نصية دون الرمز #، يجب استبدال الخيار to:‎ بـ controller:‎ بالشكل التالي:
get 'profile', action: :show, controller: 'users'
 
</syntaxhighlight>هذا مسار موجه كثير المورد:<syntaxhighlight lang="rails">
get 'profile', action: :show, controller: 'users'
 
هذا مسار موجه كثير المورد:
 
resource :geocoder
resource :geocoder
resolve('Geocoder') { [:geocoder] }
resolve('Geocoder') { [:geocoder] }
 
</syntaxhighlight>يخلق ستة مسارات موجهة مختلفة في التطبيق الخاص بك كلها معيَّنة إلى وحدة التحكم <code>Geocoders</code>:
يخلق ستة مسارات موجهة مختلفة في التطبيق الخاص بك كلها معيَّنة إلى وحدة تحكم Geocoders:
{| class="wikitable"
{| class="wikitable"
|فعل HTTP
!فعل HTTP
|المسار
!المسار
|وحدة التحكم # الإجراء
!وحدة التحكم # الإجراء
|الإستخدامات
!الإستخدامات
|-
|-
|GET
|GET
|‎/geocoder/new
|‎/geocoder/new
|geocoders#new
|<code>geocoders#new</code>
|إرجاع نموذج HTML لإنشاء geocoder.
|إرجاع نموذج HTML لإنشاء geocoder.
|-
|-
|POST
|POST
|‎/geocoder
|‎/geocoder
|geocoders#create
|<code>geocoders#create</code>
|إنشاء geocoder جديد.
|إنشاء geocoder جديد.
|-
|-
|GET
|GET
|‎/geocoder
|‎/geocoder
|geocoders#show
|<code>geocoders#show</code>
|عرض مورد geocoder واحد و فقط.
|عرض مورد geocoder واحد و فقط.
|-
|-
|GET
|GET
|‎/geocoder/edit
|‎/geocoder/edit
|geocoders#edit
|<code>geocoders#edit</code>
|إرجاع نموذج HTML لتحرير geocoder.
|إرجاع نموذج HTML لتحرير geocoder.
|-
|-
|PATCH/PUT
|PATCH/PUT
|‎/geocoder
|‎/geocoder
|geocoders#update
|<code>geocoders#update</code>
|تحديث مورد geocoder واحد و فقط.
|تحديث مورد geocoder واحد و فقط.
|-
|-
|DELETE
|DELETE
|‎/geocoder
|‎/geocoder
|geocoders#destroy
|<code>geocoders#destroy</code>
|حذف مورد geocoder.
|حذف مورد geocoder.
|}
|}
ملاحظة: نظرًا لأنك قد ترغب في استخدام وحدة التحكم نفسها لمسار فريد (‎/account) ومسار الجمع (‎/accounts/45)، فإن الموارد الفردية ستخضع إلى وحدات تحكم الجمع. على سبيل المثال، المورد ‎:photo والموارد ‎:photos تنشئ مسارات توجيه مفرد ومجتمعة تعين لنفس وحدة التحكم (PhotosController).
'''ملاحظة''': نظرًا لأنك قد ترغب في استخدام وحدة التحكم نفسها لمسار فريد (‎/account) ومسار الجمع (‎/accounts/45)، فإن الموارد الفردية ستخضع إلى وحدات تحكم الجمع. على سبيل المثال، المورد ‎<code>:photo</code> والموارد <code>‎:photos</code> تنشئ مسارات توجيه مفرد ومجتمعة تعين لنفس وحدة التحكم (PhotosController).


يولّد المسار الموجه كثير المورد المفرد (singular resourceful route) هؤلاء المساعدين:
يولّد المسار الموجه كثير المورد المفرد (singular resourceful route) هؤلاء المساعدين:
* new_geocoder_path returns /geocoder/new
* <code>new_geocoder_path returns /geocoder/new</code>
* edit_geocoder_path returns /geocoder/edit
* <code>edit_geocoder_path returns /geocoder/edit</code>
* geocoder_path returns /geocoder
* <code>geocoder_path returns /geocoder</code>
كما هو الحال مع موارد الجمع، فإن نفس المساعدين الذين ينتهون في ‎_url سيتضمنون أيضًا بادئة المضيف والمنفذ والمسار.
كما هو الحال مع موارد الجمع، فإن نفس المساعدين الذين ينتهون في <code>‎_url</code> سيتضمنون أيضًا بادئة المضيف والمنفذ والمسار.


=== وحدة تحكم مجالات الأسماء والتوجيه ===
=== وحدة تحكم مجالات الأسماء والتوجيه ===
قد ترغب في تنظيم مجموعات من وحدات التحكم تحت مجال اسم (namespace). الأكثر شيوعًا، يمكنك تجميع عدد من وحدات التحكم الإدارية تحت مجال الاسم Admin::‎. يمكنك وضع وحدات التحكم هذه تحت دليل app/controllers/admin، ويمكنك تجميعها معًا في جهاز التوجيه:
قد ترغب في تنظيم مجموعات من وحدات التحكم تحت مجال اسم (namespace). الأكثر شيوعًا، يمكنك تجميع عدد من وحدات التحكم الإدارية تحت مجال الاسم <code>Admin::</code>‎. يمكنك وضع وحدات التحكم هذه تحت دليل app/controllers/admin، ويمكنك تجميعها معًا في جهاز التوجيه:<syntaxhighlight lang="rails">
 
namespace :admin do
namespace :admin do
 
  resources :articles, :comments
 resources :articles, :comments
end
 
</syntaxhighlight>سيؤدي ذلك إلى إنشاء عدد من المسارات لكل من وحدة التحكم في <code>articles</code> و <code>comments</code>. من أجل <code>Admin::ArticlesController</code>، ستنشئ ريلز:
End
 
سيؤدي ذلك إلى إنشاء عدد من المسارات لكل من وحدة التحكم في articles و comments. من أجل Admin::ArticlesController، ستنشئ Rails:
{| class="wikitable"
{| class="wikitable"
|فعل HTTP
!فعل HTTP
|المسار
!المسار
|وحدة التحكم # الإجراء
!وحدة التحكم # الإجراء
|مسمى المساعد
!مسمى المساعد
|-
|-
|GET
|GET
|‎/admin/articles
|‎/admin/articles
|admin/articles#index
|<code>admin/articles#index</code>
|admin_articles_path
|<code>admin_articles_path</code>
|-
|-
|GET
|GET
|‎/admin/articles/new
|‎/admin/articles/new
|admin/articles#new
|<code>admin/articles#new</code>
|new_admin_article_path
|<code>new_admin_article_path</code>
|-
|-
|POST
|POST
|‎/admin/articles
|‎/admin/articles
|admin/articles#create
|<code>admin/articles#create</code>
|admin_articles_path
|<code>admin_articles_path</code>
|-
|-
|GET
|GET
|‎/admin/articles/:id
|‎/admin/articles/:id
|admin/articles#show
|<code>admin/articles#show</code>
|admin_article_path(:id)‎
|<code>admin_article_path(:id)‎</code>
|-
|-
|GET
|GET
|‎/admin/articles/:id/edit
|‎/admin/articles/:id/edit
|admin/articles#edit
|<code>admin/articles#edit</code>
|edit_admin_article_path(:id)‎
|<code>edit_admin_article_path(:id)‎</code>
|-
|-
|PATCH/PUT
|PATCH/PUT
|‎/admin/articles/:id
|‎/admin/articles/:id
|admin/articles#update
|<code>admin/articles#update</code>
|admin_article_path(:id)‎
|<code>admin_article_path(:id)‎</code>
|-
|-
|DELETE
|DELETE
|‎/admin/articles/:id
|‎/admin/articles/:id
|admin/articles#destroy
|<code>admin/articles#destroy</code>
|admin_article_path(:id)‎
|<code>admin_article_path(:id)‎</code>
|}
|}
{| class="wikitable"
إذا كنت تريد توجيه ‎/articles (بدون البادئة ‎/admin) إلى <code>Admin::ArticlesController</code>، فيمكنك استخدام:<syntaxhighlight lang="rails">
|مسمى المساعد
|وحدة التحكم # الإجراء
|المسار
|فعل HTTP
|-
|admin_articles_path
|admin/articles#index
|/admin/articles
|GET
|-
|new_admin_article_path
|admin/articles#new
|/admin/articles/new
|GET
|-
|admin_articles_path
|admin/articles#create
|/admin/articles
|POST
|-
|admin_article_path(:id)
|admin/articles#show
|/admin/articles/:id
|GET
|-
|edit_admin_article_path(:id)
|admin/articles#edit
|/admin/articles/:id/edit
|GET
|-
|admin_article_path(:id)
|admin/articles#update
|/admin/articles/:id
|PATCH/PUT
|-
|admin_article_path(:id)
|admin/articles#destroy
|/admin/articles/:id
|DELETE
|}
إذا كنت تريد توجيه ‎/articles (بدون البادئة ‎/admin) إلى Admin::ArticlesController، فيمكنك استخدام:
 
scope module: 'admin' do
scope module: 'admin' do
 
  resources :articles, :comments
 resources :articles, :comments
 
end
end
 
</syntaxhighlight>أو في حالة واحدة:<syntaxhighlight lang="rails">
أو في حالة واحدة:
resources :articles, module: 'admin'
 
</syntaxhighlight>إذا كنت تريد توجيه ‎/admin/articles إلى <code>ArticlesController</code> (بدون بادئة الوحدة <code>Admin::‎</code>)، فيمكنك استخدام:<syntaxhighlight lang="rails">
resources :articles, module: 'admin'
 
إذا كنت تريد توجيه ‎/admin/articles إلى ArticlesController (بدون بادئة الوحدة Admin::‎)، فيمكنك استخدام:
 
scope '/admin' do
scope '/admin' do
 
  resources :articles, :comments
 resources :articles, :comments
 
end
end
 
</syntaxhighlight>أو في حالة واحدة:<syntaxhighlight lang="rails">
أو في حالة واحدة:
resources :articles, path: '/admin/articles'
 
</syntaxhighlight>في كل من هذه الحالات، تظل المسارات الموجهة المسماة كما هي إذا لم تستخدم النطاق (scope). في الحالة الأخيرة، تعيَّن المسارات التالية إلى <code>ArticlesController</code>:
resources :articles, path: '/admin/articles'
 
في كل من هذه الحالات، تظل المسارات الموجهة المسماة كما هي إذا لم تستخدم النطاق (scope). في الحالة الأخيرة، تعيَّن المسارات التالية إلى ArticlesController:
{| class="wikitable"
{| class="wikitable"
|فعل HTTP
!فعل HTTP
|المسار
!المسار
|وحدة التحكم # الإجراء
!وحدة التحكم # الإجراء
|مسمى المساعد
!مسمى المساعد
|-
|-
|GET
|GET
|‎/admin/articles
|‎/admin/articles
|articles#index
|<code>articles#index</code>
|articles_path
|<code>articles_path</code>
|-
|-
|GET
|GET
|‎/admin/articles/new
|‎/admin/articles/new
|articles#new
|<code>articles#new</code>
|new_article_path
|<code>new_article_path</code>
|-
|-
|POST
|POST
|‎/admin/articles
|‎/admin/articles
|articles#create
|<code>articles#create</code>
|articles_path
|<code>articles_path</code>
|-
|-
|GET
|GET
|‎/admin/articles/:id
|‎/admin/articles/:id
|articles#show
|<code>articles#show</code>
|article_path(:id)‎
|<code>article_path(:id)‎</code>
|-
|-
|GET
|GET
|‎/admin/articles/:id/edit
|‎/admin/articles/:id/edit
|articles#edit
|<code>articles#edit</code>
|edit_article_path(:id)‎
|<code>edit_article_path(:id)‎</code>
|-
|-
|PATCH/PUT
|PATCH/PUT
|‎/admin/articles/:id
|‎/admin/articles/:id
|articles#update
|<code>articles#update</code>
|article_path(:id)‎
|<code>article_path(:id)‎</code>
|-
|-
|DELETE
|DELETE
|‎/admin/articles/:id
|‎/admin/articles/:id
|articles#destroy
|<code>articles#destroy</code>
|article_path(:id)‎
|<code>article_path(:id)‎</code>
|}
|}
ملاحظة: إذا كنت بحاجة إلى استخدام مجال اسم وحدة تحكم (controller namespace) مختلف داخل كتلة مجال الاسم (namespace block)، فيمكنك تحديد مسار جهاز تحكم مطلق، مثل: get '/foo' => '/foo#index'‎.
'''ملاحظة''': إذا كنت بحاجة إلى استخدام مجال اسم وحدة تحكم (controller namespace) مختلف داخل كتلة مجال الاسم (namespace block)، فيمكنك تحديد مسار جهاز تحكم مطلق، مثل: <code>get '/foo' => '/foo#index'</code>‎.


=== الموارد المتداخلة ===
=== الموارد المتداخلة ===
من الشائع أن يكون لديك موارد منطقية للفرع childern من الموارد الأخرى. على سبيل المثال، لنفترض أن تطبيقك يتضمن هذه النماذج:
من الشائع أن يكون لديك موارد منطقية للفرع childern من الموارد الأخرى. على سبيل المثال، لنفترض أن تطبيقك يتضمن هذه النماذج:<syntaxhighlight lang="rails">
 
class Magazine < ApplicationRecord
class Magazine < ApplicationRecord
 
  has_many :ads
 has_many :ads
 
end
end
 
class Ad < ApplicationRecord
class Ad < ApplicationRecord
 
  belongs_to :magazine
 belongs_to :magazine
end
 
</syntaxhighlight>تتيح لك المسارات المتداخلة التقاط هذه العلاقة في التوجيه الخاص بك. في هذه الحالة، يمكنك تضمين إعلان المسار هذا:<syntaxhighlight lang="rails">
End
 
تتيح لك المسارات المتداخلة التقاط هذه العلاقة في التوجيه الخاص بك. في هذه الحالة، يمكنك تضمين إعلان المسار هذا:
 
resources :magazines do
resources :magazines do
 
  resources :ads
 resources :ads
 
end
end
 
</syntaxhighlight>بالإضافة إلى المسارات الموجهة للمجلات (magazines)، سيوجه هذا الإعلان أيضًا الإعلانات إلى <code>AdsController</code>. تتطلب عناوين URL للإعلان عن مجلة:
بالإضافة إلى المسارات الموجهة للمجلات (magazines)، سيوجه هذا الإعلان أيضًا الإعلانات إلى AdsController. تتطلب عناوين URL للإعلان عن مجلة:
{| class="wikitable"
{| class="wikitable"
|فعل HTTP
!فعل HTTP
|المسار
!المسار
|وحدة التحكم # الإجراء
!وحدة التحكم # الإجراء
|الاستخدامات
!الاستخدامات
|-
|-
|GET
|GET
|‎/magazines/:magazine_id/ads
|‎/magazines/:magazine_id/ads
|ads#index
|<code>ads#index</code>
|عرض قائمة بجميع الإعلانات لمجلة محددة.
|عرض قائمة بجميع الإعلانات لمجلة محددة.
|-
|-
|GET
|GET
|‎/magazines/:magazine_id/ads/new
|‎/magazines/:magazine_id/ads/new
|ads#new
|<code>ads#new</code>
|إرجاع نموذج HTML لإنشاء إعلان جديد ينتمي إلى مجلة معينة.
|إرجاع نموذج HTML لإنشاء إعلان جديد ينتمي إلى مجلة معينة.
|-
|-
|POST
|POST
|‎/magazines/:magazine_id/ads
|‎/magazines/:magazine_id/ads
|ads#create
|<code>ads#create</code>
|إنشاء إعلان جديد ينتمي إلى مجلة محددة.
|إنشاء إعلان جديد ينتمي إلى مجلة محددة.
|-
|-
|GET
|GET
|‎/magazines/:magazine_id/ads/:id
|‎/magazines/:magazine_id/ads/:id
|ads#show
|<code>ads#show</code>
|عرض إعلان معين ينتمي إلى مجلة محددة.
|عرض إعلان معين ينتمي إلى مجلة محددة.
|-
|-
|GET
|GET
|‎/magazines/:magazine_id/ads/:id/edit
|‎/magazines/:magazine_id/ads/:id/edit
|ads#edit
|<code>ads#edit</code>
|إرجاع نموذج HTML لتحرير إعلان ينتمي إلى مجلة معينة.
|إرجاع نموذج HTML لتحرير إعلان ينتمي إلى مجلة معينة.
|-
|-
|PATCH/PUT
|PATCH/PUT
|‎/magazines/:magazine_id/ads/:id
|‎/magazines/:magazine_id/ads/:id
|ads#update
|<code>ads#update</code>
|تحديث إعلان معين ينتمي إلى مجلة محددة.
|تحديث إعلان معين ينتمي إلى مجلة محددة.
|-
|-
|DELETE
|DELETE
|‎/magazines/:magazine_id/ads/:id
|‎/magazines/:magazine_id/ads/:id
|ads#destroy
|<code>ads#destroy</code>
|حذف إعلان معين ينتمي إلى مجلة محددة.
|حذف إعلان معين ينتمي إلى مجلة محددة.
|}
|}
سيؤدي هذا أيضًا إلى إنشاء مساعدين للتوجيه مثل magazine_ads_url و edit_magazine_ad_path. يأخذ هؤلاء المساعدون نسخة للمجلة كأول معامل (magazine_ads_url(@magazine)‎).
سيؤدي هذا أيضًا إلى إنشاء مساعدين للتوجيه مثل <code>magazine_ads_url</code> و <code>edit_magazine_ad_path</code>. يأخذ هؤلاء المساعدون نسخة للمجلة كأول معامل <code>(magazine_ads_url(@magazine)‎)</code>.


==== حدود التداخل ====
==== حدود التداخل ====
يمكنك أن تشعِّب الموارد ضمن الموارد المتشعبة الأخرى إذا أردت ذلك. فمثلًا:
يمكنك أن تشعِّب الموارد ضمن الموارد المتشعبة الأخرى إذا أردت ذلك. فمثلًا:<syntaxhighlight lang="rails">
 
resources :publishers do
resources :publishers do
 
  resources :magazines do
 resources :magazines do
    resources :photos
 
  end
   resources :photos
end
 
</syntaxhighlight>تصبح الموارد المتداخلة بعمق بطيئة. في هذه الحالة مثلًا، سيتعرف التطبيق على مسارات مثل:<syntaxhighlight lang="rails">
 end
 
End
 
تصبح الموارد المتداخلة بعمق بطيئة. في هذه الحالة مثلًا، سيتعرف التطبيق على مسارات مثل:
 
/publishers/1/magazines/2/photos/3
/publishers/1/magazines/2/photos/3
 
</syntaxhighlight>سيكون مساعد المسار المقابل هو <code>publisher_magazine_photo_url</code>، مما يتطلب منك تحديد كائنات على جميع المستويات الثلاثة. في الواقع، هذا الوضع مربكًا بما فيه الكفاية، إذ يقترح جيمس باك (Jamis Buck) في مقالة شائعة له قاعدةً أساسيةً لتصميم ريلز بشكل جيد: " لا ينبغي أبدًا أن تتداخل الموارد أكثر من 1 مستوى عميق."
سيكون مساعد المسار المقابل هو publisher_magazine_photo_url، مما يتطلب منك تحديد كائنات على جميع المستويات الثلاثة. في الواقع، هذا الوضع مربكًا بما فيه الكفاية، إذ يقترح جيمس باك (Jamis Buck) في مقالة شائعة له قاعدةً أساسيةً لتصميم Rails بشكل جيد: " لا ينبغي أبدًا أن تتداخل الموارد أكثر من 1 مستوى عميق."


==== التداخل الضحل ====
==== التداخل الضحل ====
تتمثل إحدى طرق تجنب التداخل العميق (كما هو موصى به أعلاه) في إنشاء إجراءات المجموعة المحددة ضمن الأصل parent، وذلك للحصول على إحساس بالتسلسل الهرمي hierarchy ولعدم تداخل إجراءات العضو. بعبارة أخرى، لإنشاء مسارات فقط مع الحد الأدنى من المعلومات لتحديد المورد بشكل فريد، مثل هذا:
تتمثل إحدى طرق تجنب التداخل العميق (كما هو موصى به أعلاه) في إنشاء إجراءات المجموعة المحددة ضمن الأصل (parent)، وذلك للحصول على إحساس بالتسلسل الهرمي (hierarchy) ولعدم تداخل إجراءات العضو. بعبارة أخرى، لإنشاء مسارات فقط مع الحد الأدنى من المعلومات لتحديد المورد بشكل فريد، مثل هذا:<syntaxhighlight lang="rails">
 
resources :articles do
resources :articles do
 
  resources :comments, only: [:index, :new, :create]
<nowiki> resources :comments, only: [:index, :new, :create]</nowiki>
 
end
end
 
resources :comments, only: [:show, :edit, :update, :destroy]
<nowiki>resources :comments, only: [:show, :edit, :update, :destroy]</nowiki>
</syntaxhighlight>تحقق هذه الفكرة توازنًا بين المسارات الوصفية والتداخل العميق. توجد صيغة مختصرة لتحقيق ذلك، عبر الخيار <code>‎:shallow</code>:<syntaxhighlight lang="rails">
 
تحقق هذه الفكرة توازنًا بين المسارات الوصفية والتداخل العميق. توجد صيغة مختصرة لتحقيق ذلك، عبر الخيار ‎:shallow:
 
resources :articles do
resources :articles do
 
  resources :comments, shallow: true
 resources :comments, shallow: true
 
end
end
 
</syntaxhighlight>سيؤدي ذلك إلى إنشاء نفس المسارات بالضبط مثل المثال الأول. يمكنك أيضًا تحديد الخيار <code>‎:shallow</code> في المورد الرئيسي <code>parent</code>، وفي هذه الحالة ستكون جميع الموارد المتداخلة ضحلة:<syntaxhighlight lang="rails">
سيؤدي ذلك إلى إنشاء نفس المسارات بالضبط مثل المثال الأول. يمكنك أيضًا تحديد الخيار ‎:shallow في المورد الرئيسي parent، وفي هذه الحالة ستكون جميع الموارد المتداخلة ضحلة:
 
resources :articles, shallow: true do
resources :articles, shallow: true do
 
  resources :comments
 resources :comments
  resources :quotes
 
  resources :drafts
 resources :quotes
 
 resources :drafts
 
end
end
 
</syntaxhighlight>التابع الضحل <code>shallow</code> الذي يخص DSL يخلق مجالًا داخليًا يكون كل تداخل فيه ضحلًا. هذا ينشئ نفس المسارات الموجهة مثل المثال السابق:<syntaxhighlight lang="rails">
التابع الضحل shallow الذي يخص DSL يخلق مجالًا داخليًا يكون كل تداخل فيه ضحلًا. هذا ينشئ نفس المسارات الموجهة مثل المثال السابق:
 
shallow do
shallow do
 
  resources :articles do
 resources :articles do
    resources :comments
 
    resources :quotes
   resources :comments
    resources :drafts
 
  end
   resources :quotes
 
   resources :drafts
 
 end
 
end
end
 
</syntaxhighlight>هناك خياران للنطاق (scope) لتخصيص المسارات الموجهة الضحلة. البادئات <code>‎:shallow_path</code> لمسارات العضو مع المعامل المحدد:<syntaxhighlight lang="rails">
هناك خياران للنطاق (scope) لتخصيص المسارات الموجهة الضحلة. البادئات ‎:shallow_path لمسارات العضو مع المعامل المحدد:
 
scope shallow_path: "sekret" do
scope shallow_path: "sekret" do
 
  resources :articles do
 resources :articles do
    resources :comments, shallow: true
 
  end
   resources :comments, shallow: true
 
 end
 
end
end
 
</syntaxhighlight>يحتوي مورد التعليقات هنا على المسارات التالية التي أنشئت له:
يحتوي مورد التعليقات هنا على المسارات التالية التي أنشئت له:
{| class="wikitable"
{| class="wikitable"
|فعل HTTP
!فعل HTTP
|المسار
!المسار
|وحدة التحكم# الإجراء
!وحدة التحكم# الإجراء
|مسمى المساعد
!مسمى المساعد
|-
|-
|GET
|GET
|‎/articles/:article_id/comments(.:format)‎
|‎/articles/:article_id/comments(.:format)‎
|comments#index
|<code>comments#index</code>
|article_comments_path
|<code>article_comments_path</code>
|-
|-
|POST
|POST
|‎/articles/:article_id/comments(.:format)‎
|‎/articles/:article_id/comments(.:format)‎
|comments#create
|<code>comments#create</code>
|article_comments_path
|<code>article_comments_path</code>
|-
|-
|GET
|GET
|‎/articles/:article_id/comments/new(.:format)‎
|‎/articles/:article_id/comments/new(.:format)‎
|comments#new
|<code>comments#new</code>
|new_article_comment_path
|<code>new_article_comment_path</code>
|-
|-
|GET
|GET
|‎/sekret/comments/:id/edit(.:format)‎
|‎/sekret/comments/:id/edit(.:format)‎
|comments#edit
|<code>comments#edit</code>
|edit_comment_path
|<code>edit_comment_path</code>
|-
|-
|GET
|GET
|‎/sekret/comments/:id(.:format)‎
|‎/sekret/comments/:id(.:format)‎
|comments#show
|<code>comments#show</code>
|comment_path
|<code>comment_path</code>
|-
|-
|PATCH/PUT
|PATCH/PUT
|‎/sekret/comments/:id(.:format)‎
|‎/sekret/comments/:id(.:format)‎
|comments#update
|<code>comments#update</code>
|comment_path
|<code>comment_path</code>
|-
|-
|
|DELETE
|‎/sekret/comments/:id(.:format)‎
|‎/sekret/comments/:id(.:format)‎
|comments#destroy
|<code>comments#destroy</code>
|comment_path
|<code>comment_path</code>
|}
|}
الخيار ‎:shallow_prefix يضيف المعامل المحدد للمساعدين المسمايين:
الخيار <code>‎:shallow_prefix</code> يضيف المعامل المحدد للمساعدين المسمايين:<syntaxhighlight lang="rails">
 
scope shallow_prefix: "sekret" do
scope shallow_prefix: "sekret" do
 
  resources :articles do
 resources :articles do
    resources :comments, shallow: true
 
  end
   resources :comments, shallow: true
 
 end
 
end
end
 
</syntaxhighlight>يحتوي مورد التعليقات هنا على المسارات الموجهة التالية التي أنشئت له:
يحتوي مورد التعليقات هنا على المسارات الموجهة التالية التي أنشئت له:
{| class="wikitable"
{| class="wikitable"
|فعل HTTP
!فعل HTTP
|المسار
!المسار
|وحدة التحكم# الإجراء
!وحدة التحكم# الإجراء
|مسمى المساعد
!مسمى المساعد
|-
|-
|GET
|GET
|‎/articles/:article_id/comments(.:format)‎
|‎/articles/:article_id/comments(.:format)‎
|comments#index
|<code>comments#index</code>
|article_comments_path
|<code>article_comments_path</code>
|-
|-
|POST
|POST
|‎/articles/:article_id/comments(.:format)‎
|‎/articles/:article_id/comments(.:format)‎
|comments#create
|<code>comments#create</code>
|article_comments_path
|<code>article_comments_path</code>
|-
|-
|GET
|GET
|‎/articles/:article_id/comments/new(.:format)‎
|‎/articles/:article_id/comments/new(.:format)‎
|comments#new
|<code>comments#new</code>
|new_article_comment_path
|<code>new_article_comment_path</code>
|-
|-
|GET
|GET
|‎/comments/:id/edit(.:format)‎
|‎/comments/:id/edit(.:format)‎
|comments#edit
|<code>comments#edit</code>
|edit_sekret_comment_path
|<code>edit_sekret_comment_path</code>
|-
|-
|GET
|GET
|‎/comments/:id(.:format)‎
|‎/comments/:id(.:format)‎
|comments#show
|<code>comments#show</code>
|sekret_comment_path
|<code>sekret_comment_path</code>
|-
|-
|PATCH/PUT
|PATCH/PUT
|‎/comments/:id(.:format)‎
|‎/comments/:id(.:format)‎
|comments#update
|<code>comments#update</code>
|sekret_comment_path
|<code>sekret_comment_path</code>
|-
|-
|DELETE
|DELETE
|‎/comments/:id(.:format)‎
|‎/comments/:id(.:format)‎
|comments#destroy
|<code>comments#destroy</code>
|sekret_comment_path
|<code>sekret_comment_path</code>
|}
|}


=== اهتمامات التوجيه ===
=== اهتمامات التوجيه ===
تسمح لك اهتمامات التوجيه (Routing concerns) بالإعلان عن المسارات الموجهة الشائعة التي يمكن إعادة استخدامها داخل الموارد والمسارات الأخرى. ألق نظرة على الشيفرة التالي لمعرفة كيفية تعريف اهتمام concern:
تسمح لك اهتمامات التوجيه (Routing concerns) بالإعلان عن المسارات الموجهة الشائعة التي يمكن إعادة استخدامها داخل الموارد والمسارات الأخرى. ألق نظرة على الشيفرة التالي لمعرفة كيفية تعريف اهتمام <code>concern</code>:<syntaxhighlight lang="rails">
 
concern :commentable do
concern :commentable do
 
  resources :comments
 resources :comments
 
end
end
 
concern :image_attachable do
concern :image_attachable do
 
  resources :images, only: :index
 resources :images, only: :index
 
end
end
 
</syntaxhighlight>يمكن استخدام هذه الاهتمامات <code>concern</code> في الموارد لتجنب تكرار الرموز ومشاركة السلوك عبر المسارات:<syntaxhighlight lang="rails">
يمكن استخدام هذه الاهتمامات concern في الموارد لتجنب تكرار الرموز ومشاركة السلوك عبر المسارات:
 
resources :messages, concerns: :commentable
resources :messages, concerns: :commentable
 
<nowiki>resources :articles, concerns: [:commentable, :image_attachable]</nowiki>
resources :articles, concerns: [:commentable, :image_attachable]
 
</syntaxhighlight>ما ورد أعلاه يعادل ما يلي:<syntaxhighlight lang="rails">
ما ورد أعلاه يعادل ما يلي:
 
resources :messages do
resources :messages do
 
  resources :comments
 resources :comments
 
end
end
 
resources :articles do
resources :articles do
 
  resources :comments
 resources :comments
  resources :images, only: :index
 
 resources :images, only: :index
 
end
end
 
</syntaxhighlight>كما يمكنك استخدامها في أي مكان تريده داخل المسارات الموجهة، مثل في استدعاء نطاق (scope) أو مجال أسماء (namespace):<syntaxhighlight lang="rails">
كما يمكنك استخدامها في أي مكان تريده داخل المسارات الموجهة، مثل في استدعاء نطاق (scope) أو مجال أسماء (namespace):
 
namespace :articles do
namespace :articles do
 
  concerns :commentable
 concerns :commentable
 
end
end
</syntaxhighlight>


=== إنشاء مسارات وعناوين URL من الكائنات ===
=== إنشاء مسارات وعناوين URL من الكائنات ===
بالإضافة إلى استخدام مساعدين التوجيه، تستطيع Rails أيضًا إنشاء مسارات وعناوين URL من مصفوفة من المعاملات. على سبيل المثال، لنفترض أن لديك مجموعة المسارات الموجهة التالية:
بالإضافة إلى استخدام مساعدين التوجيه، تستطيع Rails أيضًا إنشاء مسارات وعناوين URL من مصفوفة من المعاملات. على سبيل المثال، لنفترض أن لديك مجموعة المسارات الموجهة التالية:<syntaxhighlight lang="rails">
 
resources :magazines do
resources :magazines do
 
  resources :ads
 resources :ads
 
end
end
 
</syntaxhighlight>عند استخدام <code>magazine_ad_path</code>، يمكنك تمرير نسخ من <code>Magazine</code> و <code>Ad</code> بدلًا من المعرفات الرقمية <code>IDs</code>:<syntaxhighlight lang="rails">
عند استخدام magazine_ad_path، يمكنك تمرير نسخ من Magazine و Ad بدلًا من المعرفات الرقمية IDs:
 
<%= link_to 'Ad details', magazine_ad_path(@magazine, @ad) %>
<%= link_to 'Ad details', magazine_ad_path(@magazine, @ad) %>
 
</syntaxhighlight>يمكنك أيضًا استخدام <code>url_for</code> مع مجموعة من الكائنات، وسوف تحدد ريلز المسار الموجهة الذي تريده تلقائيًا:<syntaxhighlight lang="rails">
يمكنك أيضًا استخدام url_for مع مجموعة من الكائنات، وسوف تحدد Rails المسار الموجهة الذي تريده تلقائيًا:
 
<%= link_to 'Ad details', url_for([@magazine, @ad]) %>
<%= link_to 'Ad details', url_for([@magazine, @ad]) %>
 
</syntaxhighlight>في هذه الحالة، سترى ريلز أن <code>magazine@</code> هو <code>Magazine</code> و <code>ad@</code> هو <code>Ad</code> وبالتالي ستستخدم المساعد <code>magazine_ad_path</code>. في المساعدين مثل <code>link_to</code>، يمكنك تحديد الكائن بدلًا من استدعاء <code>url_for</code> بالكامل:<syntaxhighlight lang="rails">
في هذه الحالة، سترى Rails أن magazine@ هو Magazine و ad@ هو Ad وبالتالي ستستخدم المساعد magazine_ad_path. في المساعدين مثل link_to، يمكنك تحديد الكائن بدلًا من استدعاء url_for بالكامل:
 
<%= link_to 'Ad details', [@magazine, @ad] %>
<%= link_to 'Ad details', [@magazine, @ad] %>
 
</syntaxhighlight>إذا كنت تريد الارتباط بمجلة فقط:<syntaxhighlight lang="rails">
إذا كنت تريد الارتباط بمجلة فقط:
 
<%= link_to 'Magazine details', @magazine %>
<%= link_to 'Magazine details', @magazine %>
 
</syntaxhighlight>بالنسبة إلى الإجراءات الأخرى، تحتاج فقط إلى إدراج اسم الإجراء باعتباره العنصر الأول في المصفوفة:<syntaxhighlight lang="rails">
بالنسبة إلى الإجراءات الأخرى، تحتاج فقط إلى إدراج اسم الإجراء باعتباره العنصر الأول في المصفوفة:
 
<%= link_to 'Edit Ad', [:edit, @magazine, @ad] %>
<%= link_to 'Edit Ad', [:edit, @magazine, @ad] %>
 
</syntaxhighlight>يتيح لك ذلك التعامل مع نسخ النماذج الخاصة بك كعناوين URL، وهي ميزة أساسية لاستخدام النمط كثير المورد.
يتيح لك ذلك التعامل مع نسخ النماذج الخاصة بك كعناوين URL، وهي ميزة أساسية لاستخدام النمط كثير المورد.


=== إضافة المزيد من الإجراءات RESTful ===
=== إضافة المزيد من الإجراءات RESTful ===
سطر 686: سطر 514:


==== إضافة مسارات الأعضاء ====
==== إضافة مسارات الأعضاء ====
لإضافة مسار موجه عضو، ما عليك سوى إضافة الكتلة member إلى كتلة الموارد resource:
لإضافة مسار موجه عضو، ما عليك سوى إضافة الكتلة <code>member</code> إلى كتلة الموارد <code>resource</code>:<syntaxhighlight lang="rails">
 
resources :photos do
resources :photos do
 
  member do
 member do
    get 'preview'
 
  end
   get 'preview'
 
 end
 
end
end
</syntaxhighlight>سيتعرف هذا على ‎/photos/1/preview مع GET، ويوجهه إلى الإجراء <code>preview</code> الذي يخص <code>PhotosController</code>، مع تمرير قيمة معرف المورد <code>id</code> في المعاملات <code>[‎:id]</code>. سيؤدي أيضًا إلى إنشاء <code>photos_preview_url</code> والمساعدين <code>photo_preview_path</code>.


سيتعرف هذا على ‎/photos/1/preview مع GET، ويوجهه إلى الإجراء preview الذي يخص PhotosController، مع تمرير قيمة معرف المورد id في المعاملات [‎:id]. سيؤدي أيضًا إلى إنشاء photos_preview_url والمساعدين photo_preview_path.
ضمن كتلة مسارات الأعضاء الموجهة، كل اسم مسار (route name) يحدد فعل HTTP سيُتعرَّف عليه. يمكنك استخدام get أو patch أو put أو post أو delete هنا. إذا لم يكن لديك العديد من مسارات الأعضاء الموجهة، فيمكنك أيضًا تمرير <code>‎:on</code> إلى المسار، وإلغاء الكتلة:<syntaxhighlight lang="rails">
 
ضمن كتلة مسارات الأعضاء الموجهة، كل اسم مسار (route name) يحدد فعل HTTP سيُتعرَّف عليه. يمكنك استخدام get أو patch أو put أو post أو delete هنا. إذا لم يكن لديك العديد من مسارات الأعضاء الموجهة، فيمكنك أيضًا تمرير ‎:on إلى المسار، وإلغاء الكتلة:
 
resources :photos do
resources :photos do
 
  get 'preview', on: :member
 get 'preview', on: :member
 
end
end
 
</syntaxhighlight>يمكنك ترك الخيار <code>‎:on</code>، إذ سيؤدي ذلك إلى إنشاء نفس مسار العضو باستثناء أن قيمة معرف المورد <code>id</code> ستكون متاحة في <code>[params[:photo_id</code> بدلًا من <code>[params[:id</code>.
يمكنك ترك الخيار ‎:on، إذ سيؤدي ذلك إلى إنشاء نفس مسار العضو باستثناء أن قيمة معرف المورد id ستكون متاحة في [params[:photo_id بدلًا من [params[:id.


==== إضافة مسارات التجميع ====
==== إضافة مسارات التجميع ====
لإضافة مسار موجه إلى المجموعة:
لإضافة مسار موجه إلى المجموعة:<syntaxhighlight lang="rails">
 
resources :photos do
resources :photos do
 
  collection do
 collection do
    get 'search'
 
  end
   get 'search'
 
 end
 
end
end
</syntaxhighlight>سيؤدي هذا إلى تمكين ريلز للتعرف على مسارات مثل ‎/photos/search باستخدام GET، والتوجيه إلى الإجراء <code>search</code> الذي يخص <code>PhotosController</code>. سيؤدي أيضًا إلى إنشاء مساعدي التوجيه <code>search_photos_url</code> و <code>search_photos_path</code>.


سيؤدي هذا إلى تمكين Rails للتعرف على مسارات مثل ‎/photos/search باستخدام GET، والتوجيه إلى الإجراء search الذي يخص PhotosController. سيؤدي أيضًا إلى إنشاء مساعدي التوجيه search_photos_url و search_photos_path.
كما هو الحال مع توجيهات الأعضاء (member routes)، يمكنك تمرير <code>‎:on</code> إلى توجيه بالشكل التالي:<syntaxhighlight lang="rails">
 
كما هو الحال مع توجيهات الأعضاء (member routes)، يمكنك تمرير ‎:on إلى توجيه بالشكل التالي:
 
resources :photos do
resources :photos do
 
  get 'search', on: :collection
 get 'search', on: :collection
 
end
end
</syntaxhighlight>


==== إضافة توجيهات لإجراءات جديدة إضافية ====
==== إضافة توجيهات لإجراءات جديدة إضافية ====
يمكن إضافة إجراء جديد بديل باستخدام الاختصار ‎:on بالشكل التالي:
يمكن إضافة إجراء جديد بديل باستخدام الاختصار ‎:on بالشكل التالي:<syntaxhighlight lang="rails">
 
resources :comments do
resources :comments do
 
  get 'preview', on: :new
 get 'preview', on: :new
 
end
end
</syntaxhighlight>سيؤدي هذا إلى تمكين ريلز للتعرف على مسارات مثل ‎/comments/new/preview باستخدام GET، وتوجيهها إلى الإجراء <code>preview</code> الذي يخص <code>CommentController</code>. سيؤدي أيضًا إلى إنشاء مساعدي التوجيه <code>preview_new_comment_url</code> و <code>preview_new_comment_path</code>.


سيؤدي هذا إلى تمكين Rails للتعرف على مسارات مثل ‎/comments/new/preview باستخدام GET، وتوجيهها إلى الإجراء preview الذي يخص CommentController. سيؤدي أيضًا إلى إنشاء مساعدي التوجيه preview_new_comment_url و preview_new_comment_path.
'''فائدة''': إذا وجدت نفسك تضيف العديد من الإجراءات الإضافية إلى مسار موجه ذي أهمية، فقد حان الوقت للتوقف وسؤال نفسك ما إذا كنت تموه عن وجود مورد آخر.
 
فائدة: إذا وجدت نفسك تضيف العديد من الإجراءات الإضافية إلى مسار موجه ذي أهمية، فقد حان الوقت للتوقف وسؤال نفسك ما إذا كنت تموه عن وجود مورد آخر.


== المسارات الموجهة غير كثيرة المورد (Non-Resourceful) ==
== المسارات الموجهة غير كثيرة المورد (Non-Resourceful) ==
بالإضافة إلى توجيه الموارد، تتمتع Rails بدعم قوي لتوجيه عناوين URL العشوائية إلى الإجراءات. هنا، لا يمكنك الحصول على مجموعات من التوجيهات التي تنشأ تلقائيًا من خلال توجيه الموارد. بدلاً من ذلك، يمكنك إعداد كل توجيه على حدة داخل تطبيقك.
بالإضافة إلى توجيه الموارد، تتمتع ريلز بدعم قوي لتوجيه عناوين URL العشوائية إلى الإجراءات. هنا، لا يمكنك الحصول على مجموعات من التوجيهات التي تنشأ تلقائيًا من خلال توجيه الموارد. بدلاً من ذلك، يمكنك إعداد كل توجيه على حدة داخل تطبيقك.


على الرغم من أنه يجب عليك عادة استخدام التوجيه كثير المورد (resourceful routing)، إلا أنه لا يزال هناك العديد من الأماكن التي يكون فيها التوجيه الأبسط أكثر ملاءمة. ليس هناك حاجة لمحاولة ارتداء كل جزء أخير من تطبيقك في إطار كثير المورد إذا لم يكن ذلك مناسبًا.
على الرغم من أنه يجب عليك عادة استخدام التوجيه كثير المورد (resourceful routing)، إلا أنه لا يزال هناك العديد من الأماكن التي يكون فيها التوجيه الأبسط أكثر ملاءمة. ليس هناك حاجة لمحاولة ارتداء كل جزء أخير من تطبيقك في إطار كثير المورد إذا لم يكن ذلك مناسبًا.


على وجه الخصوص، يجعل التوجيه البسيط من السهل جدًا تعيين عناوين URL القديمة لإجراءات Rails الجديدة.
على وجه الخصوص، يجعل التوجيه البسيط من السهل جدًا تعيين عناوين URL القديمة لإجراءات ريلز الجديدة.


=== المعاملات المقيدة ===
=== المعاملات المقيدة ===
عند إعداد مسار عادي، فإنك تقدم سلسلة من الرموز التي تحددها Rails إلى أجزاء من طلب HTTP الوارد. على سبيل المثال، ضع في اعتبارك هذا المسار الموجه:
عند إعداد مسار عادي، فإنك تقدم سلسلة من الرموز التي تحددها ريلز إلى أجزاء من طلب HTTP الوارد. على سبيل المثال، ضع في اعتبارك هذا المسار الموجه:<syntaxhighlight lang="rails">
 
get 'photos(/:id)', to: :display
get 'photos(/:id)', to: :display
</syntaxhighlight>إذا تمت معالجة طلب وارد من ‎/photos/1 من خلال هذا التوجيه (لأنه لم يطابق أي توجيه سابق في الملف)، فستكون النتيجة استدعاء الإجراء <code>display</code> الذي يخص <code>PhotosController</code>، ولجعل المعامل النهائي "1"متاحًا بالشكل <code>[params[:id</code>. سيقوم هذا التوجيه أيضًا بتوجيه الطلب الوارد ‎/photos إلى <code>DisplayController#display</code>، نظرًا لأن المُعرِّف <code>‎:id</code> هو مُعامل اختياري، يشار إليه بواسطة الأقواس.
 
إذا تمت معالجة طلب وارد من ‎/photos/1 من خلال هذا التوجيه (لأنه لم يطابق أي توجيه سابق في الملف)، فستكون النتيجة استدعاء الإجراء display الذي يخص PhotosController، ولجعل المعامل النهائي "1"متاحًا بالشكل [params[:id. سيقوم هذا التوجيه أيضًا بتوجيه الطلب الوارد ‎/photos إلى DisplayController#display، نظرًا لأن المُعرِّف ‎:id هو مُعامل اختياري، يشار إليه بواسطة الأقواس.


=== الأجزاء الديناميكية ===
=== الأجزاء الديناميكية ===
يمكنك إعداد العديد من الأجزاء الديناميكية (Dynamic Segments) ضمن مسار موجه عادي حسب رغبتك. سيكون أي جزء متاحًا للعمل كجزء من params. إذا أعددت المسار الموجه التالي:
يمكنك إعداد العديد من الأجزاء الديناميكية (Dynamic Segments) ضمن مسار موجه عادي حسب رغبتك. سيكون أي جزء متاحًا للعمل كجزء من <code>params</code>. إذا أعددت المسار الموجه التالي:<syntaxhighlight lang="rails">
 
get 'photos/:id/:user_id', to: 'photos#show'
get 'photos/:id/:user_id', to: 'photos#show'
</syntaxhighlight>سيرسل المسار الوارد ‎/photos/1/2 إلى الإجراء <code>show</code> الخاص بـ <code>[PhotosController.params [:id</code>. سيكون <code>params[:id]</code>‎ هو "1"، وسيكون <code>[params[:user_id</code> هو "2".


سيرسل المسار الوارد ‎/photos/1/2 إلى الإجراء show الخاص بـ [PhotosController.params [:id. سيكون params[:id]‎ هو "1"، وسيكون [params[:user_id هو "2".
'''فائدة''': بشكل افتراضي، لا تقبل الأجزاء الديناميكية النقاط، وهذا يرجع إلى استخدام النقطة كفاصل للمسارات الموجهة المنسقة. إذا كنت بحاجة إلى استخدام نقطة داخل جزء ديناميكي، أضف قيدًا يتجاوز هذا مثل <code>‎id: /[^\/]+/‎</code> الذي يسمح بأي شيء باستثناء الخط المستقيم المائل.
 
فائدة: بشكل افتراضي، لا تقبل الأجزاء الديناميكية النقاط، وهذا يرجع إلى استخدام النقطة كفاصل للمسارات الموجهة المنسقة. إذا كنت بحاجة إلى استخدام نقطة داخل جزء ديناميكي، أضف قيدًا يتجاوز هذا مثل ‎id: /[^\/]+/‎ الذي يسمح بأي شيء باستثناء الخط المستقيم المائل.


=== الأجزاء الثابتة ===
=== الأجزاء الثابتة ===
يمكنك تحديد الأجزاء الثابتة (Static Segments) عند إنشاء مسار موجه من خلال عدم إلحاق النقطتين بالجزء fragment:
يمكنك تحديد الأجزاء الثابتة (Static Segments) عند إنشاء مسار موجه من خلال عدم إلحاق النقطتين بالجزء fragment:<syntaxhighlight lang="rails">
 
get 'photos/:id/with_user/:user_id', to: 'photos#show'
get 'photos/:id/with_user/:user_id', to: 'photos#show'
</syntaxhighlight>يستجيب هذا المسار الموجه لمسارات مثل ‎/photos/1/with_user/2. في هذه الحالة، ستكون


يستجيب هذا المسار الموجه لمسارات مثل ‎/photos/1/with_user/2. في هذه الحالة، ستكون
المعاملات هي <code>{controller: 'photos'، action: 'show'، id: '1'، user_id: '2ٌ'‎}</code>.
 
المعاملات هي {controller: 'photos'، action: 'show'، id: '1'، user_id: '2ٌ'‎}.


=== سلسلة الاستعلام ===
=== سلسلة الاستعلام ===
ستشمل المعاملات أيضًا أي معاملات من سلسلة الاستعلام. على سبيل المثال، مع هذا المسار الموجه:
ستشمل المعاملات أيضًا أي معاملات من سلسلة الاستعلام. على سبيل المثال، مع هذا المسار الموجه:<syntaxhighlight lang="rails">
 
get 'photos/:id', to: 'photos#show'
get 'photos/:id', to: 'photos#show'
 
</syntaxhighlight>سيرسل المسار الوارد ‎/photos/1?user_id=2 إلى الإجراء <code>show</code> الخاص بوحدة تحكم <code>Photos</code>. إن <code>params</code> ستكون <code>{ controller: 'photos', action: 'show', id: '1', user_id: '2'‎ }</code>.
سيرسل المسار الوارد ‎/photos/1?user_id=2 إلى الإجراء show الخاص بوحدة تحكم Photos. إن params ستكون { controller: 'photos', action: 'show', id: '1', user_id: '2'‎ }.


=== تحديد الافتراضات ===
=== تحديد الافتراضات ===
يمكنك تحديد الإعدادات الافتراضية في المسار من خلال توفير تجزئة (hash) للخيار ‎:defaults. وينطبق هذا حتى على المعاملات التي لا تحددها كشرائح ديناميكية. فمثلًا:
يمكنك تحديد الإعدادات الافتراضية في المسار من خلال توفير تجزئة (hash) للخيار <code>‎:defaults</code>. وينطبق هذا حتى على المعاملات التي لا تحددها كشرائح ديناميكية. فمثلًا:<syntaxhighlight lang="rails">
 
get 'photos/:id', to: 'photos#show', defaults: { format: 'jpg' }
get 'photos/:id', to: 'photos#show', defaults: { format: 'jpg' }
</syntaxhighlight>تطابق ريلز المسار photos/12 مع الإجراء <code>show</code> الذي يخص <code>showController</code>، وتعين <code>params[:format]‎</code> إلى "jpg".


تطابق Rails المسار photos/12 مع الإجراء show الذي يخص showController، وتعين params[:format]‎ إلى "jpg".
يمكنك أيضًا استخدام <code>defaults</code> في تنسيق الكتلة لتحديد الإعدادات الافتراضية لعناصر متعددة:<syntaxhighlight lang="rails">
 
يمكنك أيضًا استخدام defaults في تنسيق الكتلة لتحديد الإعدادات الافتراضية لعناصر متعددة:
 
defaults format: :json do
defaults format: :json do
 
  resources :photos
 resources :photos
 
end
end
 
</syntaxhighlight>'''ملاحظة''': لا يمكنك إلغاء القيم الافتراضية عبر معاملات الاستعلام وهذا يعود لأسباب أمنية. القيم الافتراضية الوحيدة التي يمكن تجاوزها هي الأجزاء الديناميكية عن طريق استبدالها في مسار URL.
ملاحظة: لا يمكنك إلغاء القيم الافتراضية عبر معاملات الاستعلام وهذا يعود لأسباب أمنية. القيم الافتراضية  الوحيدة التي يمكن تجاوزها هي الأجزاء الديناميكية عن طريق استبدالها في مسار URL.


=== تسمية المسارات الموجهة ===
=== تسمية المسارات الموجهة ===
يمكنك تحديد اسم لأي مسار موجه باستخدام الخيار ‎:as:
يمكنك تحديد اسم لأي مسار موجه باستخدام الخيار ‎:as:<syntaxhighlight lang="rails">
get 'exit', to: 'sessions#destroy', as: :logout
</syntaxhighlight>سيؤدي ذلك إلى إنشاء <code>logout_path</code> و <code>logout_url</code> كمساعدين مسميين في تطبيقك. وسيؤدي استدعاء <code>loging_path</code> إلى إعادة ‎/exit.


get 'exit', to: 'sessions#destroy', as: :logout
يمكنك أيضًا استخدام هذا لتجاوز توابع التوجيه المحددة بواسطة الموارد كما يلي:<syntaxhighlight lang="rails">
 
get ':username', to: 'users#show', as: :user
سيؤدي ذلك إلى إنشاء logout_path و logout_url كمساعدين مسميين في تطبيقك. وسيؤدي استدعاء loging_path إلى إعادة ‎/exit.
</syntaxhighlight>سيحدد هذا التابع <code>user_path</code> الذي سيتاح في وحدات التحكم، والمساعدين والواجهات التي ستنتقل إلى مسار مثل ‎/bob. داخل الخيار <code>show</code> الخاص بـ <code>UsersController</code>، تحتوي <code>[params[:username</code> على اسم المستخدم للمستخدم. غير <code>‎:username</code> في تعريف المسار الموجه إذا كنت لا تريد أن يكون اسم المعامل <code>‎:username</code>.
 
يمكنك أيضًا استخدام هذا لتجاوز توابع التوجيه المحددة بواسطة الموارد كما يلي:
 
get ':username', to: 'users#show', as: :user
 
سيحدد هذا التابع user_path الذي سيتاح في وحدات التحكم، والمساعدين والواجهات التي ستنتقل إلى مسار مثل ‎/bob. داخل الخيار show الخاص بـ UsersController، تحتوي [params[:username على اسم المستخدم للمستخدم. غير ‎:username في تعريف المسار الموجه إذا كنت لا تريد أن يكون اسم المعامل ‎:username.


=== قيود فعل HTTP ===
=== قيود فعل HTTP ===
بشكل عام، يجب عليك استخدام التوابع get و post و put و patch و delete لتقييد توجيه إلى فعل معين. يمكنك استخدام التابع match مع الخيار ‎:via لمطابقة أفعال متعددة في وقت واحد:
بشكل عام، يجب عليك استخدام التوابع get و post و put و patch و delete لتقييد توجيه إلى فعل معين. يمكنك استخدام التابع <code>match</code> مع الخيار <code>‎:via</code> لمطابقة أفعال متعددة في وقت واحد:<syntaxhighlight lang="rails">
match 'photos', to: 'photos#show', via: [:get, :post]
</syntaxhighlight>يمكنك مطابقة جميع الأفعال إلى مسار معين باستخدام <code>via: :all</code> كما يلي:<syntaxhighlight lang="rails">
match 'photos', to: 'photos#show', via: :all
</syntaxhighlight>'''ملاحظة''': توجيه كل من طلبيات GET و POST إلى إجراء واحد له آثار متعلقة بالأمان. بشكل عام، يجب تجنب توجيه جميع الأفعال إلى أي إجراء ما لم يكن لديك سبب وجيه لذلك.


<nowiki>match 'photos', to: 'photos#show', via: [:get, :post]</nowiki>
'''ملاحظة''': لن تتحقق طلبية GET في ريلز من رمز CSRF (اختصار للعبارة cross-site request forgery، وهي الهجمات مُزوّرة الطلب عبر المواقع). يجب ألا تكتب أبدًا إلى قاعدة البيانات من طلبيات GET؛ لمزيد من المعلومات، انظر دليل الأمان الخاص بإجراءات CSRF المضادة.
 
يمكنك مطابقة جميع الأفعال إلى مسار معين باستخدام via: :all كما يلي:
 
match 'photos', to: 'photos#show', via: :all
 
ملاحظة: توجيه كل من طلبيات GET و POST إلى إجراء واحد له آثار متعلقة بالأمان. بشكل عام، يجب تجنب توجيه جميع الأفعال إلى أي إجراء ما لم يكن لديك سبب وجيه لذلك.
 
ملاحظة: لن تتحقق طلبية GET في Rails من رمز CSRF (اختصار للعبارة cross-site request forgery، وهي الهجمات مُزوّرة الطلب عبر المواقع). يجب ألا تكتب أبدًا إلى قاعدة البيانات من طلبيات GET؛ لمزيد من المعلومات، انظر دليل الأمان الخاص بإجراءات CSRF المضادة.


=== قيود الجزء (Segment Constraints) ===
=== قيود الجزء (Segment Constraints) ===
يمكنك استخدام الخيار ‎:constraints لفرض تنسيق لجزء ديناميكي بالشكل التالي:
يمكنك استخدام الخيار <code>‎:constraints</code> لفرض تنسيق لجزء ديناميكي بالشكل التالي:<syntaxhighlight lang="rails">
 
get 'photos/:id', to: 'photos#show', constraints: { id: /[A-Z]\d{5}/ }
get 'photos/:id', to: 'photos#show', constraints: { id: /[A-Z]\d{5}/ }
 
</syntaxhighlight>يطابق هذا المسار الموجه مسارات مثل ‎/photos/A12345، ولكن ليس ‎/photos/893. يمكنك التعبير بشكل أكثر دقة عن نفس التوجيه بهذه الطريقة:<syntaxhighlight lang="rails">
يطابق هذا المسار الموجه مسارات مثل ‎/photos/A12345، ولكن ليس ‎/photos/893. يمكنك التعبير بشكل أكثر دقة عن نفس التوجيه بهذه الطريقة:
 
get 'photos/:id', to: 'photos#show', id: /[A-Z]\d{5}/
get 'photos/:id', to: 'photos#show', id: /[A-Z]\d{5}/
 
</syntaxhighlight>تأخذ ‎<code>:constraints</code> تعبيرات نمطية مع القيود التي لا يمكن أن تستخدم مثبتات التعبير النمطي (regexp anchors). على سبيل المثال، لن يعمل التوجيه التالي:<syntaxhighlight lang="rails">
تأخذ ‎:constraints تعبيرات نمطية مع القيود التي لا يمكن أن تستخدم مثبتات التعبير النمطي (regexp anchors). على سبيل المثال، لن يعمل التوجيه التالي:
 
get '/:id', to: 'articles#show', constraints: { id: /^\d/ }
get '/:id', to: 'articles#show', constraints: { id: /^\d/ }
</syntaxhighlight>ومع ذلك، لاحظ أنك لست بحاجة إلى استخدام نقاط تثبيت لأن جميع المسارات الموجهة المثبتة في البداية.


ومع ذلك، لاحظ أنك لست بحاجة إلى استخدام نقاط تثبيت لأن جميع المسارات الموجهة المثبتة في البداية.
على سبيل المثال، تسمح التوجيهات التالية لـ <code>articles</code> التي لها قيم <code>to_param</code> مثل <code>1-hello-world</code> والتي تبدأ دائمًا برقم ولـ <code>users</code> التي لها قيم <code>to_param</code> مثل <code>david</code> التي لا تبدأ برقم بمشاركة مجال الاسم الجذر (root namespace):<syntaxhighlight lang="rails">
 
على سبيل المثال، تسمح التوجيهات التالية لـ articles التي لها قيم to_param مثل 1-hello-world والتي تبدأ دائمًا برقم ولـ users التي لها قيم to_param مثل david التي لا تبدأ برقم بمشاركة مجال الاسم الجذر (root namespace):
 
get '/:id', to: 'articles#show', constraints: { id: /\d.+/ }
get '/:id', to: 'articles#show', constraints: { id: /\d.+/ }
get '/:username', to: 'users#show'
get '/:username', to: 'users#show'
</syntaxhighlight>


=== قيود على أساس الطلب ===
=== قيود على أساس الطلب ===
يمكنك أيضًا تقييد مسار موجه استنادًا إلى أي تابع في كائن الطلب Request التي يعيد سلسلة نصية.
يمكنك أيضًا تقييد مسار موجه استنادًا إلى أي تابع في كائن الطلب <code>Request</code> التي يعيد سلسلة نصية.
 
يمكنك تحديد القيد على أساس الطلب بنفس الطريقة التي تحدد بها قيد الجزء (segment constraint):


يمكنك تحديد القيد على أساس الطلب بنفس الطريقة التي تحدد بها قيد الجزء (segment constraint):<syntaxhighlight lang="rails">
get 'photos', to: 'photos#index', constraints: { subdomain: 'admin' }
get 'photos', to: 'photos#index', constraints: { subdomain: 'admin' }
 
</syntaxhighlight>يمكنك أيضًا تحديد القيود في نموذج الكتلة:<syntaxhighlight lang="rails">
يمكنك أيضًا تحديد القيود في نموذج الكتلة:
 
namespace :admin do
namespace :admin do
 
  constraints subdomain: 'admin' do
 constraints subdomain: 'admin' do
    resources :photos
 
  end
   resources :photos
 
 end
 
end
end
</syntaxhighlight>'''ملاحظة''': تعمل قيود الطلب عن طريق استدعاء تابع في كائن الطلب <code>Request</code> يحمل نفس الاسم مثل مفتاح التجزئة (hash) ثم مقارنة القيمة المعادة بقيمة الجدول Hash. لذلك، يجب أن تتطابق قيم القيد مع نوع إرجاع تابع كائن الطلب المقابل. على سبيل المثال: <code>{ 'constraints: { subdomain: 'api</code> سيطابق نطاقًا فرعيًا لواجهة برمجة التطبيق كما هو متوقع، ولكن لن يكون باستخدام رمز مثل


ملاحظة: تعمل قيود الطلب عن طريق استدعاء تابع في كائن الطلب Request يحمل نفس الاسم مثل مفتاح التجزئة (hash) ثم مقارنة القيمة المعادة بقيمة التجزئة. لذلك، يجب أن تتطابق قيم القيد مع نوع إرجاع تابع كائن الطلب المقابل. على سبيل المثال: { 'constraints: { subdomain: 'api سيطابق نطاقًا فرعيًا لواجهة برمجة التطبيق كما هو متوقع، ولكن لن يكون باستخدام رمز مثل
<code>{ constraints: { subdomain: :api</code>، نظرًا لأن <code>request.subdomain</code> يعرض <code>"api"</code> كسلسلة نصية.


{ constraints: { subdomain: :api، نظرًا لأن request.subdomain يعرض "api" كسلسلة نصية.
'''ملاحظة''': هناك استثناء للقيد <code>format</code> وهو في حين أنه تابع في كائن الطلب <code>Request</code>، وهو أيضًا معامل اختياري ضمني في كل مسار. يكون لقيود الشريحة الأسبقية وتطبق قيود التنسيق فقط عند فرضها عبر التجزئة. على سبيل المثال، <code>get 'foo', constraints: { format: 'json' }</code>‎ سيطابق <code>GET  /foo</code> لأن التنسيق اختياري بشكل افتراضي. ومع ذلك، يمكنك استخدام تعابير lambda مثل <code>{ get 'foo', constraints: lambda { |req| req.format == :json</code> وسيتطابق مسار التوجيه مع طلبيات JSON الصريحة فقط.
 
ملاحظة: هناك استثناء للقيد format وهو في حين أنه تابع في كائن الطلب Request، وهو أيضًا معامل اختياري ضمني في كل مسار. يكون لقيود الشريحة الأسبقية وتطبق قيود التنسيق فقط عند فرضها عبر التجزئة. على سبيل المثال، get 'foo', constraints: { format: 'json' }‎ سيطابق GET  /foo
 
لأن التنسيق اختياري بشكل افتراضي. ومع ذلك، يمكنك استخدام تعابير lambda مثل
 
{ get 'foo', constraints: lambda { |req| req.format == :json وسيتطابق التوجيه مع طلبيات JSON الصريحة فقط.


=== القيود المتقدمة ===
=== القيود المتقدمة ===
إذا كان لديك قيد أكثر تقدمًا، يمكنك توفير كائن يستجيب إلى matches?‎ التي يجب أن تستخدمها Rails. لنفترض أنك تريد توجيه جميع المستخدمين في القائمة السوداء إلى BlacklistController، يمكنك القيام بذلك بالشكل التالي:
إذا كان لديك قيد أكثر تقدمًا، يمكنك توفير كائن يستجيب إلى <code>matches?</code>‎ التي يجب أن تستخدمها ريلز. لنفترض أنك تريد توجيه جميع المستخدمين في القائمة السوداء إلى <code>BlacklistController</code>، يمكنك القيام بذلك بالشكل التالي:<syntaxhighlight lang="rails">
 
class BlacklistConstraint
class BlacklistConstraint
 
  def initialize
 def initialize
    @ips = Blacklist.retrieve_ips
 
  end
   @ips = Blacklist.retrieve_ips
 
  def matches?(request)
 end
    @ips.include?(request.remote_ip)
 
  end
 def matches?(request)
 
   @ips.include?(request.remote_ip)
 
 end
 
end
end
 
Rails.application.routes.draw do
Rails.application.routes.draw do
 
  get '*path', to: 'blacklist#index',
 get '*path', to: 'blacklist#index',
    constraints: BlacklistConstraint.new
 
   constraints: BlacklistConstraint.new
 
end
end
 
</syntaxhighlight>يمكنك أيضا تحديد القيود على أنها تعابير lambda:<syntaxhighlight lang="rails">
يمكنك أيضا تحديد القيود على أنها تعابير lambda:
 
Rails.application.routes.draw do
Rails.application.routes.draw do
 
  get '*path', to: 'blacklist#index',
 get '*path', to: 'blacklist#index',
    constraints: lambda { |request| Blacklist.retrieve_ips.include?(request.remote_ip) }
 
   constraints: lambda { |request| Blacklist.retrieve_ips.include?(request.remote_ip) }
 
end
end
 
</syntaxhighlight>كل من التابع <code>matches?‎</code> وتعابير lambda تحصل على كائن الطلب <code>Request</code> كوسيط.
كل من تابع matches?‎ و lambda يحصل على كائن الطلب Request كوسيط.


=== التوجيه النمطي والأجزاء المتطابقة بالمحارف الخاصة ===
=== التوجيه النمطي والأجزاء المتطابقة بالمحارف الخاصة ===
التوجيه النمطي (Route globbing) هو طريقة لتحديد أنه يجب مطابقة معامل معين مع جميع الأجزاء المتبقية من المسار. فمثلًا:
التوجيه النمطي (Route globbing) هو طريقة لتحديد أنه يجب مطابقة معامل معين مع جميع الأجزاء المتبقية من المسار. فمثلًا:<syntaxhighlight lang="rails">
 
get 'photos/*other', to: 'photos#unknown'
get 'photos/*other', to: 'photos#unknown'
</syntaxhighlight>سيطابق هذا التوجيه المسار photos/12 أو /photos/long/path/to/12 مع تعيين <code>[params[:other</code> إلى "12" أو "long/path/to/12". تسمى الأجزاء المسبوقة بالرمز <code>*</code> باسم "الأجزاء المتطابقة بالمحارف الخاصة" (wildcard segments).


سيطابق هذا التوجيه المسار photos/12 أو /photos/long/path/to/12 مع تعيين [params[:other إلى "12" أو "long/path/to/12". تسمى الأجزاء المسبوقة بالرمز * باسم "الأجزاء المتطابقة بالمحارف الخاصة" (wildcard segments).
يمكن أن تظهر الأجزاء المتطابقة بالمحارف الخاصة في أي مكان في المسار. فمثلًا:<syntaxhighlight lang="rails">
 
يمكن أن تظهر الأجزاء المتطابقة بالمحارف الخاصة في أي مكان في المسار. فمثلًا:
 
get 'books/*section/:title', to: 'books#show'
get 'books/*section/:title', to: 'books#show'
</syntaxhighlight>من شأنه أن يطابق books/some/section/last-words-a-memoir مع <code>[params[:section</code> الذي يساوي 'some/section'، ومع <code>[params [:title</code> الذي يساوي 'last-words-a-memoir'.


من شأنه أن يطابق books/some/section/last-words-a-memoir مع [params[:section الذي يساوي 'some/section'، ومع [params [:title الذي يساوي 'last-words-a-memoir'.
من الناحية الفنية، يمكن أن يحتوي المسار على أكثر من جزء واحدة متطابق. يعين المطابق (matcher) الأجزاء إلى معاملات بطريقة بديهية. فمثلًا:<syntaxhighlight lang="rails">
 
من الناحية الفنية، يمكن أن يحتوي المسار على أكثر من جزء واحدة متطابق. يعين المطابق (matcher) الأجزاء إلى معاملات بطريقة بديهية. فمثلًا:
 
get '*a/foo/*b', to: 'test#index'
get '*a/foo/*b', to: 'test#index'
</syntaxhighlight>سيطابق zoo/woo/foo/bar/baz مع <code>[params[:a</code> الذي يساوي 'zoo/woo'، ومع <code>[params[:b</code> الذي يساوي 'bar/baz'.


سيطابق zoo/woo/foo/bar/baz مع [params[:a الذي يساوي 'zoo/woo'، ومع [params[:b الذي يساوي 'bar/baz'.
'''ملاحظة''': عبر طلب '‎/foo/bar.json'، ستكون <code>[params[:pages</code> مساوية لـ '‎/foo/bar' مع تنسيق طلب JSON. إذا كنت تريد استعادة سلوك الإصدار ‎3.0.‎x القديم، فيمكنك توفير <code>format: false</code> بالشكل التالي:<syntaxhighlight lang="rails">
 
ملاحظة: عبر طلب '‎/foo/bar.json'، ستكون [params[:pages مساوية لـ '‎/foo/bar' مع تنسيق طلب JSON. إذا كنت تريد استعادة سلوك الإصدار ‎3.0.‎x القديم، فيمكنك توفير format: false بالشكل التالي:
 
get '*pages', to: 'pages#show', format: false
get '*pages', to: 'pages#show', format: false
 
</syntaxhighlight>إذا كنت تريد جعل جزء التنسيق إلزاميًا، وبذلك لا يمكن حذفه، فيمكنك توفير <code>format: true</code> بالشكل التالي:<syntaxhighlight lang="rails">
إذا كنت تريد جعل جزء التنسيق إلزاميًا، وبذلك لا يمكن حذفه، فيمكنك توفير format: true بالشكل التالي:
 
get '*pages', to: 'pages#show', format: true
get '*pages', to: 'pages#show', format: true
</syntaxhighlight>


=== إعادة التوجيه ===
=== إعادة التوجيه ===
يمكنك إعادة توجيه (redirect) أي مسار إلى مسار آخر باستخدام مساعد إعادة التوجيه redirect في المسار الموجه الخاص بك:
يمكنك إعادة توجيه (redirect) أي مسار إلى مسار آخر باستخدام مساعد إعادة التوجيه <code>redirect</code> في المسار الموجه الخاص بك:<syntaxhighlight lang="rails">
 
get '/stories', to: redirect('/articles')
get '/stories', to: redirect('/articles')
 
</syntaxhighlight>يمكنك أيضًا إعادة استخدام أجزاء ديناميكية من المطابقة في المسار لإعادة التوجيه إلى:<syntaxhighlight lang="rails">
يمكنك أيضًا إعادة استخدام أجزاء ديناميكية من المطابقة في المسار لإعادة التوجيه إلى:
 
get '/stories/:name', to: redirect('/articles/%{name}')
get '/stories/:name', to: redirect('/articles/%{name}')
 
</syntaxhighlight>يمكنك أيضًا توفير حظر لإعادة التوجيه، والذي يتلقى معاملات المسار الرمزية وكائن الطلب <code>Request</code>:<syntaxhighlight lang="rails">
يمكنك أيضًا توفير حظر لإعادة التوجيه، والذي يتلقى معاملات المسار الرمزية وكائن الطلب Request:
 
get '/stories/:name', to: redirect { |path_params, req| "/articles/#{path_params[:name].pluralize}" }
get '/stories/:name', to: redirect { |path_params, req| "/articles/#{path_params[:name].pluralize}" }
get '/stories', to: redirect { |path_params, req| "/articles/#{req.subdomain}" }
get '/stories', to: redirect { |path_params, req| "/articles/#{req.subdomain}" }
 
</syntaxhighlight>يرجى ملاحظة أن إعادة التوجيه الافتراضية هي عملية إعادة توجيه 301 "تم نقلها بشكل دائم" (Moved Permanently). ضع في اعتبارك أن بعض متصفحات الويب أو الخوادم الوسيطة (proxy servers) ستخزن هذا النوع من إعادة التوجيه، مما يجعل الصفحة القديمة غير قابلة للوصول. يمكنك استخدام الخيار <code>‎:status</code> لتغيير حالة الاستجابة:<syntaxhighlight lang="rails">
يرجى ملاحظة أن إعادة التوجيه الافتراضية هي عملية إعادة توجيه 301 "تم نقلها بشكل دائم" (Moved Permanently). ضع في اعتبارك أن بعض متصفحات الويب أو الخوادم الوسيطة (proxy servers) ستخزن هذا النوع من إعادة التوجيه، مما يجعل الصفحة القديمة غير قابلة للوصول. يمكنك استخدام الخيار ‎:status لتغيير حالة الاستجابة:
 
get '/stories/:name', to: redirect('/articles/%{name}', status: 302)
get '/stories/:name', to: redirect('/articles/%{name}', status: 302)
 
</syntaxhighlight>في جميع هذه الحالات، إذا لم تقدم المضيف الأساسي (<nowiki>http://www.example.com)،</nowiki> فستأخذ ريلز هذه التفاصيل من الطلب الحالي.
في جميع هذه الحالات، إذا لم تقدم المضيف الأساسي (<nowiki>http://www.example.com)،</nowiki> فستأخذ Rails هذه التفاصيل من الطلب الحالي.


=== التوجيه إلى تطبيقات Rack ===
=== التوجيه إلى تطبيقات Rack ===
بدلاً من سلسلة نصية مثل 'articles#index'، والتي تتطابق مع الإجراء index في ArticlesController، يمكنك تحديد أي تطبيق Rack كنقطة نهاية للمطابق:
بدلاً من سلسلة نصية مثل <code>'articles#index'</code>، والتي تتطابق مع الإجراء <code>index</code> في <code>ArticlesController</code>، يمكنك تحديد أي تطبيق Rack كنقطة نهاية للمطابق:<syntaxhighlight lang="rails">
 
match '/application.js', to: MyRackApp, via: :all
match '/application.js', to: MyRackApp, via: :all
</syntaxhighlight>طالما يستجيب <code>MyRackApp</code> لاستدعاء ويعيد <code>[status, headers, body]</code>، لن يعرف جهاز التوجيه الفرق بين تطبيق Rack والإجراء. هذا هو الاستخدام المناسب لـ <code>via: :all</code>، كما تريد السماح لتطبيق Rack الخاص بك بالتعامل مع جميع الأفعال التي تراها مناسبة.
 
طالما يستجيب MyRackApp لاستدعاء ويعيد [status, headers, body]، لن يعرف جهاز التوجيه الفرق بين تطبيق Rack والإجراء. هذا هو الاستخدام المناسب لـ via: :all، كما تريد السماح لتطبيق Rack الخاص بك بالتعامل مع جميع الأفعال التي تراها مناسبة.


ملاحظة: يوسع 'articles#index' فعليًا إلى (ArticlesController.action(:index، التي تُرجع تطبيق Rack صالحًا.
'''ملاحظة''': يوسع <code>'articles#index'</code> فعليًا إلى <code>(ArticlesController.action(:index</code>، التي تُرجع تطبيق Rack صالحًا.
 
إذا قمت بتحديد تطبيق Rack كنقطة نهاية للمطابقة، فتذكر أنَّ التوجيه لن يتغير في تطبيق الاستلام. مع التوجيه التالي، يجب أن يتوقع تطبيق Rack أن يكون المسار هو ‎/admin:
 
match '/admin', to: AdminApp, via: :all
 
إذا كنت تفضل أن يتلقى تطبيق Rack طلبات على المسار الجذر بدلًا من ذلك، فاستخدم mount:


إذا قمت بتحديد تطبيق Rack كنقطة نهاية للمطابقة، فتذكر أنَّ التوجيه لن يتغير في تطبيق الاستلام. مع التوجيه التالي، يجب أن يتوقع تطبيق Rack أن يكون المسار هو ‎/admin:<syntaxhighlight lang="rails">
match '/admin', to: AdminApp, via: :all
</syntaxhighlight>إذا كنت تفضل أن يتلقى تطبيق Rack طلبات على المسار الجذر بدلًا من ذلك، فاستخدم <code>mount</code>:<syntaxhighlight lang="rails">
mount AdminApp, at: '/admin'
mount AdminApp, at: '/admin'
</syntaxhighlight>


=== استخدام الجذر ===
=== استخدام الجذر ===
يمكنك تحديد ما يجب أن تسلكه Rails عند توجيه '/' باستخدام التابع root:
يمكنك تحديد ما يجب أن تسلكه Rails عند توجيه '/' باستخدام التابع <code>root</code>:<syntaxhighlight lang="rails">
 
root to: 'pages#main'
root to: 'pages#main'
root 'pages#main' # shortcut for the abov
</syntaxhighlight>يجب وضع مسار الجذر أعلى الملف، لأنه المسار الأكثر شيوعًا ويجب مطابقته أولاً.


root 'pages#main' # shortcut for the above
'''ملاحظة''': يوجه مسار الجذر فقط طلبيات GET إلى الإجراء.
 
يجب وضع مسار الجذر أعلى الملف، لأنه المسار الأكثر شيوعًا ويجب مطابقته أولاً.
 
ملاحظة: يوجه مسار الجذر فقط طلبيات GET إلى الإجراء.
 
يمكنك أيضًا استخدام الجذر داخل مجالات الأسماء والنطاقات أيضًا. فمثلًا:


يمكنك أيضًا استخدام الجذر داخل مجالات الأسماء والنطاقات أيضًا. فمثلًا:<syntaxhighlight lang="rails">
namespace :admin do
namespace :admin do
 
  root to: "admin#index"
 root to: "admin#index"
 
end
end
 
root to: "home#index"
root to: "home#index"
</syntaxhighlight>


=== توجيهات محارف يونيكود ===
=== توجيهات محارف يونيكود ===
يمكنك تحديد توجيهات محارف يونيكود مباشرةً. فمثلًا:
يمكنك تحديد توجيهات محارف يونيكود مباشرةً. فمثلًا:<syntaxhighlight lang="rails">
 
get 'こんにちは', to: 'welcome#index'
get 'こんにちは', to: 'welcome#index'
</syntaxhighlight>


=== التوجيهات المباشرة ===
=== التوجيهات المباشرة ===
يمكنك إنشاء مساعدين مخصصين لعناوين URL مباشرةً. فمثلًا:
يمكنك إنشاء مساعدين مخصصين لعناوين URL مباشرةً. فمثلًا:<syntaxhighlight lang="rails">
 
direct :homepage do
direct :homepage do
 
  "http://www.rubyonrails.org"
 "<nowiki>http://www.rubyonrails.org</nowiki>"
 
end
end
 
<nowiki>#</nowiki> >> homepage_url
# >> homepage_url
 
# => "http://www.rubyonrails.org"
<nowiki>#</nowiki> => "<nowiki>http://www.rubyonrails.org</nowiki>"
</syntaxhighlight>يجب أن تعيد الكتلة وسيطًا صالحًا للتابع <code>url_for</code>. لذلك، يمكنك تمرير سلسلة URL صحيحة، أو جدول Hash، أو مصفوفة، أو نسخة من [[Rails/active model|Active Model]]، أو صنف من [[Rails/active model|Active Model]]: <syntaxhighlight lang="rails">
 
يجب أن تعيد الكتلة وسيطًا صالحًا للتابع url_for. لذلك، يمكنك تمرير سلسلة URL صحيحة، أو تجزئة، أو مصفوفة، أو نسخة نموذج نشط (Active Model instance)، أو صنف نموذج نشط (Active Model class).
 
direct :commentable do |model|
direct :commentable do |model|
 
  [ model, anchor: model.dom_id ]
 [ model, anchor: model.dom_id ]
 
end
end
 
direct :main do
direct :main do
 
  { controller: 'pages', action: 'index', subdomain: 'www' }
 { controller: 'pages', action: 'index', subdomain: 'www' }
 
end
end
</syntaxhighlight>


=== استخدام resolve ===
=== استخدام <code>resolve</code> ===
يسمح التابع resolve بتخصيص تعيينات متعددة الأشكال (polymorphic mapping) للنماذج. فمثلًا:
يسمح التابع <code>resolve</code> بتخصيص تعيينات متعددة الأشكال (polymorphic mapping) للنماذج. فمثلًا:<syntaxhighlight lang="rails">
 
resource :basket
resource :basket
 
resolve("Basket") { [:basket] }
resolve("Basket") { [:basket] }
 
</syntaxhighlight><syntaxhighlight lang="rails">
<%= form_for @basket do |form| %>
<%= form_for @basket do |form| %>
 
  <!-- basket form -->
 <!-- basket form -->
 
<% end %>
<% end %>
 
</syntaxhighlight>سيؤدي ذلك إلى إنشاء عنوان URL هو  ‎/basket بدلًا من العنوان ‎/baskets/:id المعتاد.
سيؤدي ذلك إلى إنشاء عنوان URL هو  ‎/basket بدلًا من العنوان ‎/baskets/:id المعتاد.


== تخصيص التوجيهات كثيرة الموارد ==
== تخصيص التوجيهات كثيرة الموارد ==
في حين أن التوجيهات والمساعدات الافتراضية التي أنشئت بواسطة resources :articles عادةً ما تخدمك جيدًا، فقد تحتاج إلى تخصيصها بطريقة ما. تسمح لك Rails بتخصيص أي جزء عام من المساعدين كثيري الموارد (resourceful helpers).
في حين أن التوجيهات والمساعدات الافتراضية التي أنشئت بواسطة <code>resources :articles</code> عادةً ما تخدمك جيدًا، فقد تحتاج إلى تخصيصها بطريقة ما. تسمح لك ريلز بتخصيص أي جزء عام من المساعدين كثيري الموارد (resourceful helpers).


=== تحديد وحدة تحكم لاستخدامها ===
=== تحديد وحدة تحكم لاستخدامها ===
يتيح لك الخيار ‎:controller تحديد وحدة تحكم بشكل صريح لاستخدامها في المورد. فمثلًا:
يتيح لك الخيار <code>‎:controller</code> تحديد وحدة تحكم بشكل صريح لاستخدامها في المورد. فمثلًا:<syntaxhighlight lang="rails">
 
resources :photos, controller: 'images'
resources :photos, controller: 'images'
</syntaxhighlight>سيتعرف على المسارات الواردة التي تبدأ بـ ‎/photos ولكن سيوجه إلى وحدة التحكم في <code>Images</code>:
 
سيتعرف على المسارات الواردة التي تبدأ بـ ‎/photos ولكن سيوجه إلى وحدة التحكم في Images:
{| class="wikitable"
{| class="wikitable"
|فعل HTTP
!فعل HTTP
|المسار
!المسار
|وحدة التحكم#الإجراء
!وحدة التحكم#الإجراء
|مسمى المساعد
!مسمى المساعد
|-
|-
|GET
|GET
|‎/photos
|‎/photos
|images#index
|<code>images#index</code>
|photos_path
|<code>photos_path</code>
|-
|-
|GET
|GET
|‎/photos/new
|‎/photos/new
|images#new
|<code>images#new</code>
|new_photo_path
|<code>new_photo_path</code>
|-
|-
|POST
|POST
|‎/photos
|‎/photos
|images#create
|<code>images#create</code>
|photos_path
|<code>photos_path</code>
|-
|-
|GET
|GET
|‎/photos/:id
|‎/photos/:id
|images#show
|<code>images#show</code>
|photo_path(:id)‎
|<code>photo_path(:id)‎</code>
|-
|-
|GET
|GET
|‎/photos/:id/edit
|‎/photos/:id/edit
|images#edit
|<code>images#edit</code>
|edit_photo_path(:id)‎
|<code>edit_photo_path(:id)‎</code>
|-
|-
|PATCH/PUT
|PATCH/PUT
|‎/photos/:id
|‎/photos/:id
|images#update
|<code>images#update</code>
|photo_path(:id)‎
|<code>photo_path(:id)‎</code>
|-
|-
|DELETE
|DELETE
|‎/photos/:id
|‎/photos/:id
|images#destroy
|<code>images#destroy</code>
|photo_path(:id)‎
|<code>photo_path(:id)‎</code>
|}
|}
ملاحظة: استخدم photos_photo و new_photo_path وما إلى ذلك لإنشاء مسارات لهذا المورد.
'''ملاحظة''': استخدم <code>photos_photo</code> و <code>new_photo_path</code> وما إلى ذلك لإنشاء مسارات لهذا المورد.
 
بالنسبة لوحدات تحكم ذات مجال أسماء (namespaced controllers)، يمكنك استخدام تدوين المجلد (directory notation). فمثلًا:
 
resources :user_permissions, controller: 'admin/user_permissions'


هذا سوف يوجهه إلى وحدة التحكم Admin::UserPermissions.
بالنسبة لوحدات تحكم ذات مجال أسماء (namespaced controllers)، يمكنك استخدام تدوين المجلد (directory notation). فمثلًا:<syntaxhighlight lang="rails">
resources :user_permissions, controller: 'admin/user_permissions'
</syntaxhighlight>هذا سوف يوجهه إلى وحدة التحكم <code>Admin::UserPermissions</code>.


ملاحظة: تدوين المجلد مدعومٌ فقط. يمكن أن يؤدي تحديد وحدة التحكم بتدوين Ruby الثابت
'''ملاحظة''': تدوين المجلد مدعومٌ فقط. يمكن أن يؤدي تحديد وحدة التحكم بتدوين [[Ruby|روبي]] الثابت


(مثل controller: 'Admin::UserPermissions'‎) إلى مشاكل في التوجيه ينتج عنها تحذيرات.
(مثل <code>controller: 'Admin::UserPermissions'</code>‎) إلى مشاكل في التوجيه ينتج عنها تحذيرات.


=== تحديد القيود ===
=== تحديد القيود ===
يمكنك استخدام الخيار ‎:constraints لتحديد التنسيق المطلوب على المعرّف id الضمني. فمثلًا:
يمكنك استخدام الخيار <code>‎:constraints</code> لتحديد التنسيق المطلوب على المعرّف <code>id</code> الضمني. فمثلًا:<syntaxhighlight lang="rails">
 
resources :photos, constraints: { id: /[A-Z][A-Z][0-9]+/ }
<nowiki>resources :photos, constraints: { id: /[A-Z][A-Z][0-9]+/ }</nowiki>
</syntaxhighlight>يقيد هذا الاعلان المعامل <code>id:</code> ليطابق التعبير المعتاد الموفر. لذلك، في هذه الحالة، لم يعد جهاز التوجيه يتطابق مع ‎/photos/1 مع هذا المسار. بدلًا من ذلك، إنَّ ‎/photos/RR27 هي من ستتطابق.
 
يقيد هذا الاعلان المعامل id: ليطابق التعبير المعتاد الموفر. لذلك، في هذه الحالة، لم يعد جهاز التوجيه يتطابق مع ‎/photos/1 مع هذا المسار. بدلًا من ذلك، إنَّ ‎/photos/RR27 هي من ستتطابق.
 
يمكنك تحديد قيد واحد لتطبيقه على عدد من المسارات باستخدام نموذج الكتلة:


يمكنك تحديد قيد واحد لتطبيقه على عدد من المسارات باستخدام نموذج الكتلة:<syntaxhighlight lang="rails">
constraints(id: /[A-Z][A-Z][0-9]+/) do
constraints(id: /[A-Z][A-Z][0-9]+/) do
  resources :photos
  resources :accounts
end
</syntaxhighlight>'''ملاحظة''': بالطبع، يمكنك استخدام القيود الأكثر تقدمًا المتوفرة في المسارات غير كثيرة الموارد في هذا السياق.


 resources :photos
'''فائدة''': بشكل افتراضي، لا يقبل المعامل <code>‎:id</code> النقاط وذلك لأن النقطة تستخدم كفاصل للمسارات المنسقة. إذا كنت بحاجة إلى استخدام نقطة داخل <code>‎:id</code>، فأدخل قيدًا يتجاوز هذا مثل <code>id: /[^\/]+/‎</code> يسمح بأي شيء باستثناء الشرطة المائلة.
 
 resources :accounts
 
End
 
ملاحظة: بالطبع، يمكنك استخدام القيود الأكثر تقدمًا المتوفرة في المسارات غير كثيرة الموارد في هذا السياق.
 
فائدة: بشكل افتراضي، لا يقبل المعامل ‎:id النقاط وذلك لأن النقطة تستخدم كفاصل للمسارات المنسقة. إذا كنت بحاجة إلى استخدام نقطة داخل ‎:id، فأدخل قيدًا يتجاوز هذا مثل id: /[^\/]+/‎ يسمح بأي شيء باستثناء الشرطة المائلة.


=== تجاوز المساعدين المسماة ===
=== تجاوز المساعدين المسماة ===
يسمح لك الخيار ‎:as بتجاوز التسمية العادية لمساعدي مسار معين. فمثلًا:
يسمح لك الخيار <code>‎:as</code> بتجاوز التسمية العادية لمساعدي مسار معين. فمثلًا:<syntaxhighlight lang="rails">
 
resources :photos, as: 'images'
resources :photos, as: 'images'
</syntaxhighlight>سوف يتعرف على المسارات الواردة التي تبدأ بـ ‎/photos ويوجه الطلبات إلى <code>PhotosController</code>، ولكن استخدم الخيار <code>‎:as</code> لتسمية المساعدين.
 
سوف يتعرف على المسارات الواردة التي تبدأ بـ ‎/photos ويوجه الطلبات إلى PhotosController، ولكن استخدم الخيار ‎:as لتسمية المساعدين.
{| class="wikitable"
{| class="wikitable"
|فعل HTTP
!فعل HTTP
|المسار
!المسار
|وحدة التحكم # الإجراء
!وحدة التحكم # الإجراء
|مسمى المساعد
!مسمى المساعد
|-
|-
|GET
|GET
|‎/photos
|‎/photos
|photos#index
|<code>photos#index</code>
|images_path
|<code>images_path</code>
|-
|-
|GET
|GET
|‎/photos/new
|‎/photos/new
|photos#new
|<code>photos#new</code>
|new_image_path
|<code>new_image_path</code>
|-
|-
|POST
|POST
|‎/photos
|‎/photos
|photos#create
|<code>photos#create</code>
|images_path
|<code>images_path</code>
|-
|-
|GET
|GET
|‎/photos/:id
|‎/photos/:id
|photos#show
|<code>photos#show</code>
|image_path(:id)‎
|<code>image_path(:id)‎</code>
|-
|-
|GET
|GET
|‎/photos/:id/edit
|‎/photos/:id/edit
|photos#edit
|<code>photos#edit</code>
|edit_image_path(:id)‎
|<code>edit_image_path(:id)‎</code>
|-
|-
|PATCH/PUT
|PATCH/PUT
|‎/photos/:id
|‎/photos/:id
|photos#update
|<code>photos#update</code>
|image_path(:id)‎
|<code>image_path(:id)‎</code>
|-
|-
|DELETE
|DELETE
|‎/photos/:id
|‎/photos/:id
|photos#destroy
|<code>photos#destroy</code>
|image_path(:id)‎
|<code>image_path(:id)‎</code>
|}
|}


=== استبدال الأجزاء الجديدة وتعديلها ===
=== استبدال الأجزاء الجديدة وتعديلها ===
يتيح لك الخيار ‎:path_names استبدال الأجزاء الجديدة وتعديلها تلقائيًا في المسارات:
يتيح لك الخيار <code>‎:path_names</code> استبدال الأجزاء الجديدة وتعديلها تلقائيًا في المسارات:<syntaxhighlight lang="rails">
 
resources :photos, path_names: { new: 'make', edit: 'change' }
resources :photos, path_names: { new: 'make', edit: 'change' }
</syntaxhighlight>قد يتسبب هذا في التعرف على المسارات مثل:<syntaxhighlight lang="text">
 
قد يتسبب هذا في التعرف على المسارات مثل:
 
/photos/make
/photos/make


/photos/1/change
/photos/1/change
</syntaxhighlight>'''ملاحظة''': لا تتغيير أسماء الإجراءات الفعلية بواسطة هذا الخيار. سيستمر المساران المعروضان في مسار التوجيه إلى الإجراءات الجديدة وتعديلها.


ملاحظة: لا تتغيير أسماء الإجراءات الفعلية بواسطة هذا الخيار. سيستمر المساران المعروضان في مسار التوجيه إلى الإجراءات الجديدة وتعديلها.
'''فائدة''': إذا وجدت نفسك ترغب في تغيير هذا الخيار بشكل موحد لجميع مسارات التوجيه لديك، فيمكنك استخدام النطاق.<syntaxhighlight lang="rails">
 
فائدة: إذا وجدت نفسك ترغب في تغيير هذا الخيار بشكل موحد لجميع مسارات التوجيه لديك، فيمكنك استخدام النطاق.
 
scope path_names: { new: 'make' } do
scope path_names: { new: 'make' } do
 
  # rest of your routes
 # rest of your routes
 
end
end
</syntaxhighlight>


=== إضافة بادئة لمساعدي مسار التوجيه المسمى ===
=== إضافة بادئة لمساعدي مسار التوجيه المسمى ===
يمكنك استخدام الخيار ‎:as لإضافة بادئة لمساعدي مسار التوجيه المسمى الذي تُنشئُه Rails لمسار التوجيه. استخدم هذا الخيار لمنع تضارب الأسماء بين المسارات باستخدام نطاق مسار. فمثلًا:
يمكنك استخدام الخيار <code>‎:as</code> لإضافة بادئة لمساعدي مسار التوجيه المسمى الذي تُنشئُه ريلز لمسار التوجيه. استخدم هذا الخيار لمنع تضارب الأسماء بين المسارات باستخدام نطاق مسار. فمثلًا:<syntaxhighlight lang="rails">
 
scope 'admin' do
scope 'admin' do
 
  resources :photos, as: 'admin_photos'
 resources :photos, as: 'admin_photos'
 
end
end
 
resources :photos
resources :photos
</syntaxhighlight>سيوفر ذلك مساعدين لمسارات التوجيه، مثل <code>admin_photos_path</code> و <code>new_admin_photo_path</code> وما إلى ذلك.


سيوفر ذلك مساعدين لمسارات التوجيه، مثل admin_photos_path و new_admin_photo_path وما إلى ذلك.
لإضافة بادئة لمجموعة من مساعدي مسارات التوجيه، استخدم الخيار <code>‎:as</code> مع النطاق:<syntaxhighlight lang="rails">
 
لإضافة بادئة لمجموعة من مساعدي مسارات التوجيه، استخدم الخيار ‎:as مع النطاق:
 
scope 'admin', as: 'admin' do
scope 'admin', as: 'admin' do
 
  resources :photos, :accounts
 resources :photos, :accounts
 
end
end
 
resources :photos, :accounts
resources :photos, :accounts
</syntaxhighlight>سيؤدي ذلك إلى إنشاء مسارات مثل <code>admin_photos_path</code> و <code>admin_accounts_path</code> والتي تعين ‎/admin /photos و ‎/admin/accounts على التوالي.


سيؤدي ذلك إلى إنشاء مسارات مثل admin_photos_path و admin_accounts_path والتي تعين ‎/admin /photos و ‎/admin/accounts على التوالي.
'''ملاحظة''': سيضيف نطاق مجال الأسماء تلقائيًا الخيار <code>‎:as</code> بالإضافة إلى البادئات <code>‎:module</code> و <code>‎:path</code>.
 
ملاحظة: سيضيف نطاق مجال الأسماء تلقائيًا الخيار ‎:as بالإضافة إلى البادئات ‎:module و ‎:path.
 
يمكن إضافة بادئة لمسارات التوجيه مع معامل مسمى أيضًا:


يمكن إضافة بادئة لمسارات التوجيه مع معامل مسمى أيضًا:<syntaxhighlight lang="rails">
scope ':username' do
scope ':username' do
 
  resources :articles
 resources :articles
 
end
end
</syntaxhighlight>سيزودك هذا بعناوين URL مثل ‎/bob/articles/1 وسيسمح لك بمراجعة الجزء <code>username</code> من المسار


سيزودك هذا بعناوين URL مثل ‎/bob/articles/1 وسيسمح لك بمراجعة الجزء username من المسار
بالشكل <code>[params[:username</code> في وحدات التحكم والمساعدين والواجهات.
 
بالشكل [params[:username في وحدات التحكم والمساعدين والواجهات.


=== تقييد مسارات التوجيه التي أنشئت ===
=== تقييد مسارات التوجيه التي أنشئت ===
بشكل افتراضي، تنشئ Rails مسارات توجيه للإجراءات الافتراضية السبعة (index، و show، و new، و create، و edit، و update، و destroy) لكل مسار RESTful في التطبيق الخاص بك. يمكنك استخدام الخيارات ‎:only و ‎:except لضبط هذا السلوك. الخيار ‎:only يخبر Rails بإنشاء المسارات المحددة فقط:
بشكل افتراضي، تنشئ ريلز مسارات توجيه للإجراءات الافتراضية السبعة (<code>index</code>، و <code>show</code>، و <code>new</code>، و <code>create</code>، و <code>edit</code>، و <code>update</code>، و <code>destroy</code>) لكل مسار RESTful في التطبيق الخاص بك. يمكنك استخدام الخيارات <code>‎:only</code> و <code>‎:except</code> لضبط هذا السلوك. الخيار <code>‎:only</code> يخبر ريلز بإنشاء المسارات المحددة فقط:<syntaxhighlight lang="rails">
 
resources :photos, only: [:index, :show]
<nowiki>resources :photos, only: [:index, :show]</nowiki>
</syntaxhighlight>الآن، قد ينجح طلب GET إلى ‎/photos، ولكن سيخفق طلب POST إلى ‎/photos (والذي عادةً ما يوجه إلى الإجراء <code>create</code>).
 
الآن، قد ينجح طلب GET إلى ‎/photos، ولكن سيخفق طلب POST إلى ‎/photos (والذي عادةً ما يوجه إلى إجراء create).
 
الخيار ‎:except يحدد المسار أو قائمة المسارات التي لا يجب على Rails أن تنشئها:
 
resources :photos, except: :destroy


في هذه الحالة، ستنشئ Rails  كل المسارات العادية باستثناء مسار التدمير (طلب DELETE إلى ‎/photos/:id).
الخيار <code>‎:except</code> يحدد المسار أو قائمة المسارات التي لا يجب على ريلز أن تنشئها:<syntaxhighlight lang="rails">
resources :photos, except: :destroy
</syntaxhighlight>في هذه الحالة، ستنشئ ريلز  كل المسارات العادية باستثناء مسار التدمير (طلب DELETE إلى ‎/photos/:id).


فائدة: إذا كان التطبيق يحتوي على العديد من مسارات RESTful، فاستعمال ‎:only و ‎:except لتوليد مسارات التوجيه التي تحتاجها فعليًا فقط يمكن من تقليل استخدام الذاكرة وتسريع عملية التوجيه.
'''فائدة''': إذا كان التطبيق يحتوي على العديد من مسارات RESTful، فاستعمال <code>‎:only</code> و <code>‎:except</code> لتوليد مسارات التوجيه التي تحتاجها فعليًا فقط يمكن من تقليل استخدام الذاكرة وتسريع عملية التوجيه.


=== المسارات المبدَّلة ===
=== المسارات المبدَّلة ===
باستخدام scope، يمكننا تغيير أسماء المسارات التي أنشئت بواسطة resources:
باستخدام <code>scope</code>، يمكننا تغيير أسماء المسارات التي أنشئت بواسطة <code>resources</code>:<syntaxhighlight lang="rails">
 
scope(path_names: { new: 'neu', edit: 'bearbeiten' }) do
scope(path_names: { new: 'neu', edit: 'bearbeiten' }) do
 
  resources :categories, path: 'kategorien'
 resources :categories, path: 'kategorien'
 
end
end
 
</syntaxhighlight>تنشئ ريلز الآن مسارات موجهة إلى <code>CategoriesContator</code>.
تنشئ Rails الآن مسارات إلى CategoriesContator.
{| class="wikitable"
{| class="wikitable"
|فعل HTTP
!فعل HTTP
|المسار
!المسار
|وحدة التحكم # الإجراء
!وحدة التحكم # الإجراء
|مسمى المساعد
!مسمى المساعد
|-
|-
|GET
|GET
|‎/kategorien
|‎/kategorien
|categories#index
|<code>categories#index</code>
|categories_path
|<code>categories_path</code>
|-
|-
|GET
|GET
|‎/kategorien/neu
|‎/kategorien/neu
|categories#new
|<code>categories#new</code>
|new_category_path
|<code>new_category_path</code>
|-
|-
|POST
|POST
|‎/kategorien
|‎/kategorien
|categories#create
|<code>categories#create</code>
|categories_path
|<code>categories_path</code>
|-
|-
|GET
|GET
|‎/kategorien/:id
|‎/kategorien/:id
|categories#show
|<code>categories#show</code>
|category_path(:id)‎
|<code>category_path(:id)‎</code>
|-
|-
|GET
|GET
|‎/kategorien/:id/bearbeiten
|‎/kategorien/:id/bearbeiten
|categories#edit
|<code>categories#edit</code>
|edit_category_path(:id)‎
|<code>edit_category_path(:id)‎</code>
|-
|-
|PATCH/PUT
|PATCH/PUT
|‎/kategorien/:id
|‎/kategorien/:id
|categories#update
|<code>categories#update</code>
|category_path(:id)‎
|<code>category_path(:id)‎</code>
|-
|-
|DELETE
|DELETE
|/kategorien/:id
|/kategorien/:id
|categories#destroy
|<code>categories#destroy</code>
|category_path(:id)‎
|<code>category_path(:id)‎</code>
|}
|}


=== استبدال النموذج المفرد ===
=== استبدال النموذج المفرد ===
إذا كنت تريد تعريف الشكل المفرد لمورد، فيجب عليك إضافة قواعد إضافية إلى Inflector:
إذا كنت تريد تعريف الشكل المفرد لمورد، فيجب عليك إضافة قواعد إضافية إلى <code>Inflector</code>:<syntaxhighlight lang="rails">
 
ActiveSupport::Inflector.inflections do |inflect|
ActiveSupport::Inflector.inflections do |inflect|
 
  inflect.irregular 'tooth', 'teeth'
 inflect.irregular 'tooth', 'teeth'
 
end
end
</syntaxhighlight>


=== استخدام ‎:as في الموارد المتداخلة ===
=== استخدام <code>‎:as</code> في الموارد المتداخلة ===
الخيار ‎:as يستبدل الاسم الذي أُنشِأ تلقائيًا للمورد في مساعدي المسارات الموجهة المتداخلة. فمثلًا:
الخيار <code>‎:as</code> يستبدل الاسم الذي أُنشِأ تلقائيًا للمورد في مساعدي المسارات الموجهة المتداخلة. فمثلًا:<syntaxhighlight lang="rails">
 
resources :magazines do
resources :magazines do
 
  resources :ads, as: 'periodical_ads'
 resources :ads, as: 'periodical_ads'
 
end
end
 
</syntaxhighlight>سيؤدي ذلك إلى إنشاء مساعدين للتوجيه مثل <code>magazine_periodical_ads_url</code> و <code>edit_magazine_periodical_ad_path</code>.
سيؤدي ذلك إلى إنشاء مساعدين للتوجيه مثل magazine_periodical_ads_url و edit_magazine_periodical_ad_path.


=== استبدال معاملات المسار الموجه المسماة ===
=== استبدال معاملات المسار الموجه المسماة ===
يستبدل الخيار param: معرف المورد ‎:id الافتراضي (اسم الجزء الديناميكي المستخدم لإنشاء المسارات الموجهة). يمكنك الوصول إلى هذا الجزء من وحدة التحكم باستخدام params[<:param>]‎.
يستبدل الخيار <code>param:</code> معرف المورد <code>‎:id</code> الافتراضي (اسم الجزء الديناميكي المستخدم لإنشاء المسارات الموجهة). يمكنك الوصول إلى هذا الجزء من وحدة التحكم باستخدام <code>params[<:param>]</code>‎.<syntaxhighlight lang="rails">
 
resources :videos, param: :identifier
resources :videos, param: :identifier
 
</syntaxhighlight><syntaxhighlight lang="rails">
   videos GET  /videos(.:format)                  videos#index
    videos GET /videos(.:format)                 videos#index
 
            POST /videos(.:format)                 videos#create
           POST /videos(.:format)                  videos#create
new_videos GET /videos/new(.:format)             videos#new
 
edit_videos GET /videos/:identifier/edit(.:format) videos#edit
new_videos GET  /videos/new(.:format)              videos#new
</syntaxhighlight><syntaxhighlight lang="rails">
 
edit_videos GET  /videos/:identifier/edit(.:format) videos#edit
 
Video.find_by(identifier: params[:identifier])
Video.find_by(identifier: params[:identifier])
 
</syntaxhighlight>يمكنك استبدال <code>ActiveRecord::Base#to_param</code> لنموذج ذي صلة لإنشاء عنوان URL:<syntaxhighlight lang="rails">
يمكنك استبدال ActiveRecord::Base#to_param لنموذج ذي صلة لإنشاء عنوان URL:
 
class Video < ApplicationRecord
class Video < ApplicationRecord
 
  def to_param
 def to_param
    identifier
 
  end
   identifier
 
 end
 
end
end
 
video = Video.find_by(identifier: "Roman-Holiday")
video = Video.find_by(identifier: "Roman-Holiday")
edit_videos_path(video) # => "/videos/Roman-Holiday"
edit_videos_path(video) # => "/videos/Roman-Holiday"
</syntaxhighlight>


== فحص واختبار المسارات الموجهة ==
== فحص واختبار المسارات الموجهة ==
توفر Rails أدوات ووسائل لفحص واختبار المسارات الموجهة الخاصة بك.
توفر ريلز أدوات ووسائل لفحص واختبار المسارات الموجهة الخاصة بك.


=== قائمة المسارات الحالية ===
=== قائمة المسارات الحالية ===
للحصول على قائمة كاملة بالمسارات المتاحة في التطبيق الخاص بك، قم بزيارة <nowiki>http://localhost:3000/rails/info/routes</nowiki> في المستعرض الخاص بك أثناء تشغيل خادمك في بيئة التطوير. يمكنك أيضًا تنفيذ الأمر rails routes في الطرفية الخاصة بك لإنتاج نفس المخرجات.
للحصول على قائمة كاملة بالمسارات المتاحة في التطبيق الخاص بك، قم بزيارة <nowiki>http://localhost:3000/rails/info/routes</nowiki> في المستعرض الخاص بك أثناء تشغيل خادمك في بيئة التطوير. يمكنك أيضًا تنفيذ الأمر <code>rails routes</code> في الطرفية الخاصة بك لإنتاج نفس المخرجات.


ستقوم كلا الطريقتين بإدراج جميع مساراتك الموجهة بنفس الترتيب الذي تظهر به في config/routes.rb. لكل مسار، سترى:
ستقوم كلا الطريقتين بإدراج جميع مساراتك الموجهة بنفس الترتيب الذي تظهر به في config/routes.rb. لكل مسار، سترى:
سطر 1٬370: سطر 1٬025:
* نمط عنوان URL المراد مطابقته.
* نمط عنوان URL المراد مطابقته.
* معاملات التوجيه للمسار الموجه.
* معاملات التوجيه للمسار الموجه.
على سبيل المثال، إليك مقطع صغير من مخرجات الأمر rails routes لمسار RESTful الموجه:
على سبيل المثال، إليك مقطع صغير من مخرجات الأمر <code>rails routes</code> لمسار RESTful الموجه:<syntaxhighlight lang="rails">
 
    users GET   /users(.:format)         users#index
   users GET    /users(.:format)          users#index
          POST   /users(.:format)         users#create
 
new_user GET   /users/new(.:format)     users#new
         POST   /users(.:format)          users#create
edit_user GET   /users/:id/edit(.:format) users#edit
 
</syntaxhighlight>يمكنك البحث من خلال مساراتك الموجهة باستخدام الخيار <code>grep: -g</code>. يظهر هذا الأمر أي مسارات موجهة تتطابق جزئيًا مع اسم تابع مساعد العنوان URL، أو فعل HTTP، أو مسار عنوان URL.<syntaxhighlight lang="shell">
new_user GET    /users/new(.:format)      users#new
 
edit_user GET    /users/:id/edit(.:format) users#edit
 
يمكنك البحث من خلال مساراتك الموجهة باستخدام الخيار  grep: -g. يظهر هذا الأمر أي مسارات موجهة تتطابق جزئيًا مع اسم تابع مساعد العنوان URL، أو فعل HTTP، أو مسار عنوان URL.
 
$ bin/rails routes -g new_comment
$ bin/rails routes -g new_comment
$ bin/rails routes -g POST
$ bin/rails routes -g POST
$ bin/rails routes -g admin
$ bin/rails routes -g admin
 
</syntaxhighlight>إذا كنت ترغب فقط في رؤية المسارات الموجهة التي تعين إلى وحدة تحكم معينة، فهناك الخيار <code>‎-c</code>:<syntaxhighlight lang="shell">
إذا كنت ترغب فقط في رؤية المسارات الموجهة التي تعين إلى وحدة تحكم معينة، فهناك الخيار ‎-c:
 
$ bin/rails routes -c users
$ bin/rails routes -c users
$ bin/rails routes -c admin/users
$ bin/rails routes -c admin/users
$ bin/rails routes -c Comments
$ bin/rails routes -c Comments
$ bin/rails routes -c Articles::CommentsController
$ bin/rails routes -c Articles::CommentsController
 
</syntaxhighlight>'''فائدة''': ستجد أن المخرجات من الأمر <code>rails routes</code> أكثر قابلية للقراءة إذا قمت بتوسيع نافذة طرفيتك حتى لا تلتف سطور المخرجات.
فائدة: ستجد أن المخرجات من الأمر rails routes أكثر قابلية للقراءة إذا قمت بتوسيع نافذة طرفيتك حتى لا تلتف سطور المخرجات.


=== اختبار المسارات الموجهة ===
=== اختبار المسارات الموجهة ===
يجب تضمين المسارات الموجهة في إستراتيجية الاختبار (تمامًا مثل بقية تطبيقك). تقدم Rails ثلاثة تأكيدات مضمنة مصممة لجعل عملية اختبار المسارات الموجهة أكثر بساطة:
يجب تضمين المسارات الموجهة في إستراتيجية الاختبار (تمامًا مثل بقية تطبيقك). تقدم ريلز ثلاثة [https://api.rubyonrails.org/v5.2.2/classes/ActionDispatch/Assertions/RoutingAssertions.html تأكيدات مضمنة] مصممة لجعل عملية اختبار المسارات الموجهة أكثر بساطة:
* Assert_generates
* <code>Assert_generates</code>
* Assert_recognizes
* <code>Assert_recognizes</code>
* assert_routing
* <code>assert_routing</code>
 
==== تأكيد assert_generates ====
يؤكد assert_generates أن مجموعة معينة من الخيارات تولد مسارًا معينًا ويمكن استخدامها مع المسارات الافتراضية أو المسارات المخصصة. إليك المثال التالي:


==== تأكيد <code>assert_generates</code> ====
يؤكد <code>assert_generates</code> أن مجموعة معينة من الخيارات تولد مسارًا معينًا ويمكن استخدامها مع المسارات الافتراضية أو المسارات المخصصة. إليك المثال التالي:<syntaxhighlight lang="rails">
assert_generates '/photos/1', { controller: 'photos', action: 'show', id: '1' }
assert_generates '/photos/1', { controller: 'photos', action: 'show', id: '1' }
assert_generates '/about', controller: 'pages', action: 'about'
assert_generates '/about', controller: 'pages', action: 'about'
</syntaxhighlight>


==== تأكيد assert_recognizes ====
==== تأكيد <code>assert_recognizes</code> ====
هو عكس التأكيد assert_generates، إذ يؤكد أنه جرى التعرف على مسار معين ووُجِّه إلى مكان معين في التطبيق الخاص بك. إليك المثال التالي:
هو عكس التأكيد <code>assert_generates</code>، إذ يؤكد أنه جرى التعرف على مسار معين ووُجِّه إلى مكان معين في التطبيق الخاص بك. إليك المثال التالي:<syntaxhighlight lang="rails">
 
assert_recognizes({ controller: 'photos', action: 'show', id: '1' }, '/photos/1')
assert_recognizes({ controller: 'photos', action: 'show', id: '1' }, '/photos/1')
</syntaxhighlight>يمكنك توفير الوسيط <code>method:</code> لتحديد فعل HTTP:<syntaxhighlight lang="rails">
assert_recognizes({ controller: 'photos', action: 'create' }, { path: 'photos', method: :post })
</syntaxhighlight>


يمكنك توفير الوسيط method: لتحديد فعل HTTP:
==== تأكيد <code>assert_routing</code> ====
 
يتحقق تأكيد <code>assert_routing</code> من الطريقتين: يختبر أن المسار يولد الخيارات، وأن الخيارات تولد المسار. وبالتالي، فهو يجمع بين وظائف <code>assert_generates</code> و <code>assert_recognizes</code>:<syntaxhighlight lang="rails">
assert_recognizes({ controller: 'photos', action: 'create' },
 
{ path: 'photos', method: :post })
 
==== تأكيد assert_routing ====
يتحقق تأكيد assert_routing من الطريقتين: يختبر أن المسار يولد الخيارات، وأن الخيارات تولد المسار. وبالتالي، فهو يجمع بين وظائف assert_generates و assert_recognizes:
 
assert_routing({ path: 'photos', method: :post }, { controller: 'photos', action: 'create' })
assert_routing({ path: 'photos', method: :post }, { controller: 'photos', action: 'create' })
</syntaxhighlight>


المصادر
== المصادر ==
* الدليل الإرشادي لتوجيه Rails
* [https://guides.rubyonrails.org/routing.html صفحة Rails Routing from the Outside In في توثيق Ruby On Rails الرسمي.]

المراجعة الحالية بتاريخ 10:20، 24 مارس 2019

يغطي هذا الدليل الميزات التي يواجهها المستخدم في عمليات التوجيه في ريلز.

بعد قراءة هذا الدليل، ستعرف:

  • كيفية تفسير الشيفرة في config/routes.rb.
  • كيفية بناء المسارات الخاصة بك باستخدام إما أسلوب الحيلة (resourceful style) المفضل أو طريقة المطابقة (match method).
  • كيفية الإعلان عن معاملات المسار الموجه، والتي تمرر إلى إجراءات وحدة التحكم (controller actions).
  • كيفية إنشاء المسارات وعناوين URL تلقائيًا باستخدام مساعدي المسار الموجه.
  • التقنيات المتقدمة مثل إنشاء قيود وتثبيت نقاط نهاية Rack.

الغرض من توجيه المسارات في ريلز

يتعرف جهاز التوجيه في ريلز على عناوين URL ويرسلها إلى إجراء وحدة التحكم Action Controller، أو إلى تطبيق Rack. ويمكنه أيضًا إنشاء مسارات وعناوين URL، مع تجنب الحاجة إلى استخدام رموز ثابتة في الواجهة الخاصة بك.

توصيل عناوين URL بالشيفرة

عندما يتلقى تطبيق ريلز طلبًا واردًا مثل: GET /patients/17 يطلب من جهاز التوجيه مطابقته مع إجراء وحدة تحكم Action Controller. إذا كان أول مسار مطابق هو:

get '/patients/:id', to: 'patients#show'

يرسل الطلب إلى وحدة التحكم patients الخاص بالإجراء show مع { id: '17' } في params.

إنشاء مسارات وعناوين URL من الشيفرة

يمكنك أيضًا إنشاء مسارات وعناوين URL. إذا تم تعديل المسار الموجه أعلاه ليكون:

get '/patients/:id', to: 'patients#show', as: 'patient'

ويحتوي التطبيق الخاص بك على هذا الرمز في وحدة التحكم:

@patient = Patient.find(params[:id])

وهذا في الواجهة يقابل:

<%= link_to 'Patient Record', patient_path(@patient) %>

ثم ينشئ جهاز التوجيه المسار /patients/17. هذا يقلل من هشاشة الواجهة الخاص بك ويجعل التعليمات البرمجية الخاصة بك أسهل للفهم. لاحظ أن الهوية id لا تحتاج إلى التحديد في مساعد المسار الموجه.

تهيئة جهاز توجيه المسارات في ريلز

توجد المسارات الموجهة للتطبيق أو المحرك (engine) في الملف config/routes.rb وعادةً ما تبدو كالتالي:

Rails.application.routes.draw do
  resources :brands, only: [:index, :show] do
    resources :products, only: [:index, :show]
  end
 
  resource :basket, only: [:show, :update, :destroy]
 
  resolve("Basket") { route_for(:basket) }
end

نظرًا لأن هذا ملف مصدر روبي منتظم، يمكنك استخدام جميع ميزاته لمساعدتك في تحديد مساراتك الموجهة، لكن كن حذرًا مع أسماء المتغيرات، إذ إنها يمكن أن تتعارض مع توابع DSL الخاصة بالموجه.

ملاحظة: تقوم الكتلة Rails.application.routes.draw do… end التي تلتزم بتعريفات المسار الموجه الخاصة بك بإنشاء النطاق الخاص بجهاز التوجيه DSL ويجب عدم حذفه.

توجيه المورد: الافتراضي في ريلز

يتيح لك توجيه الموارد إمكانية الإعلان بسرعة عن جميع المسارات الشائعة لوحدة التحكم كثيرة الموارد. بدلًا من الإعلان عن مسارات موجهة منفصلة للإجراءات index، و show، و new، و edit، و create، و update و destroy الخاصة بك، فإن المسار كثير المورد يعلن عنه في سطر واحد من الشيفرة.

الموارد على الويب

تطلب صفحات المتصفحات من ريلز عن طريق تقديم طلب لعنوان URL باستخدام تابع HTTP محدد، مثل GET و POST و PATCH و PUT و DELETE. كل تابع هو طلب لتنفيذ عملية على المورد. يحدد مسار المورد الموجه عددًا من الطلبات ذات الصلة بالإجراءات في وحدة التحكم الواحدة.

عندما يتلقى تطبيق ريلز طلبًا واردًا لما يلي:

DELETE /photos/17

يطلب من جهاز التوجيه لتعيينه إلى إجراء وحدة تحكم Action Controller. إذا كان أول مسار مطابق هو:

resources :photos

سترسل ريلز ذلك الطلب للإجراء destroy على وحدة التحكم photos مع {id: '17'} في params.

CRUD والأفعال والإجراءات

في ريلز، يوفر المسار كثير المورد تخطيطًا بين أفعال HTTP وعناوين URL لإجراءات التحكم. من خلال الاتفاقية، كل إجراء يخطط أيضًا لعملية CRUD محددة في قاعدة البيانات. إدخال فردي في ملف التوجيه يكون مثل:

resources :photos

ينشئ سبعة مسارات مختلفة في التطبيق الخاص بك معيَّنةً جميعها إلى وحدة التحكم Photos:

فعل HTTP المسار وحدة التحكم # الإجراء الاستخدامات
GET ‎/photos photos#index عرض قائمة بجميع الصور.
GET ‎/photos/new photos#new إرجاع نموذج HTML لإنشاء صورة جديدة.
POST ‎/photos photos#create خلق صورة جديدة.
GET ‎/photos/:id photos#show عرض صورة محددة.
GET ‎/photos/:id/edit photos#edit إرجاع نموذج HTML لتحرير صورة.
PATCH/PUT ‎/photos/:id photos#update تحديث صورة معينة.
DELETE ‎/photos/:id photos#destroy حذف صورة معينة.

ملاحظة: نظرًا لأن جهاز التوجيه يستخدم الفعل HTTP وعنوان URL لمطابقة الطلبات الواردة، فإن أربعة عناوين URL تتحول إلى سبعة إجراءات مختلفة.

ملاحظة: تُطابَق مسارات ريلز بالترتيب المحدد لها، لذلك إذا كانت لديك resources :photos الموجودة أعلى get photos/poll، فسيطابق مسار الإجراء show السطر resources قبل سطر get. لحل هذه المشكلة، قم بتحريك سطر get فوق سطر resources بحيث يطابقه أولًا.

المسار ومساعد URL

سيؤدي إنشاء مسار موجه كثير المورد إلى كشف عدد من المساعدين إلى وحدات التحكم في تطبيقك. في حالة resources :photos:

  • photos_path returns /photos
  • new_photo_path returns /photos/new
  • edit_photo_path(:id) returns /photos/:id/edit (for instance, edit_photo_path(10) returns /photos/10/edit)‎
  • photo_path(:id) returns /photos/:id (for instance, photo_path(10) returns /photos/10)‎

كل من هؤلاء المساعدين لديه مساعد ‎_url مقابل (مثل photos_url) الذي يعيد نفس المسار مسبوقًا ببادئة المضيف والمنفذ والمسار الحالي.

تحديد موارد متعددة في نفس الوقت

إذا كنت بحاجة إلى إنشاء مسارات توجيه لأكثر من مورد واحد، فيمكنك توفير جزء من الكتابة عن طريق تعريفهم جميعًا باستدعاءٍ واحدٍ إلى resources:

resources :photos, :books, :videos

هذا يعمل بالضبط بطريقة مشابهة للشيفرة التالية:

resources :photos
resources :books
resources :videos

الموارد الفردية

في بعض الأحيان، يكون لديك مورد يبحث عنه العملاء دائمًا دون الإشارة إلى معرف ID. على سبيل المثال، ترغب في أن يعرض ‎/profile دائمًا ملف تعريف المستخدم الذي قام بتسجيل الدخول حاليًا. في هذه الحالة، يمكنك استخدام مورد مفرد لتعيين ‎/profile (بدلًا من ‎/profile/:id) إلى الإجراء show:

get 'profile', to: 'users#show'

تمرير سلسلة نصية (String) إلى to:‎ ستتوقع أن تكون بالتنسيق controller#action. عند استخدام رمز (Symbol)، يجب استبدال الخيار to:‎ بالقيمة action:‎. عند استخدام سلسلة نصية دون الرمز #، يجب استبدال الخيار to:‎ بـ controller:‎ بالشكل التالي:

get 'profile', action: :show, controller: 'users'

هذا مسار موجه كثير المورد:

resource :geocoder
resolve('Geocoder') { [:geocoder] }

يخلق ستة مسارات موجهة مختلفة في التطبيق الخاص بك كلها معيَّنة إلى وحدة التحكم Geocoders:

فعل HTTP المسار وحدة التحكم # الإجراء الإستخدامات
GET ‎/geocoder/new geocoders#new إرجاع نموذج HTML لإنشاء geocoder.
POST ‎/geocoder geocoders#create إنشاء geocoder جديد.
GET ‎/geocoder geocoders#show عرض مورد geocoder واحد و فقط.
GET ‎/geocoder/edit geocoders#edit إرجاع نموذج HTML لتحرير geocoder.
PATCH/PUT ‎/geocoder geocoders#update تحديث مورد geocoder واحد و فقط.
DELETE ‎/geocoder geocoders#destroy حذف مورد geocoder.

ملاحظة: نظرًا لأنك قد ترغب في استخدام وحدة التحكم نفسها لمسار فريد (‎/account) ومسار الجمع (‎/accounts/45)، فإن الموارد الفردية ستخضع إلى وحدات تحكم الجمع. على سبيل المثال، المورد ‎:photo والموارد ‎:photos تنشئ مسارات توجيه مفرد ومجتمعة تعين لنفس وحدة التحكم (PhotosController).

يولّد المسار الموجه كثير المورد المفرد (singular resourceful route) هؤلاء المساعدين:

  • new_geocoder_path returns /geocoder/new
  • edit_geocoder_path returns /geocoder/edit
  • geocoder_path returns /geocoder

كما هو الحال مع موارد الجمع، فإن نفس المساعدين الذين ينتهون في ‎_url سيتضمنون أيضًا بادئة المضيف والمنفذ والمسار.

وحدة تحكم مجالات الأسماء والتوجيه

قد ترغب في تنظيم مجموعات من وحدات التحكم تحت مجال اسم (namespace). الأكثر شيوعًا، يمكنك تجميع عدد من وحدات التحكم الإدارية تحت مجال الاسم Admin::‎. يمكنك وضع وحدات التحكم هذه تحت دليل app/controllers/admin، ويمكنك تجميعها معًا في جهاز التوجيه:

namespace :admin do
  resources :articles, :comments
end

سيؤدي ذلك إلى إنشاء عدد من المسارات لكل من وحدة التحكم في articles و comments. من أجل Admin::ArticlesController، ستنشئ ريلز:

فعل HTTP المسار وحدة التحكم # الإجراء مسمى المساعد
GET ‎/admin/articles admin/articles#index admin_articles_path
GET ‎/admin/articles/new admin/articles#new new_admin_article_path
POST ‎/admin/articles admin/articles#create admin_articles_path
GET ‎/admin/articles/:id admin/articles#show admin_article_path(:id)‎
GET ‎/admin/articles/:id/edit admin/articles#edit edit_admin_article_path(:id)‎
PATCH/PUT ‎/admin/articles/:id admin/articles#update admin_article_path(:id)‎
DELETE ‎/admin/articles/:id admin/articles#destroy admin_article_path(:id)‎

إذا كنت تريد توجيه ‎/articles (بدون البادئة ‎/admin) إلى Admin::ArticlesController، فيمكنك استخدام:

scope module: 'admin' do
  resources :articles, :comments
end

أو في حالة واحدة:

resources :articles, module: 'admin'

إذا كنت تريد توجيه ‎/admin/articles إلى ArticlesController (بدون بادئة الوحدة Admin::‎)، فيمكنك استخدام:

scope '/admin' do
  resources :articles, :comments
end

أو في حالة واحدة:

resources :articles, path: '/admin/articles'

في كل من هذه الحالات، تظل المسارات الموجهة المسماة كما هي إذا لم تستخدم النطاق (scope). في الحالة الأخيرة، تعيَّن المسارات التالية إلى ArticlesController:

فعل HTTP المسار وحدة التحكم # الإجراء مسمى المساعد
GET ‎/admin/articles articles#index articles_path
GET ‎/admin/articles/new articles#new new_article_path
POST ‎/admin/articles articles#create articles_path
GET ‎/admin/articles/:id articles#show article_path(:id)‎
GET ‎/admin/articles/:id/edit articles#edit edit_article_path(:id)‎
PATCH/PUT ‎/admin/articles/:id articles#update article_path(:id)‎
DELETE ‎/admin/articles/:id articles#destroy article_path(:id)‎

ملاحظة: إذا كنت بحاجة إلى استخدام مجال اسم وحدة تحكم (controller namespace) مختلف داخل كتلة مجال الاسم (namespace block)، فيمكنك تحديد مسار جهاز تحكم مطلق، مثل: get '/foo' => '/foo#index'‎.

الموارد المتداخلة

من الشائع أن يكون لديك موارد منطقية للفرع childern من الموارد الأخرى. على سبيل المثال، لنفترض أن تطبيقك يتضمن هذه النماذج:

class Magazine < ApplicationRecord
  has_many :ads
end
 
class Ad < ApplicationRecord
  belongs_to :magazine
end

تتيح لك المسارات المتداخلة التقاط هذه العلاقة في التوجيه الخاص بك. في هذه الحالة، يمكنك تضمين إعلان المسار هذا:

resources :magazines do
  resources :ads
end

بالإضافة إلى المسارات الموجهة للمجلات (magazines)، سيوجه هذا الإعلان أيضًا الإعلانات إلى AdsController. تتطلب عناوين URL للإعلان عن مجلة:

فعل HTTP المسار وحدة التحكم # الإجراء الاستخدامات
GET ‎/magazines/:magazine_id/ads ads#index عرض قائمة بجميع الإعلانات لمجلة محددة.
GET ‎/magazines/:magazine_id/ads/new ads#new إرجاع نموذج HTML لإنشاء إعلان جديد ينتمي إلى مجلة معينة.
POST ‎/magazines/:magazine_id/ads ads#create إنشاء إعلان جديد ينتمي إلى مجلة محددة.
GET ‎/magazines/:magazine_id/ads/:id ads#show عرض إعلان معين ينتمي إلى مجلة محددة.
GET ‎/magazines/:magazine_id/ads/:id/edit ads#edit إرجاع نموذج HTML لتحرير إعلان ينتمي إلى مجلة معينة.
PATCH/PUT ‎/magazines/:magazine_id/ads/:id ads#update تحديث إعلان معين ينتمي إلى مجلة محددة.
DELETE ‎/magazines/:magazine_id/ads/:id ads#destroy حذف إعلان معين ينتمي إلى مجلة محددة.

سيؤدي هذا أيضًا إلى إنشاء مساعدين للتوجيه مثل magazine_ads_url و edit_magazine_ad_path. يأخذ هؤلاء المساعدون نسخة للمجلة كأول معامل (magazine_ads_url(@magazine)‎).

حدود التداخل

يمكنك أن تشعِّب الموارد ضمن الموارد المتشعبة الأخرى إذا أردت ذلك. فمثلًا:

resources :publishers do
  resources :magazines do
    resources :photos
  end
end

تصبح الموارد المتداخلة بعمق بطيئة. في هذه الحالة مثلًا، سيتعرف التطبيق على مسارات مثل:

/publishers/1/magazines/2/photos/3

سيكون مساعد المسار المقابل هو publisher_magazine_photo_url، مما يتطلب منك تحديد كائنات على جميع المستويات الثلاثة. في الواقع، هذا الوضع مربكًا بما فيه الكفاية، إذ يقترح جيمس باك (Jamis Buck) في مقالة شائعة له قاعدةً أساسيةً لتصميم ريلز بشكل جيد: " لا ينبغي أبدًا أن تتداخل الموارد أكثر من 1 مستوى عميق."

التداخل الضحل

تتمثل إحدى طرق تجنب التداخل العميق (كما هو موصى به أعلاه) في إنشاء إجراءات المجموعة المحددة ضمن الأصل (parent)، وذلك للحصول على إحساس بالتسلسل الهرمي (hierarchy) ولعدم تداخل إجراءات العضو. بعبارة أخرى، لإنشاء مسارات فقط مع الحد الأدنى من المعلومات لتحديد المورد بشكل فريد، مثل هذا:

resources :articles do
  resources :comments, only: [:index, :new, :create]
end
resources :comments, only: [:show, :edit, :update, :destroy]

تحقق هذه الفكرة توازنًا بين المسارات الوصفية والتداخل العميق. توجد صيغة مختصرة لتحقيق ذلك، عبر الخيار ‎:shallow:

resources :articles do
  resources :comments, shallow: true
end

سيؤدي ذلك إلى إنشاء نفس المسارات بالضبط مثل المثال الأول. يمكنك أيضًا تحديد الخيار ‎:shallow في المورد الرئيسي parent، وفي هذه الحالة ستكون جميع الموارد المتداخلة ضحلة:

resources :articles, shallow: true do
  resources :comments
  resources :quotes
  resources :drafts
end

التابع الضحل shallow الذي يخص DSL يخلق مجالًا داخليًا يكون كل تداخل فيه ضحلًا. هذا ينشئ نفس المسارات الموجهة مثل المثال السابق:

shallow do
  resources :articles do
    resources :comments
    resources :quotes
    resources :drafts
  end
end

هناك خياران للنطاق (scope) لتخصيص المسارات الموجهة الضحلة. البادئات ‎:shallow_path لمسارات العضو مع المعامل المحدد:

scope shallow_path: "sekret" do
  resources :articles do
    resources :comments, shallow: true
  end
end

يحتوي مورد التعليقات هنا على المسارات التالية التي أنشئت له:

فعل HTTP المسار وحدة التحكم# الإجراء مسمى المساعد
GET ‎/articles/:article_id/comments(.:format)‎ comments#index article_comments_path
POST ‎/articles/:article_id/comments(.:format)‎ comments#create article_comments_path
GET ‎/articles/:article_id/comments/new(.:format)‎ comments#new new_article_comment_path
GET ‎/sekret/comments/:id/edit(.:format)‎ comments#edit edit_comment_path
GET ‎/sekret/comments/:id(.:format)‎ comments#show comment_path
PATCH/PUT ‎/sekret/comments/:id(.:format)‎ comments#update comment_path
DELETE ‎/sekret/comments/:id(.:format)‎ comments#destroy comment_path

الخيار ‎:shallow_prefix يضيف المعامل المحدد للمساعدين المسمايين:

scope shallow_prefix: "sekret" do
  resources :articles do
    resources :comments, shallow: true
  end
end

يحتوي مورد التعليقات هنا على المسارات الموجهة التالية التي أنشئت له:

فعل HTTP المسار وحدة التحكم# الإجراء مسمى المساعد
GET ‎/articles/:article_id/comments(.:format)‎ comments#index article_comments_path
POST ‎/articles/:article_id/comments(.:format)‎ comments#create article_comments_path
GET ‎/articles/:article_id/comments/new(.:format)‎ comments#new new_article_comment_path
GET ‎/comments/:id/edit(.:format)‎ comments#edit edit_sekret_comment_path
GET ‎/comments/:id(.:format)‎ comments#show sekret_comment_path
PATCH/PUT ‎/comments/:id(.:format)‎ comments#update sekret_comment_path
DELETE ‎/comments/:id(.:format)‎ comments#destroy sekret_comment_path

اهتمامات التوجيه

تسمح لك اهتمامات التوجيه (Routing concerns) بالإعلان عن المسارات الموجهة الشائعة التي يمكن إعادة استخدامها داخل الموارد والمسارات الأخرى. ألق نظرة على الشيفرة التالي لمعرفة كيفية تعريف اهتمام concern:

concern :commentable do
  resources :comments
end
 
concern :image_attachable do
  resources :images, only: :index
end

يمكن استخدام هذه الاهتمامات concern في الموارد لتجنب تكرار الرموز ومشاركة السلوك عبر المسارات:

resources :messages, concerns: :commentable
 
resources :articles, concerns: [:commentable, :image_attachable]

ما ورد أعلاه يعادل ما يلي:

resources :messages do
  resources :comments
end
 
resources :articles do
  resources :comments
  resources :images, only: :index
end

كما يمكنك استخدامها في أي مكان تريده داخل المسارات الموجهة، مثل في استدعاء نطاق (scope) أو مجال أسماء (namespace):

namespace :articles do
  concerns :commentable
end

إنشاء مسارات وعناوين URL من الكائنات

بالإضافة إلى استخدام مساعدين التوجيه، تستطيع Rails أيضًا إنشاء مسارات وعناوين URL من مصفوفة من المعاملات. على سبيل المثال، لنفترض أن لديك مجموعة المسارات الموجهة التالية:

resources :magazines do
  resources :ads
end

عند استخدام magazine_ad_path، يمكنك تمرير نسخ من Magazine و Ad بدلًا من المعرفات الرقمية IDs:

<%= link_to 'Ad details', magazine_ad_path(@magazine, @ad) %>

يمكنك أيضًا استخدام url_for مع مجموعة من الكائنات، وسوف تحدد ريلز المسار الموجهة الذي تريده تلقائيًا:

<%= link_to 'Ad details', url_for([@magazine, @ad]) %>

في هذه الحالة، سترى ريلز أن magazine@ هو Magazine و ad@ هو Ad وبالتالي ستستخدم المساعد magazine_ad_path. في المساعدين مثل link_to، يمكنك تحديد الكائن بدلًا من استدعاء url_for بالكامل:

<%= link_to 'Ad details', [@magazine, @ad] %>

إذا كنت تريد الارتباط بمجلة فقط:

<%= link_to 'Magazine details', @magazine %>

بالنسبة إلى الإجراءات الأخرى، تحتاج فقط إلى إدراج اسم الإجراء باعتباره العنصر الأول في المصفوفة:

<%= link_to 'Edit Ad', [:edit, @magazine, @ad] %>

يتيح لك ذلك التعامل مع نسخ النماذج الخاصة بك كعناوين URL، وهي ميزة أساسية لاستخدام النمط كثير المورد.

إضافة المزيد من الإجراءات RESTful

لا تقتصر على المسارات الموجهة السبعة التي ينشئها توجيه RESTful بشكل افتراضي. يمكنك إضافة مسارات موجهة إضافية، إذا كنت ترغب في ذلك، تنطبق على المجموعة أو على أعضاء فرديين في المجموعة.

إضافة مسارات الأعضاء

لإضافة مسار موجه عضو، ما عليك سوى إضافة الكتلة member إلى كتلة الموارد resource:

resources :photos do
  member do
    get 'preview'
  end
end

سيتعرف هذا على ‎/photos/1/preview مع GET، ويوجهه إلى الإجراء preview الذي يخص PhotosController، مع تمرير قيمة معرف المورد id في المعاملات [‎:id]. سيؤدي أيضًا إلى إنشاء photos_preview_url والمساعدين photo_preview_path. ضمن كتلة مسارات الأعضاء الموجهة، كل اسم مسار (route name) يحدد فعل HTTP سيُتعرَّف عليه. يمكنك استخدام get أو patch أو put أو post أو delete هنا. إذا لم يكن لديك العديد من مسارات الأعضاء الموجهة، فيمكنك أيضًا تمرير ‎:on إلى المسار، وإلغاء الكتلة:

resources :photos do
  get 'preview', on: :member
end

يمكنك ترك الخيار ‎:on، إذ سيؤدي ذلك إلى إنشاء نفس مسار العضو باستثناء أن قيمة معرف المورد id ستكون متاحة في [params[:photo_id بدلًا من [params[:id.

إضافة مسارات التجميع

لإضافة مسار موجه إلى المجموعة:

resources :photos do
  collection do
    get 'search'
  end
end

سيؤدي هذا إلى تمكين ريلز للتعرف على مسارات مثل ‎/photos/search باستخدام GET، والتوجيه إلى الإجراء search الذي يخص PhotosController. سيؤدي أيضًا إلى إنشاء مساعدي التوجيه search_photos_url و search_photos_path. كما هو الحال مع توجيهات الأعضاء (member routes)، يمكنك تمرير ‎:on إلى توجيه بالشكل التالي:

resources :photos do
  get 'search', on: :collection
end

إضافة توجيهات لإجراءات جديدة إضافية

يمكن إضافة إجراء جديد بديل باستخدام الاختصار ‎:on بالشكل التالي:

resources :comments do
  get 'preview', on: :new
end

سيؤدي هذا إلى تمكين ريلز للتعرف على مسارات مثل ‎/comments/new/preview باستخدام GET، وتوجيهها إلى الإجراء preview الذي يخص CommentController. سيؤدي أيضًا إلى إنشاء مساعدي التوجيه preview_new_comment_url و preview_new_comment_path.

فائدة: إذا وجدت نفسك تضيف العديد من الإجراءات الإضافية إلى مسار موجه ذي أهمية، فقد حان الوقت للتوقف وسؤال نفسك ما إذا كنت تموه عن وجود مورد آخر.

المسارات الموجهة غير كثيرة المورد (Non-Resourceful)

بالإضافة إلى توجيه الموارد، تتمتع ريلز بدعم قوي لتوجيه عناوين URL العشوائية إلى الإجراءات. هنا، لا يمكنك الحصول على مجموعات من التوجيهات التي تنشأ تلقائيًا من خلال توجيه الموارد. بدلاً من ذلك، يمكنك إعداد كل توجيه على حدة داخل تطبيقك.

على الرغم من أنه يجب عليك عادة استخدام التوجيه كثير المورد (resourceful routing)، إلا أنه لا يزال هناك العديد من الأماكن التي يكون فيها التوجيه الأبسط أكثر ملاءمة. ليس هناك حاجة لمحاولة ارتداء كل جزء أخير من تطبيقك في إطار كثير المورد إذا لم يكن ذلك مناسبًا.

على وجه الخصوص، يجعل التوجيه البسيط من السهل جدًا تعيين عناوين URL القديمة لإجراءات ريلز الجديدة.

المعاملات المقيدة

عند إعداد مسار عادي، فإنك تقدم سلسلة من الرموز التي تحددها ريلز إلى أجزاء من طلب HTTP الوارد. على سبيل المثال، ضع في اعتبارك هذا المسار الموجه:

get 'photos(/:id)', to: :display

إذا تمت معالجة طلب وارد من ‎/photos/1 من خلال هذا التوجيه (لأنه لم يطابق أي توجيه سابق في الملف)، فستكون النتيجة استدعاء الإجراء display الذي يخص PhotosController، ولجعل المعامل النهائي "1"متاحًا بالشكل [params[:id. سيقوم هذا التوجيه أيضًا بتوجيه الطلب الوارد ‎/photos إلى DisplayController#display، نظرًا لأن المُعرِّف ‎:id هو مُعامل اختياري، يشار إليه بواسطة الأقواس.

الأجزاء الديناميكية

يمكنك إعداد العديد من الأجزاء الديناميكية (Dynamic Segments) ضمن مسار موجه عادي حسب رغبتك. سيكون أي جزء متاحًا للعمل كجزء من params. إذا أعددت المسار الموجه التالي:

get 'photos/:id/:user_id', to: 'photos#show'

سيرسل المسار الوارد ‎/photos/1/2 إلى الإجراء show الخاص بـ [PhotosController.params [:id. سيكون params[:id]‎ هو "1"، وسيكون [params[:user_id هو "2".

فائدة: بشكل افتراضي، لا تقبل الأجزاء الديناميكية النقاط، وهذا يرجع إلى استخدام النقطة كفاصل للمسارات الموجهة المنسقة. إذا كنت بحاجة إلى استخدام نقطة داخل جزء ديناميكي، أضف قيدًا يتجاوز هذا مثل ‎id: /[^\/]+/‎ الذي يسمح بأي شيء باستثناء الخط المستقيم المائل.

الأجزاء الثابتة

يمكنك تحديد الأجزاء الثابتة (Static Segments) عند إنشاء مسار موجه من خلال عدم إلحاق النقطتين بالجزء fragment:

get 'photos/:id/with_user/:user_id', to: 'photos#show'

يستجيب هذا المسار الموجه لمسارات مثل ‎/photos/1/with_user/2. في هذه الحالة، ستكون

المعاملات هي {controller: 'photos'، action: 'show'، id: '1'، user_id: '2ٌ'‎}.

سلسلة الاستعلام

ستشمل المعاملات أيضًا أي معاملات من سلسلة الاستعلام. على سبيل المثال، مع هذا المسار الموجه:

get 'photos/:id', to: 'photos#show'

سيرسل المسار الوارد ‎/photos/1?user_id=2 إلى الإجراء show الخاص بوحدة تحكم Photos. إن params ستكون { controller: 'photos', action: 'show', id: '1', user_id: '2'‎ }.

تحديد الافتراضات

يمكنك تحديد الإعدادات الافتراضية في المسار من خلال توفير تجزئة (hash) للخيار ‎:defaults. وينطبق هذا حتى على المعاملات التي لا تحددها كشرائح ديناميكية. فمثلًا:

get 'photos/:id', to: 'photos#show', defaults: { format: 'jpg' }

تطابق ريلز المسار photos/12 مع الإجراء show الذي يخص showController، وتعين params[:format]‎ إلى "jpg". يمكنك أيضًا استخدام defaults في تنسيق الكتلة لتحديد الإعدادات الافتراضية لعناصر متعددة:

defaults format: :json do
  resources :photos
end

ملاحظة: لا يمكنك إلغاء القيم الافتراضية عبر معاملات الاستعلام وهذا يعود لأسباب أمنية. القيم الافتراضية الوحيدة التي يمكن تجاوزها هي الأجزاء الديناميكية عن طريق استبدالها في مسار URL.

تسمية المسارات الموجهة

يمكنك تحديد اسم لأي مسار موجه باستخدام الخيار ‎:as:

get 'exit', to: 'sessions#destroy', as: :logout

سيؤدي ذلك إلى إنشاء logout_path و logout_url كمساعدين مسميين في تطبيقك. وسيؤدي استدعاء loging_path إلى إعادة ‎/exit. يمكنك أيضًا استخدام هذا لتجاوز توابع التوجيه المحددة بواسطة الموارد كما يلي:

get ':username', to: 'users#show', as: :user

سيحدد هذا التابع user_path الذي سيتاح في وحدات التحكم، والمساعدين والواجهات التي ستنتقل إلى مسار مثل ‎/bob. داخل الخيار show الخاص بـ UsersController، تحتوي [params[:username على اسم المستخدم للمستخدم. غير ‎:username في تعريف المسار الموجه إذا كنت لا تريد أن يكون اسم المعامل ‎:username.

قيود فعل HTTP

بشكل عام، يجب عليك استخدام التوابع get و post و put و patch و delete لتقييد توجيه إلى فعل معين. يمكنك استخدام التابع match مع الخيار ‎:via لمطابقة أفعال متعددة في وقت واحد:

match 'photos', to: 'photos#show', via: [:get, :post]

يمكنك مطابقة جميع الأفعال إلى مسار معين باستخدام via: :all كما يلي:

match 'photos', to: 'photos#show', via: :all

ملاحظة: توجيه كل من طلبيات GET و POST إلى إجراء واحد له آثار متعلقة بالأمان. بشكل عام، يجب تجنب توجيه جميع الأفعال إلى أي إجراء ما لم يكن لديك سبب وجيه لذلك.

ملاحظة: لن تتحقق طلبية GET في ريلز من رمز CSRF (اختصار للعبارة cross-site request forgery، وهي الهجمات مُزوّرة الطلب عبر المواقع). يجب ألا تكتب أبدًا إلى قاعدة البيانات من طلبيات GET؛ لمزيد من المعلومات، انظر دليل الأمان الخاص بإجراءات CSRF المضادة.

قيود الجزء (Segment Constraints)

يمكنك استخدام الخيار ‎:constraints لفرض تنسيق لجزء ديناميكي بالشكل التالي:

get 'photos/:id', to: 'photos#show', constraints: { id: /[A-Z]\d{5}/ }

يطابق هذا المسار الموجه مسارات مثل ‎/photos/A12345، ولكن ليس ‎/photos/893. يمكنك التعبير بشكل أكثر دقة عن نفس التوجيه بهذه الطريقة:

get 'photos/:id', to: 'photos#show', id: /[A-Z]\d{5}/

تأخذ ‎:constraints تعبيرات نمطية مع القيود التي لا يمكن أن تستخدم مثبتات التعبير النمطي (regexp anchors). على سبيل المثال، لن يعمل التوجيه التالي:

get '/:id', to: 'articles#show', constraints: { id: /^\d/ }

ومع ذلك، لاحظ أنك لست بحاجة إلى استخدام نقاط تثبيت لأن جميع المسارات الموجهة المثبتة في البداية. على سبيل المثال، تسمح التوجيهات التالية لـ articles التي لها قيم to_param مثل 1-hello-world والتي تبدأ دائمًا برقم ولـ users التي لها قيم to_param مثل david التي لا تبدأ برقم بمشاركة مجال الاسم الجذر (root namespace):

get '/:id', to: 'articles#show', constraints: { id: /\d.+/ }
get '/:username', to: 'users#show'

قيود على أساس الطلب

يمكنك أيضًا تقييد مسار موجه استنادًا إلى أي تابع في كائن الطلب Request التي يعيد سلسلة نصية.

يمكنك تحديد القيد على أساس الطلب بنفس الطريقة التي تحدد بها قيد الجزء (segment constraint):

get 'photos', to: 'photos#index', constraints: { subdomain: 'admin' }

يمكنك أيضًا تحديد القيود في نموذج الكتلة:

namespace :admin do
  constraints subdomain: 'admin' do
    resources :photos
  end
end

ملاحظة: تعمل قيود الطلب عن طريق استدعاء تابع في كائن الطلب Request يحمل نفس الاسم مثل مفتاح التجزئة (hash) ثم مقارنة القيمة المعادة بقيمة الجدول Hash. لذلك، يجب أن تتطابق قيم القيد مع نوع إرجاع تابع كائن الطلب المقابل. على سبيل المثال: { 'constraints: { subdomain: 'api سيطابق نطاقًا فرعيًا لواجهة برمجة التطبيق كما هو متوقع، ولكن لن يكون باستخدام رمز مثل

{ constraints: { subdomain: :api، نظرًا لأن request.subdomain يعرض "api" كسلسلة نصية.

ملاحظة: هناك استثناء للقيد format وهو في حين أنه تابع في كائن الطلب Request، وهو أيضًا معامل اختياري ضمني في كل مسار. يكون لقيود الشريحة الأسبقية وتطبق قيود التنسيق فقط عند فرضها عبر التجزئة. على سبيل المثال، get 'foo', constraints: { format: 'json' }‎ سيطابق GET  /foo لأن التنسيق اختياري بشكل افتراضي. ومع ذلك، يمكنك استخدام تعابير lambda مثل { get 'foo', constraints: lambda { |req| req.format == :json وسيتطابق مسار التوجيه مع طلبيات JSON الصريحة فقط.

القيود المتقدمة

إذا كان لديك قيد أكثر تقدمًا، يمكنك توفير كائن يستجيب إلى matches?‎ التي يجب أن تستخدمها ريلز. لنفترض أنك تريد توجيه جميع المستخدمين في القائمة السوداء إلى BlacklistController، يمكنك القيام بذلك بالشكل التالي:

class BlacklistConstraint
  def initialize
    @ips = Blacklist.retrieve_ips
  end
 
  def matches?(request)
    @ips.include?(request.remote_ip)
  end
end
 
Rails.application.routes.draw do
  get '*path', to: 'blacklist#index',
    constraints: BlacklistConstraint.new
end

يمكنك أيضا تحديد القيود على أنها تعابير lambda:

Rails.application.routes.draw do
  get '*path', to: 'blacklist#index',
    constraints: lambda { |request| Blacklist.retrieve_ips.include?(request.remote_ip) }
end

كل من التابع matches?‎ وتعابير lambda تحصل على كائن الطلب Request كوسيط.

التوجيه النمطي والأجزاء المتطابقة بالمحارف الخاصة

التوجيه النمطي (Route globbing) هو طريقة لتحديد أنه يجب مطابقة معامل معين مع جميع الأجزاء المتبقية من المسار. فمثلًا:

get 'photos/*other', to: 'photos#unknown'

سيطابق هذا التوجيه المسار photos/12 أو /photos/long/path/to/12 مع تعيين [params[:other إلى "12" أو "long/path/to/12". تسمى الأجزاء المسبوقة بالرمز * باسم "الأجزاء المتطابقة بالمحارف الخاصة" (wildcard segments). يمكن أن تظهر الأجزاء المتطابقة بالمحارف الخاصة في أي مكان في المسار. فمثلًا:

get 'books/*section/:title', to: 'books#show'

من شأنه أن يطابق books/some/section/last-words-a-memoir مع [params[:section الذي يساوي 'some/section'، ومع [params [:title الذي يساوي 'last-words-a-memoir'. من الناحية الفنية، يمكن أن يحتوي المسار على أكثر من جزء واحدة متطابق. يعين المطابق (matcher) الأجزاء إلى معاملات بطريقة بديهية. فمثلًا:

get '*a/foo/*b', to: 'test#index'

سيطابق zoo/woo/foo/bar/baz مع [params[:a الذي يساوي 'zoo/woo'، ومع [params[:b الذي يساوي 'bar/baz'. ملاحظة: عبر طلب '‎/foo/bar.json'، ستكون [params[:pages مساوية لـ '‎/foo/bar' مع تنسيق طلب JSON. إذا كنت تريد استعادة سلوك الإصدار ‎3.0.‎x القديم، فيمكنك توفير format: false بالشكل التالي:

get '*pages', to: 'pages#show', format: false

إذا كنت تريد جعل جزء التنسيق إلزاميًا، وبذلك لا يمكن حذفه، فيمكنك توفير format: true بالشكل التالي:

get '*pages', to: 'pages#show', format: true

إعادة التوجيه

يمكنك إعادة توجيه (redirect) أي مسار إلى مسار آخر باستخدام مساعد إعادة التوجيه redirect في المسار الموجه الخاص بك:

get '/stories', to: redirect('/articles')

يمكنك أيضًا إعادة استخدام أجزاء ديناميكية من المطابقة في المسار لإعادة التوجيه إلى:

get '/stories/:name', to: redirect('/articles/%{name}')

يمكنك أيضًا توفير حظر لإعادة التوجيه، والذي يتلقى معاملات المسار الرمزية وكائن الطلب Request:

get '/stories/:name', to: redirect { |path_params, req| "/articles/#{path_params[:name].pluralize}" }
get '/stories', to: redirect { |path_params, req| "/articles/#{req.subdomain}" }

يرجى ملاحظة أن إعادة التوجيه الافتراضية هي عملية إعادة توجيه 301 "تم نقلها بشكل دائم" (Moved Permanently). ضع في اعتبارك أن بعض متصفحات الويب أو الخوادم الوسيطة (proxy servers) ستخزن هذا النوع من إعادة التوجيه، مما يجعل الصفحة القديمة غير قابلة للوصول. يمكنك استخدام الخيار ‎:status لتغيير حالة الاستجابة:

get '/stories/:name', to: redirect('/articles/%{name}', status: 302)

في جميع هذه الحالات، إذا لم تقدم المضيف الأساسي (http://www.example.com)، فستأخذ ريلز هذه التفاصيل من الطلب الحالي.

التوجيه إلى تطبيقات Rack

بدلاً من سلسلة نصية مثل 'articles#index'، والتي تتطابق مع الإجراء index في ArticlesController، يمكنك تحديد أي تطبيق Rack كنقطة نهاية للمطابق:

match '/application.js', to: MyRackApp, via: :all

طالما يستجيب MyRackApp لاستدعاء ويعيد [status, headers, body]، لن يعرف جهاز التوجيه الفرق بين تطبيق Rack والإجراء. هذا هو الاستخدام المناسب لـ via: :all، كما تريد السماح لتطبيق Rack الخاص بك بالتعامل مع جميع الأفعال التي تراها مناسبة.

ملاحظة: يوسع 'articles#index' فعليًا إلى (ArticlesController.action(:index، التي تُرجع تطبيق Rack صالحًا.

إذا قمت بتحديد تطبيق Rack كنقطة نهاية للمطابقة، فتذكر أنَّ التوجيه لن يتغير في تطبيق الاستلام. مع التوجيه التالي، يجب أن يتوقع تطبيق Rack أن يكون المسار هو ‎/admin:

match '/admin', to: AdminApp, via: :all

إذا كنت تفضل أن يتلقى تطبيق Rack طلبات على المسار الجذر بدلًا من ذلك، فاستخدم mount:

mount AdminApp, at: '/admin'

استخدام الجذر

يمكنك تحديد ما يجب أن تسلكه Rails عند توجيه '/' باستخدام التابع root:

root to: 'pages#main'
root 'pages#main' # shortcut for the abov

يجب وضع مسار الجذر أعلى الملف، لأنه المسار الأكثر شيوعًا ويجب مطابقته أولاً.

ملاحظة: يوجه مسار الجذر فقط طلبيات GET إلى الإجراء.

يمكنك أيضًا استخدام الجذر داخل مجالات الأسماء والنطاقات أيضًا. فمثلًا:

namespace :admin do
  root to: "admin#index"
end
 
root to: "home#index"

توجيهات محارف يونيكود

يمكنك تحديد توجيهات محارف يونيكود مباشرةً. فمثلًا:

get 'こんにちは', to: 'welcome#index'

التوجيهات المباشرة

يمكنك إنشاء مساعدين مخصصين لعناوين URL مباشرةً. فمثلًا:

direct :homepage do
  "http://www.rubyonrails.org"
end
 
# >> homepage_url
# => "http://www.rubyonrails.org"

يجب أن تعيد الكتلة وسيطًا صالحًا للتابع url_for. لذلك، يمكنك تمرير سلسلة URL صحيحة، أو جدول Hash، أو مصفوفة، أو نسخة من Active Model، أو صنف من Active Model:

direct :commentable do |model|
  [ model, anchor: model.dom_id ]
end
 
direct :main do
  { controller: 'pages', action: 'index', subdomain: 'www' }
end

استخدام resolve

يسمح التابع resolve بتخصيص تعيينات متعددة الأشكال (polymorphic mapping) للنماذج. فمثلًا:

resource :basket
 
resolve("Basket") { [:basket] }
<%= form_for @basket do |form| %>
  <!-- basket form -->
<% end %>

سيؤدي ذلك إلى إنشاء عنوان URL هو  ‎/basket بدلًا من العنوان ‎/baskets/:id المعتاد.

تخصيص التوجيهات كثيرة الموارد

في حين أن التوجيهات والمساعدات الافتراضية التي أنشئت بواسطة resources :articles عادةً ما تخدمك جيدًا، فقد تحتاج إلى تخصيصها بطريقة ما. تسمح لك ريلز بتخصيص أي جزء عام من المساعدين كثيري الموارد (resourceful helpers).

تحديد وحدة تحكم لاستخدامها

يتيح لك الخيار ‎:controller تحديد وحدة تحكم بشكل صريح لاستخدامها في المورد. فمثلًا:

resources :photos, controller: 'images'

سيتعرف على المسارات الواردة التي تبدأ بـ ‎/photos ولكن سيوجه إلى وحدة التحكم في Images:

فعل HTTP المسار وحدة التحكم#الإجراء مسمى المساعد
GET ‎/photos images#index photos_path
GET ‎/photos/new images#new new_photo_path
POST ‎/photos images#create photos_path
GET ‎/photos/:id images#show photo_path(:id)‎
GET ‎/photos/:id/edit images#edit edit_photo_path(:id)‎
PATCH/PUT ‎/photos/:id images#update photo_path(:id)‎
DELETE ‎/photos/:id images#destroy photo_path(:id)‎

ملاحظة: استخدم photos_photo و new_photo_path وما إلى ذلك لإنشاء مسارات لهذا المورد.

بالنسبة لوحدات تحكم ذات مجال أسماء (namespaced controllers)، يمكنك استخدام تدوين المجلد (directory notation). فمثلًا:

resources :user_permissions, controller: 'admin/user_permissions'

هذا سوف يوجهه إلى وحدة التحكم Admin::UserPermissions.

ملاحظة: تدوين المجلد مدعومٌ فقط. يمكن أن يؤدي تحديد وحدة التحكم بتدوين روبي الثابت

(مثل controller: 'Admin::UserPermissions'‎) إلى مشاكل في التوجيه ينتج عنها تحذيرات.

تحديد القيود

يمكنك استخدام الخيار ‎:constraints لتحديد التنسيق المطلوب على المعرّف id الضمني. فمثلًا:

resources :photos, constraints: { id: /[A-Z][A-Z][0-9]+/ }

يقيد هذا الاعلان المعامل id: ليطابق التعبير المعتاد الموفر. لذلك، في هذه الحالة، لم يعد جهاز التوجيه يتطابق مع ‎/photos/1 مع هذا المسار. بدلًا من ذلك، إنَّ ‎/photos/RR27 هي من ستتطابق. يمكنك تحديد قيد واحد لتطبيقه على عدد من المسارات باستخدام نموذج الكتلة:

constraints(id: /[A-Z][A-Z][0-9]+/) do
  resources :photos
  resources :accounts
end

ملاحظة: بالطبع، يمكنك استخدام القيود الأكثر تقدمًا المتوفرة في المسارات غير كثيرة الموارد في هذا السياق.

فائدة: بشكل افتراضي، لا يقبل المعامل ‎:id النقاط وذلك لأن النقطة تستخدم كفاصل للمسارات المنسقة. إذا كنت بحاجة إلى استخدام نقطة داخل ‎:id، فأدخل قيدًا يتجاوز هذا مثل id: /[^\/]+/‎ يسمح بأي شيء باستثناء الشرطة المائلة.

تجاوز المساعدين المسماة

يسمح لك الخيار ‎:as بتجاوز التسمية العادية لمساعدي مسار معين. فمثلًا:

resources :photos, as: 'images'

سوف يتعرف على المسارات الواردة التي تبدأ بـ ‎/photos ويوجه الطلبات إلى PhotosController، ولكن استخدم الخيار ‎:as لتسمية المساعدين.

فعل HTTP المسار وحدة التحكم # الإجراء مسمى المساعد
GET ‎/photos photos#index images_path
GET ‎/photos/new photos#new new_image_path
POST ‎/photos photos#create images_path
GET ‎/photos/:id photos#show image_path(:id)‎
GET ‎/photos/:id/edit photos#edit edit_image_path(:id)‎
PATCH/PUT ‎/photos/:id photos#update image_path(:id)‎
DELETE ‎/photos/:id photos#destroy image_path(:id)‎

استبدال الأجزاء الجديدة وتعديلها

يتيح لك الخيار ‎:path_names استبدال الأجزاء الجديدة وتعديلها تلقائيًا في المسارات:

resources :photos, path_names: { new: 'make', edit: 'change' }

قد يتسبب هذا في التعرف على المسارات مثل:

/photos/make

/photos/1/change

ملاحظة: لا تتغيير أسماء الإجراءات الفعلية بواسطة هذا الخيار. سيستمر المساران المعروضان في مسار التوجيه إلى الإجراءات الجديدة وتعديلها. فائدة: إذا وجدت نفسك ترغب في تغيير هذا الخيار بشكل موحد لجميع مسارات التوجيه لديك، فيمكنك استخدام النطاق.

scope path_names: { new: 'make' } do
  # rest of your routes
end

إضافة بادئة لمساعدي مسار التوجيه المسمى

يمكنك استخدام الخيار ‎:as لإضافة بادئة لمساعدي مسار التوجيه المسمى الذي تُنشئُه ريلز لمسار التوجيه. استخدم هذا الخيار لمنع تضارب الأسماء بين المسارات باستخدام نطاق مسار. فمثلًا:

scope 'admin' do
  resources :photos, as: 'admin_photos'
end
 
resources :photos

سيوفر ذلك مساعدين لمسارات التوجيه، مثل admin_photos_path و new_admin_photo_path وما إلى ذلك. لإضافة بادئة لمجموعة من مساعدي مسارات التوجيه، استخدم الخيار ‎:as مع النطاق:

scope 'admin', as: 'admin' do
  resources :photos, :accounts
end
 
resources :photos, :accounts

سيؤدي ذلك إلى إنشاء مسارات مثل admin_photos_path و admin_accounts_path والتي تعين ‎/admin /photos و ‎/admin/accounts على التوالي.

ملاحظة: سيضيف نطاق مجال الأسماء تلقائيًا الخيار ‎:as بالإضافة إلى البادئات ‎:module و ‎:path.

يمكن إضافة بادئة لمسارات التوجيه مع معامل مسمى أيضًا:

scope ':username' do
  resources :articles
end

سيزودك هذا بعناوين URL مثل ‎/bob/articles/1 وسيسمح لك بمراجعة الجزء username من المسار

بالشكل [params[:username في وحدات التحكم والمساعدين والواجهات.

تقييد مسارات التوجيه التي أنشئت

بشكل افتراضي، تنشئ ريلز مسارات توجيه للإجراءات الافتراضية السبعة (index، و show، و new، و create، و edit، و update، و destroy) لكل مسار RESTful في التطبيق الخاص بك. يمكنك استخدام الخيارات ‎:only و ‎:except لضبط هذا السلوك. الخيار ‎:only يخبر ريلز بإنشاء المسارات المحددة فقط:

resources :photos, only: [:index, :show]

الآن، قد ينجح طلب GET إلى ‎/photos، ولكن سيخفق طلب POST إلى ‎/photos (والذي عادةً ما يوجه إلى الإجراء create). الخيار ‎:except يحدد المسار أو قائمة المسارات التي لا يجب على ريلز أن تنشئها:

resources :photos, except: :destroy

في هذه الحالة، ستنشئ ريلز  كل المسارات العادية باستثناء مسار التدمير (طلب DELETE إلى ‎/photos/:id).

فائدة: إذا كان التطبيق يحتوي على العديد من مسارات RESTful، فاستعمال ‎:only و ‎:except لتوليد مسارات التوجيه التي تحتاجها فعليًا فقط يمكن من تقليل استخدام الذاكرة وتسريع عملية التوجيه.

المسارات المبدَّلة

باستخدام scope، يمكننا تغيير أسماء المسارات التي أنشئت بواسطة resources:

scope(path_names: { new: 'neu', edit: 'bearbeiten' }) do
  resources :categories, path: 'kategorien'
end

تنشئ ريلز الآن مسارات موجهة إلى CategoriesContator.

فعل HTTP المسار وحدة التحكم # الإجراء مسمى المساعد
GET ‎/kategorien categories#index categories_path
GET ‎/kategorien/neu categories#new new_category_path
POST ‎/kategorien categories#create categories_path
GET ‎/kategorien/:id categories#show category_path(:id)‎
GET ‎/kategorien/:id/bearbeiten categories#edit edit_category_path(:id)‎
PATCH/PUT ‎/kategorien/:id categories#update category_path(:id)‎
DELETE /kategorien/:id categories#destroy category_path(:id)‎

استبدال النموذج المفرد

إذا كنت تريد تعريف الشكل المفرد لمورد، فيجب عليك إضافة قواعد إضافية إلى Inflector:

ActiveSupport::Inflector.inflections do |inflect|
  inflect.irregular 'tooth', 'teeth'
end

استخدام ‎:as في الموارد المتداخلة

الخيار ‎:as يستبدل الاسم الذي أُنشِأ تلقائيًا للمورد في مساعدي المسارات الموجهة المتداخلة. فمثلًا:

resources :magazines do
  resources :ads, as: 'periodical_ads'
end

سيؤدي ذلك إلى إنشاء مساعدين للتوجيه مثل magazine_periodical_ads_url و edit_magazine_periodical_ad_path.

استبدال معاملات المسار الموجه المسماة

يستبدل الخيار param: معرف المورد ‎:id الافتراضي (اسم الجزء الديناميكي المستخدم لإنشاء المسارات الموجهة). يمكنك الوصول إلى هذا الجزء من وحدة التحكم باستخدام params[<:param>]‎.

resources :videos, param: :identifier
     videos GET  /videos(.:format)                  videos#index
            POST /videos(.:format)                  videos#create
 new_videos GET  /videos/new(.:format)              videos#new
edit_videos GET  /videos/:identifier/edit(.:format) videos#edit
Video.find_by(identifier: params[:identifier])

يمكنك استبدال ActiveRecord::Base#to_param لنموذج ذي صلة لإنشاء عنوان URL:

class Video < ApplicationRecord
  def to_param
    identifier
  end
end
 
video = Video.find_by(identifier: "Roman-Holiday")
edit_videos_path(video) # => "/videos/Roman-Holiday"

فحص واختبار المسارات الموجهة

توفر ريلز أدوات ووسائل لفحص واختبار المسارات الموجهة الخاصة بك.

قائمة المسارات الحالية

للحصول على قائمة كاملة بالمسارات المتاحة في التطبيق الخاص بك، قم بزيارة http://localhost:3000/rails/info/routes في المستعرض الخاص بك أثناء تشغيل خادمك في بيئة التطوير. يمكنك أيضًا تنفيذ الأمر rails routes في الطرفية الخاصة بك لإنتاج نفس المخرجات.

ستقوم كلا الطريقتين بإدراج جميع مساراتك الموجهة بنفس الترتيب الذي تظهر به في config/routes.rb. لكل مسار، سترى:

  • اسم المسار الموجه (إن وجد).
  • الفعل HTTP المستخدم (إذا كان المسار لا يستجيب لكل الأفعال).
  • نمط عنوان URL المراد مطابقته.
  • معاملات التوجيه للمسار الموجه.

على سبيل المثال، إليك مقطع صغير من مخرجات الأمر rails routes لمسار RESTful الموجه:

    users GET    /users(.:format)          users#index
          POST   /users(.:format)          users#create
 new_user GET    /users/new(.:format)      users#new
edit_user GET    /users/:id/edit(.:format) users#edit

يمكنك البحث من خلال مساراتك الموجهة باستخدام الخيار grep: -g. يظهر هذا الأمر أي مسارات موجهة تتطابق جزئيًا مع اسم تابع مساعد العنوان URL، أو فعل HTTP، أو مسار عنوان URL.

$ bin/rails routes -g new_comment
$ bin/rails routes -g POST
$ bin/rails routes -g admin

إذا كنت ترغب فقط في رؤية المسارات الموجهة التي تعين إلى وحدة تحكم معينة، فهناك الخيار ‎-c:

$ bin/rails routes -c users
$ bin/rails routes -c admin/users
$ bin/rails routes -c Comments
$ bin/rails routes -c Articles::CommentsController

فائدة: ستجد أن المخرجات من الأمر rails routes أكثر قابلية للقراءة إذا قمت بتوسيع نافذة طرفيتك حتى لا تلتف سطور المخرجات.

اختبار المسارات الموجهة

يجب تضمين المسارات الموجهة في إستراتيجية الاختبار (تمامًا مثل بقية تطبيقك). تقدم ريلز ثلاثة تأكيدات مضمنة مصممة لجعل عملية اختبار المسارات الموجهة أكثر بساطة:

  • Assert_generates
  • Assert_recognizes
  • assert_routing

تأكيد assert_generates

يؤكد assert_generates أن مجموعة معينة من الخيارات تولد مسارًا معينًا ويمكن استخدامها مع المسارات الافتراضية أو المسارات المخصصة. إليك المثال التالي:

assert_generates '/photos/1', { controller: 'photos', action: 'show', id: '1' }
assert_generates '/about', controller: 'pages', action: 'about'

تأكيد assert_recognizes

هو عكس التأكيد assert_generates، إذ يؤكد أنه جرى التعرف على مسار معين ووُجِّه إلى مكان معين في التطبيق الخاص بك. إليك المثال التالي:

assert_recognizes({ controller: 'photos', action: 'show', id: '1' }, '/photos/1')

يمكنك توفير الوسيط method: لتحديد فعل HTTP:

assert_recognizes({ controller: 'photos', action: 'create' }, { path: 'photos', method: :post })

تأكيد assert_routing

يتحقق تأكيد assert_routing من الطريقتين: يختبر أن المسار يولد الخيارات، وأن الخيارات تولد المسار. وبالتالي، فهو يجمع بين وظائف assert_generates و assert_recognizes:

assert_routing({ path: 'photos', method: :post }, { controller: 'photos', action: 'create' })

المصادر