سؤال

أنا مبتدئ في القضبان وحاول أداء النقد الأيسر في mysql.

هناك كائنين - المستخدم والرسالة.

المستخدم has_and_belongs_to_many رسائل، رسالة has_and_belongs_to_many المستخدمين

حاليا، ببساطة عن طريق كتابة User.Messages أحصل على استعلام متابع في وحدة التحكم

SELECT * FROM `messages` INNER JOIN `messages_users` ON `messages`.id = `messages_users`.message_id WHERE (`users_messages`.group_id = 1 )

رسالة مع مقيدة == FALSE غير متصل بأي مستخدم ولكني يمكن الوصول إليها من قبل أي مستخدم، وأحتاج إلى إضافة رسالة جمع. جميع (مقيد => خطأ) للمستخدم.

الاستعلام الذي من شأنه أن يحل مشكلتي سيكون:

select * from messages left join messages_users on messages_users.message_id=messages.id and messages_users.user_id=1 where (messages_users.user_id is NULL and messages.restricted=false) OR (messages_users.user_id=1 and messages.restricted=true);

كيف أكتبها في القضبان بأناقة قدر الإمكان؟

هل سيكون مثل

Message.find(:all,:conditions => "(messages_users.user_id is NULL and messages.restricted=false) OR (messages_users.user_id=1 and messages.restricted=true)", :joins => "left join messages_groups on messages_users.message_id=messages.id and messages_users.user_id=1 " )

أو هل يمكن أن يكون أجمل؟

أنا أستخدم القضبان 2.3.2

شكرا، بافل

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

المحلول

يبدو لي أنك تحاول سحب شيئين في هذا الاستعلام: 1) جميع الرسائل غير مرتبطة للمستخدم مع تقييد = False و 2) جميع الرسائل مرتبطة بالمستخدم الحالي مع تقييد = صحيح.

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

class Message < ActiveRecord:Base
  has_and_belongs_to_many :users

  named_scope :restricted, :conditions => {:restricted => true}
  named_scope :unrestricted, :conditions => {:restricted => false}
  named_scope :public, :conditions => "id NOT IN (SELECT DISTINCT message_id FROM messages_users)"
end

class User < ActiveRecord:Base
  has_and_belongs_to_many :messages
end

للحصول على القائمة في رمز أقل، ولكن تتطلب ضربتين من الزيارات التي يمكنك القيام بها:

@current_user.messages.restricted + Message.unrestricted.public

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

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

class Message < ActiveRecord:Base

  has_many :subscriptions
  has_many :users, :through => :subscriptions

  named_scope :restricted,   :conditions => {:restricted => true}
  named_scope :unrestricted, :conditions => {:restricted => false}
  named_scope :public, :conditions => "id NOT IN (SELECT DISTINCT message_id FROM subscriptions)"
end

class User < ActiveRecord:Base

  has_many :subscriptions
  has_many :messages, :through => :subscriptions

end

class Subscription < ActiveRecord:Base

  belongs_to :message
  belongs_to :user

end

نصائح أخرى

لماذا لا تستخدم: تشمل؟

أعتقد أن named_scopes قد تكون جوابك. في النموذج الخاص بك وضع شيء مثل:

named_scope :restricted,   :conditions => {:restricted => true}
named_scope :unrestricted, :conditions => {:restricted => false}

ثم يمكنك الاتصال بأشياء مثل:

Message.restricted
=> All restricted messages

User.first.messages.unrestricted
=> All unrestricted messages belonging to the first user.

أعتقد أن هذه العمل من خلال جمعيات Habtm.

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