একটি রেল মডেল জন্য ডিফল্ট বাছাই আদেশ?


255

আমি আমার মডেলটিতে একটি ডিফল্ট ক্রম অর্ডার নির্দিষ্ট করতে চাই।

যাতে আমি যখন .where()কোনও নির্দিষ্ট না করে এটি করি তখন এটি .order()ডিফল্ট বাছাই করে। তবে আমি যদি একটি নির্দিষ্ট করে থাকি তবে .order()এটি ডিফল্টকে ওভাররাইড করে।

উত্তর:


544

default_scope

এটি রেল 4+ এর জন্য কাজ করে:

class Book < ActiveRecord::Base
  default_scope { order(created_at: :desc) }
end

রেল ২.৩, ৩ এর জন্য আপনার পরিবর্তে এটি দরকার:

default_scope order('created_at DESC')

রেল 2.x এর জন্য:

default_scope :order => 'created_at DESC'

কোথায় created_atক্ষেত্র যদি আপনি চান করা হয় ডিফল্ট কাজ করতে হবে বাছাই।

দ্রষ্টব্য: ASC হ'ল আরোহণের জন্য ব্যবহার করার কোড এবং DESC অবতরণের জন্য ( desc, নয় dsc !)।

scope

একবার আপনি অভ্যস্ত হয়ে গেলে আপনি এটি ব্যবহার করতে পারেন scope:

class Book < ActiveRecord::Base
  scope :confirmed, :conditions => { :confirmed => true }
  scope :published, :conditions => { :published => true }
end

রেল 2 এর জন্য আপনার প্রয়োজন named_scope

:publishedসুযোগ আপনাকে Book.publishedপরিবর্তে দেয় Book.find(:published => true)

যেহেতু রেলস 3 আপনি এই পদ্ধতিগুলি তাদের মধ্যে সময়সীমার সাথে একযোগে 'চেইন' করতে পারেন, সুতরাং উপরের স্কোপগুলির সাহায্যে আপনি এখন ব্যবহার করতে পারেন Book.published.confirmed

এই পদ্ধতির সাহায্যে, সত্যিকারের ফলাফল (অলস মূল্যায়ন) প্রয়োজন না হওয়া অবধি ক্যোয়ারীটি আসলে সম্পাদন করা হয় না, সুতরাং 7 টি স্কোপগুলি এক সাথে জড়িত হতে পারে তবে 7 টি পৃথক ক্যোরিয়ালি কার্যকর করতে পারফরম্যান্সের সমস্যা থেকে বাঁচতে কেবল 1 টি প্রকৃত ডাটাবেস ক্যোয়ারী তৈরি করতে পারে।

