Ruby on Rails - الرجوع إلى نفس النموذج مرتين؟
-
20-09-2019 - |
سؤال
هل من الممكن إعداد علاقة مزدوجة activerecord
النماذج عبر generate scaffold
يأمر؟
على سبيل المثال ، إذا كان لدي User
نموذج و PrivateMessage
النموذج ، سيحتاج جدول PM إلى تتبع كل من sender
و recipient
.
من الواضح ، بالنسبة لعلاقة واحدة ، سأقوم بذلك:
ruby script/generate scaffold pm title:string content:string user:references
هل هناك طريقة مماثلة لإعداد علاقتين؟
أيضا ، هل هناك على أي حال لإعداد الاسم المستعار للعلاقات؟
لذا بدلاً من القول:
@message.user
يمكنك استخدام شيء مثل:
@message.sender
أو @message.recipient
أي نصيحة سيكون موضع تقدير كبير.
شكرًا.
المحلول
أضف هذا إلى النموذج الخاص بك
has_one :sender, :class_name => "User"
has_one :recipient, :class_name => "User"
وأنت قادر على الاتصال @message.sender
و @message.recipient
وكلاهما يشير إلى نموذج المستخدم.
بدلاً من user:references
في أمر إنشاءك تحتاجه sender:references
و recipient:references
نصائح أخرى
فيما يلي إجابة كاملة على هذه المشكلة ، في حالة زيارة الأشخاص الذين يزورون هذا السؤال ، يكونون جديدين لروبي على القضبان وتواجه صعوبة في وضع كل شيء معًا (كما كنت عندما نظرت لأول مرة في هذا).
تحدث بعض أجزاء الحل في ترحيلك وبعضها في نماذجك:
الهجرات
class CreatePrivateMessages < ActiveRecord::Migration
def change
create_table :private_messages do |t|
t.references :sender
t.references :recipient
end
# Rails 5+ only: add foreign keys
add_foreign_key :private_messages, :users, column: :sender_id, primary_key: :id
add_foreign_key :private_messages, :users, column: :recipient_id, primary_key: :id
end
end
أنت هنا تحدد أن هناك عمودين في هذا الجدول سيشار إليهما على أنه: المرسل و: المستلم والذين يحملان مراجعًا إلى جدول آخر. ستقوم القضبان بإنشاء أعمدة تسمى "Sender_id" و "recient_id" بالنسبة لك. في حالتنا ، سيقوم كل صفوف مرجعية في جدول المستخدمين ، لكننا نحدد ذلك في النماذج ، وليس في الترحيل.
عارضات ازياء
class PrivateMessage < ActiveRecord::Base
belongs_to :sender, :class_name => 'User'
belongs_to :recipient, :class_name => 'User'
end
تقوم هنا بإنشاء خاصية على نموذج الخصوصية المسمى: المرسل ، ثم تحديد أن هذه الخاصية مرتبطة بفئة المستخدم. سوف يبحث القضبان ، ، رؤية "الانتماء inss_to: المرسل" ، عن عمود في قاعدة البيانات الخاصة بك بعنوان "sender_id" ، والتي حددناها أعلاه ، وتستخدم ذلك لتخزين المفتاح الخارجي. ثم تفعل الشيء نفسه بالضبط للمستلم.
سيتيح لك ذلك الوصول إلى المرسل والمستلم ، كلا حالتين من نموذج المستخدم ، من خلال مثيل لنموذج الخصوصية ، مثل هذا:
@private_message.sender.name
@private_message.recipient.email
هنا نموذج المستخدم الخاص بك:
class User < ActiveRecord::Base
has_many :sent_private_messages, :class_name => 'PrivateMessage', :foreign_key => 'sender_id'
has_many :received_private_messages, :class_name => 'PrivateMessage', :foreign_key => 'recipient_id'
end
تقوم هنا بإنشاء خاصية على نموذج المستخدم المسمى: Sent_Private_Messages ، مما يحدد أن هذه الخاصية مرتبطة بنموذج الخصوصية ، وأن المفتاح الأجنبي في نموذج الخصوصية الذي يرتبط به بهذه الخاصية يسمى "sender_id". ثم تفعل الشيء نفسه للرسائل الخاصة المستلمة.
يتيح لك ذلك إرسال جميع المستخدمين المرسلة أو تلقوا رسائل خاصة عن طريق القيام بشيء مثل هذا:
@user.sent_private_messages
@user.received_private_messages
القيام بأي من هؤلاء سيعيد مجموعة من حالات نموذج الخصوصية.
....
مرحبًا ، هناك علاقة جانبية تفعل كلا النموذجين:
class Message < ActiveRecord::Base
belongs_to :sender,
:class_name => "User",
:foreign_key => "sender_id"
belongs_to :recipient,
:class_name => "User",
:foreign_key => "recipient_id"
end
class User < ActiveRecord::Base
has_many :sent,
:class_name => "Message",
:foreign_key => "sent_id"
has_many :received,
:class_name => "Message",
:foreign_key => "received_id"
end
اتمنى ان يساعدك هذا...
الإجابات أعلاه ، على الرغم من أن ممتازة ، لا تنشئ قيود مفاتيح خارجية في قاعدة البيانات ، بدلاً من ذلك فقط إنشاء فهارس وأعمدة Bigint. لضمان فرض قيود المفاتيح الخارجية ، أضف ما يلي إلى ترحيلك:
class CreatePrivateMessages < ActiveRecord::Migration[5.1]
def change
create_table :private_messages do |t|
t.references :sender
t.references :recipient
end
add_foreign_key :private_messages, :users, column: :sender_id, primary_key: :id
add_foreign_key :private_messages, :users, column: :recipient_id, primary_key: :id
end
end
سيضمن ذلك إنشاء المؤشرات على sender_id
و recipient_id
بالإضافة إلى قيود المفاتيح الخارجية في قاعدة البيانات التي تستخدمها.