سؤال

أنا جديد على واجهة الاستعلام الجديدة لـ ActiveRecord لذا ما زلت أكتشف الأشياء.

كنت آمل أن يتمكن شخص ما من شرح الفرق بين استخدام ملف scope في نموذج ActiveRecord وباستخدام طريقة الفصل فقط (على سبيل المثال self.some_method)

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

على سبيل المثال، اعتقدت أنه سيكون من المنطقي القيام بشيء مثل:

class Person
  scope :grouped_counts, group(:name).count
end

ولكن هذا لا يعمل.أحصل على هذا الخطأ:

ArgumentError: Unknown key(s): communicating, failed, matched, unmatched
    from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/activesupport-3.0.5/lib/active_support/core_ext/hash/keys.rb:43:in `assert_valid_keys'
    from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/activerecord-3.0.5/lib/active_record/relation/spawn_methods.rb:110:in `apply_finder_options'
    from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/activerecord-3.0.5/lib/active_record/named_scope.rb:110:in `block in scope'
    from (irb):48
    from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/railties-3.0.5/lib/rails/commands/console.rb:44:in `start'
    from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/railties-3.0.5/lib/rails/commands/console.rb:8:in `start'
    from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/railties-3.0.5/lib/rails/commands.rb:23:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'
r

ومع ذلك فهي تعمل كطريقة صفية

def self.grouped_counts
  group(:name).count
end

أنا مهتم بمعرفة أفكار الناس حول متى يتم استخدام النطاقات ومتى يتم استخدام أساليب الفصل.هل أنا على صواب في افتراض أن النطاق يجب أن يُرجع دائمًا علاقة، لكن طريقة الفصل يمكنها إرجاع ما تريد؟

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

المحلول

كان هناك اختلاف أكبر في Rails 2.x، نظرًا لأن النطاقات المسماة لم تنفذ استعلاماتك (حتى تتمكن من تسلسلها)، في حين أن أساليب الفصل بشكل عام تنفذ الاستعلامات (لذلك لا يمكنك ربطها)، إلا إذا قمت بلف استعلامك يدويًا في scoped(...) يتصل.

في Rails 3، يُرجع كل شيء ملفًا ActiveRecord::Relation حتى تحتاج إلى النتائج الفعلية، لذلك يمكن ربط النطاقات مقابل أساليب الفصل والعكس صحيح (طالما أن أساليب الفصل تعود ActiveRecord::Relation الكائنات، وليس بعض أنواع الكائنات الأخرى (مثل العدد)).

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

نصائح أخرى

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

على سبيل المثال ، Genacodicetagpre

عرضة للخطأ.الطريقة الصحيحة هي استخدام لامدا Genacodicetagpre

يتم تقييم كتلة Lambda بتكاسل.لذلك يتم تشغيل Date.today عند استدعاء النطاق ، لا عندما يتم تقييم الفصل.

إذا كنت تستخدم طريقة الصف ، فلن تحتاج إلى استخدام لامدا. Genacodicetagpre

لأنه باستخدام طريقة الفئة ، يتم تشغيل الكود في وقت استدعاء الطريقة.

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