আপনি একটি প্যারামিটারে পাস যেমন একটি তারিখ বা ইউজার_আইডি ব্যবহার করতে পারেন (এমন কিছু যা রান-টাইমে পরিবর্তিত হয় এবং তাই ল্যাম্বদা সহ 'অলস মূল্যায়ন' প্রয়োজন হবে:

scope :recent_books, lambda 
  { |since_when| where("created_at >= ?", since_when) }
  # Note the `where` is making use of AREL syntax added in Rails 3.

শেষ পর্যন্ত আপনি এর সাথে ডিফল্ট সুযোগটি অক্ষম করতে পারেন:

Book.with_exclusive_scope { find(:all) } 

বা আরও ভাল:

Book.unscoped.all

যা কোনও ফিল্টার (শর্তাবলী) বা বাছাই করে (ক্রম অনুসারে) অক্ষম করবে।

মনে রাখবেন যে প্রথম সংস্করণটি রেল 2 + ​​এ কাজ করে যেখানে দ্বিতীয় (আনস্কোপড) কেবলমাত্র রেল 3 + এর জন্য


সুতরাং ... আপনি যদি ভাবছেন, হুম, সুতরাং এটি ঠিক একই পদ্ধতিগুলির মতো তবে ..., হ্যাঁ, এই স্কোপগুলি ঠিক এটিই!
এগুলি রাখার মতো def self.method_name ...code... endতবে সর্বদা রুবি হিসাবে তারা আপনার জন্য জিনিসগুলিকে আরও সহজ করার জন্য সুন্দর ছোট সিনট্যাক্টিকাল শর্টকাট (বা 'চিনি')!

প্রকৃতপক্ষে তারা শ্রেণি স্তরের পদ্ধতি হিসাবে তারা 'সমস্ত' রেকর্ডের 1 সেটটিতে কাজ করে।

তাদের ফর্ম্যাটটি পরিবর্তিত হচ্ছে, রেল 4 এর সাথে একটি কলযোগ্য বস্তুটি পাস না করে # এস্কোপ ব্যবহার করার সময় অবচয় হুঁশিয়ারি রয়েছে। উদাহরণস্বরূপ সুযোগ: লাল, যেখানে (রঙ: 'লাল') এ পরিবর্তন করতে হবে scope :red, -> { where(color: 'red') }

পার্শ্ব নোট হিসাবে, যখন ভুলভাবে ব্যবহার করা হয়, তখন ডিফল্ট _স্কোপের অপব্যবহার / অপব্যবহার করা যায়।
এটি সাধারণত ফলাফল অর্ডার দেওয়ার জন্য ব্যবহৃত whereনা হয়ে ডিফল্ট নির্বাচন ( ডিফল্টের জন্য একটি খারাপ ধারণা ) সীমাবদ্ধকরণ (ফিল্টারিং) এর মতো ক্রিয়াকলাপগুলির জন্য ব্যবহৃত হয় about
জন্য whereপছন্দসই মান নির্বাচন করে, শুধু নিয়মিত নামে সুযোগ ব্যবহার করুন। এবং ক্যোয়ারিতে সেই সুযোগটি যুক্ত করুন, উদাহরণস্বরূপ Book.all.publishedযেখানে publishedএকটি নামকৃত সুযোগ রয়েছে।

উপসংহারে, স্কোপগুলি সত্যিই দুর্দান্ত এবং আপনাকে একটি 'ফ্যাট মডেল পাতলা নিয়ামক' ডিআরওয়াইর পদ্ধতির জন্য জিনিসগুলিকে মডেলটিতে এগিয়ে যেতে সহায়তা করে।


1
দয়া করে এই পোস্টে বর্ণনা এটি ব্যবহার করার পূর্বে default_scope ব্যবহার সম্পর্কে ডেভ টমাস 'সতর্কবার্তা বিবেচনা করুন: pragdave.blogs.pragprog.com/pragdave/2012/03/...
reto

3
এটি করা কি আরও সুরক্ষিত হবে না default_scope { order("#{table_name}.created_at DESC") }?
সাইরিলচ্যাম্পিয়ার

37
রেলস 4:default_scope { order(created_at: :desc) }
মার্কাস

2
অন্তত না অনুসারে 4.2.6বাছাই করা বলে মনে হচ্ছে । updated_atcreated_at
আইন তোহ্বরী

2
@ আইনতোহরি ঠিক আছে। এটি কেবল মাত্র 4.2 রেলগুলিতে আমাকে আশ্চর্য করে। updated_atডিফল্ট অনুসারে বাছাই কেন ? : - |
ষাট

112

উপরে মাইকের দুর্দান্ত উত্তরের একটি দ্রুত আপডেট।

রেলস 4.0+ এর জন্য আপনাকে এই জাতীয় ব্লকটিতে আপনার বাছাই করা দরকার:

class Book < ActiveRecord::Base
  default_scope { order('created_at DESC') }
end

লক্ষ্য করুন যে অর্ডার স্টেটমেন্টটি কোঁকড়া ধনুর্বন্ধনী দ্বারা চিহ্নিত একটি ব্লকে রাখা হয়েছে।

তারা এটি পরিবর্তন করেছেন কারণ গতিশীল কিছুতে (বর্তমান সময়ের মতো) পাস করা খুব সহজ ছিল। এটি সমস্যাটি সরিয়ে দেয় কারণ রানটাইমগুলিতে ব্লকটি মূল্যায়ন করা হয়। আপনি যদি কোনও ব্লক ব্যবহার না করেন তবে আপনি এই ত্রুটিটি পাবেন:

কোনও ব্লক ছাড়াই # ডেফল্ট_স্কোপ কল করার জন্য সমর্থন সরিয়ে ফেলা হয়েছে। পরিবর্তে উদাহরণস্বরূপ default_scope where(color: 'red'), দয়া করে ব্যবহার করুনdefault_scope { where(color: 'red') } । (বিকল্পভাবে আপনি কেবল নিজের.ডিফল্ট_স্কোপটিকে নতুন সংজ্ঞা দিতে পারেন))

@ ড্যান যেমন নীচে তার মন্তব্যে উল্লেখ করেছেন, আপনি এর মতো আরও একটি রুবিশ বাক্য গঠন করতে পারেন:

class Book < ActiveRecord::Base
  default_scope { order(created_at: :desc) }
end

বা একাধিক কলাম সহ:

class Book < ActiveRecord::Base
  default_scope { order({begin_date: :desc}, :name) }
end

ধন্যবাদ @ ড্যান !


28
রেল In এ এটিও রচনা করা default_scope { order(created_at: :desc) }যেতে পারে যেমন , আমার মতো আপনিও রেলগুলিতে বর্গক্ষেত্রের বাক্য গঠনকে ছোট করার চেষ্টা করেন / গোঁফের মতো কলামগুলিdefault_scope { order({begin_date: :desc}, :name) }
ড্যান

1
@ ড্যান - আপনার মন্তব্যটি এসকিউএলকে কেবল সরিয়ে দেয় না, এটি আরও রুবিশ সিনট্যাক্স।
বি সেভেন

6

আপনি ডিফল্ট ক্রম অর্ডার প্রয়োগ করতে ডিফল্ট_স্কোপ ব্যবহার করতে পারেন http://api.rubyonrails.org/classes/ActiveRecord/Scoping/Default/ClassMethods.html


6
লিঙ্কটি কাজ করছে তবে default_scopeসেই পৃষ্ঠাটিতে কিছুই নেই , কারণ এটি থেকে এফেক্টরActiveRecord::Base করা হয়েছে ActiveRecord::Scoping::Default::ClassMethods( api.rubyonrails.org/class/ActtiveRecord/Scoping/Default/… )
ড্যানিয়েল রিকোভস্কি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.