سؤال

هل من الممكن إعداد علاقة مزدوجة 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 بالإضافة إلى قيود المفاتيح الخارجية في قاعدة البيانات التي تستخدمها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top