رابطة القضبان المتعددة الأشكال (قاعدة البيانات القديمة)
-
22-09-2019 - |
سؤال
أنا أستخدم قاعدة بيانات قديمة ، لذلك ليس لدي أي تحكم في Datamodel. يستخدمون الكثير من طاولات الارتباط/الصلة متعددة الأشكال ، مثل هذا
create table person(per_ident, name, ...)
create table person_links(per_ident, obj_name, obj_r_ident)
create table report(rep_ident, name, ...)
أين obj_name
هو اسم الجدول ، و obj_r_ident
هو المعرف. لذلك سيتم إدراج التقارير المرتبطة على النحو التالي:
insert into person(1, ...)
insert into report(1, ...)
insert into report(2, ...)
insert into person_links(1, 'REPORT', 1)
insert into person_links(1, 'REPORT', 2)
ثم الشخص 1 سيكون لديه تقريرين مرتبطين ، 1 و 2.
أستطيع أن أفهم الفوائد المحتملة التي تحتوي على datamodel مثل هذا ، لكنني في الغالب أرى عيبًا كبيرًا واحد: استخدام القيود غير ممكن لضمان سلامة البيانات. لكن للأسف ، لا يمكنني تغيير هذا بعد الآن.
لكن لاستخدام هذا في القضبان ، كنت أنظر إلى جمعيات الأشكال المتعددة ، لكنني لم أجد طريقة لطيفة لحل هذا (بما أنني لا أستطيع تغيير أسماء الأعمدة ، ولم أجد بسهولة طريقة للقيام بذلك).
لقد توصلت إلى حل رغم ذلك. يرجى تقديم اقتراحات.
class Person < ActiveRecord::Base
set_primary_key "per_ident"
set_table_name "person"
has_and_belongs_to_many :reports,
:join_table => "person_links",
:foreign_key => "per_ident",
:association_foreign_key => "obj_r_ident",
:conditions => "OBJ_NAME='REPORT'"
end
class Report < ActiveRecord::Base
set_primary_key "rep_ident"
set_table_name "report"
has_and_belongs_to_many :persons,
:join_table => "person_links",
:foreign_key => "obj_r_ident",
:association_foreign_key => "per_ident",
:conditions => "OBJ_NAME='REPORT'"
end
هذا يعمل ، لكنني أتساءل عما إذا كان هناك حل أفضل ، باستخدام ارتباطات متعددة الأشكال.
المحلول
يمكنك تجاوز أسماء الأعمدة ، بالتأكيد ، لكن فحصًا سريعًا لواجهة برمجة تطبيقات Rails لم يظهرني في أي مكان لتجاوز عمود "النوع" متعدد الأشكال. لذلك ، لن تكون قادرًا على تعيين ذلك على "OBJ_NAME".
إنه قبيح ، لكنني أعتقد أنك ستحتاج إلى habtm لكل نوع من الكائن في الجدول الخاص بك.
أنت ربما كن قادرًا على فعل شيء مثل هذا:
{:report => 'REPORT'}.each do |sym, text|
has_and_belongs_to_many sym,
:join_table => "person_links",
:foreign_key => "obj_r_ident",
:association_foreign_key => "per_ident",
:conditions => "OBJ_NAME='#{text}'"
end
على الأقل بهذه الطريقة تبقى جميع الأشياء المشتركة جاف ويمكنك إضافة المزيد من العلاقات بسهولة.
نصائح أخرى
على الأقل اعتبارًا من القضبان 4.2.1 ، يمكنك المرور foreign_type
إلى إعلان ينتمي لتحديد اسم العمود المراد استخدامه في "نوع" الارتباط متعدد الأشكال
http://apidock.com/rails/v4.2.1/activerecord/associations/classmethods/belongs_to