نطاق ActiveRecord Rails 3 مقابل طريقة الفئة
-
29-10-2019 - |
سؤال
أنا جديد على واجهة الاستعلام الجديدة لـ 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
لأنه باستخدام طريقة الفئة ، يتم تشغيل الكود في وقت استدعاء الطريقة.