سؤال

لدي النماذج الثلاثة التالية: المستخدم والمشروع والمهمة.

مستخدم has_many المشاريع من خلال مهمة. ومع ذلك ، فإن المهمة لديها بالفعل اثنين المفاتيح الأجنبية التي تتعلق بالمستخدم: user_id (يمثل المستخدم الذي تم تعيينه للمشروع) و completer_id (يمثل المستخدم الذي أكمل المشروع).

غالباً، user_id و completer_id سيكون هو نفسه (إذا كان المستخدم الذي تم تعيينه في المشروع يكمله). ومع ذلك ، إذا أكملها مستخدم آخر ، فسيكون user_id و completer_id مختلفًا.

في نموذج المستخدم الخاص بي ، لدي ما يلي:

class User < ActiveRecord::Base
  has_many   :assignments
  has_many   :incomplete_assignments, :class_name => 'Assignment',
    :conditions  => 'completer_id IS NULL'
  has_many   :completed_assignments, :class_name => 'Assignment',
    :foreign_key => 'completer_id'

  # this is the important one
  has_many   :incomplete_projects,
    :through     => :assignments,
    :source      => :project,
    :conditions  => 'completer_id IS NULL'
end

أود أن أجعل جمعية أخرى ، تسمى :completed_projects, الذي يستخدم completer_id كمفتاح خارجي للمستخدم في :through النموذج بدلاً من :user_id. هل من الممكن القيام بذلك؟

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

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

هل كانت مفيدة؟

المحلول

يمكنك دائمًا استخدام SQL للاختيار إذا لم يتمكن ActivereCord من التعبير بسهولة عن العلاقة خارج الصندوق:

has_many :completed_projects,
:class_name => "Project",
:finder_sql => 'SELECT p.* FROM projects p ' +
  'INNER JOIN assignments a ON p.id=a.project_id ' +
  'INNER JOIN users u on u.id=a.completer_id ' +
  'WHERE u.id=#{id}'

نصائح أخرى

هل لديك بيانات ميتا أخرى في جدول المهام الخاصة بك؟

إذا لم يكن الأمر كذلك ، فسوف أستخدم HABTM وإضافة COMMENTER_ID إلى جدول المشاريع بدلاً من ذلك ، فمن المنطقي العيش هناك على أي حال.

إذا كنت بحاجة/تريد استخدام HAS_MANY: من خلالك ، يمكنك النظر في استخدام name_scopes (تصريح إصدار القضبان) حتى تتمكن من القول user.projects.completed و user.projects.incomplete

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