একটি রেল ডিফল্ট_স্কোপ ওভাররাইড করা


155

আমার যদি ডিফল্ট-স্কোপ সহ অ্যাক্টিভেকর্ড :: বেস মডেল থাকে:

class Foo < ActiveRecord::Base

  default_scope :conditions => ["bar = ?",bar]

end

শর্তগুলি ব্যবহার Foo.find না করে কি কোনও উপায় আছে default_scope? অন্য কথায়, আপনি কি কোনও ডিফল্ট সুযোগকে ওভাররাইড করতে পারেন?

আমি চিন্তা করে যে নামে 'ডিফল্ট' ব্যবহার সুপারিশ করবে এটা ছিল overridable, অন্যথায় এটি এরকম কিছু বলা হবে global_scope, ঠিক?


উত্তর:


151

সংক্ষিপ্ত উত্তর: default_scopeআপনার সত্যিকারের প্রয়োজন না হলে ব্যবহার করবেন না । নামযুক্ত স্কোপগুলি নিয়ে আপনি সম্ভবত আরও ভাল থাকবেন। যা বলেছিল, আপনার with_exclusive_scopeযদি প্রয়োজন হয় তবে আপনি ডিফল্ট স্কোপ ওভাররাইড করতে পারেন ।

কটাক্ষপাত আছে এই প্রশ্নের আরো বিস্তারিত জানার জন্য।


পূর্ববর্তী প্রশ্নের লিঙ্কের জন্য ধন্যবাদ
গ্যারেথ

10
> আপনার যদি সত্যিই না থাকে তবে ডিফল্ট_স্কোপ ব্যবহার করবেন না। একটি দুর্দান্ত পরামর্শ! ধন্যবাদ!
ইনস্টলার

2
আসলেই সত্য. ব্যবহার করা default_scopeভাল ধারণা মত মনে হতে পারে তবে সম্ভবত আপনার অ্যাপ্লিকেশন চলাকালীন একাধিক মাথা ব্যাথার কারণ হতে পারে।
থোম্যাক্স


1
আপনি কিছুটা বাড়িয়ে বলছেন স্যার। default_scopeএকটি দুর্দান্ত সরঞ্জাম এবং এমন পরিস্থিতি রয়েছে যেখানে আপনি অন্য কোনও উপায়ে পারতেন তবে default_scopeএটি করা ঠিক কাজ just উদাহরণস্বরূপ, যখন আপনার Productকাছে একটি inactiveপতাকা রয়েছে এমন একটি মডেল থাকে তখন default_scope { where inactive: false }99% বা ক্ষেত্রে আপনি কোনও নিষ্ক্রিয় পণ্য প্রদর্শন করতে চাইবেন না সেহেতু একটি সেট করা সবচেয়ে ভাল কাজ। তারপরে আপনি কেবলমাত্র unscopedবাকি 1% কেসগুলি কল করবেন যা সম্ভবত একটি অ্যাডমিন প্যানেল।
পেদ্রোজথ

215

কারাগারে 3:

foos = Foo.unscoped.where(:baz => baz)

58
এটির একটি পার্শ্ব প্রতিক্রিয়া রয়েছে, যদি পোস্টে_মনি মন্তব্য, Post.first.comments.unscoped সমস্ত মন্তব্য প্রত্যাবর্তন করে।
এনরিকো কারলেসো

3
এটি সত্যিই কিছুক্ষণের জন্য আমাকে খারাপ করে দিয়েছে। বিশেষত যদি আপনি এটি কোনও def self.random; unscoped.order('rand()'); endশ্রেণিবদ্ধ পদ্ধতিতে রাখেন যেমন: অনস্কেপড তার পূর্বে সমস্ত স্ক্যুয়াল অপসারণ করে, কেবলমাত্র ডিফল্ট_স্কোপের আওতায় তালিকাভুক্ত নয়। প্রযুক্তিগতভাবে সঠিক উত্তর দেওয়ার সময়, সতর্কতা অবলম্বন করুনunstopped
স্নেমেটস

7
সতর্কবার্তা! আনস্কোপড কেবলমাত্র ডিফল্ট_স্কোপটি সরাবে না, এটি ইতিমধ্যে অন্য মন্তব্যে বলা হয়েছিল তবে এটি সত্যিই জিনিসগুলির সাথে বিশৃঙ্খলা করতে পারে।
dsimard

15
থাম্বের একটি ভাল নিয়ম কেবল unscopedতখনই যখন এটি সরাসরি কোনও মডেল অনুসরণ করতে পারে, উদাহরণস্বরূপ Foo.unscoped.blah()ঠিক আছে তবে কখনই হয় না Foo.blah().unscoped
গ্রান্ট বার্চমিয়ার

stackoverflow.com/questions/1834159/... পার্শ্ব প্রতিক্রিয়া এনরিকো উল্লেখ কাজ করে
wbharding

107

আপনার যদি যা দরকার তা হল সংজ্ঞায়িত ক্রমটি পরিবর্তন করা default_scope, আপনি reorderপদ্ধতিটি ব্যবহার করতে পারেন ।

class Foo < ActiveRecord::Base
  default_scope order('created_at desc')
end

Foo.reorder('created_at asc')

নিম্নলিখিত এসকিউএল চালায়:

SELECT * FROM "foos" ORDER BY created_at asc

3
টিপ: মত একটি স্কোপ সংজ্ঞায়িত করুন scope :without_default_order, -> { reorder("") }এবং আপনি যেমন Foo.without_default_order.order("created_at ASC")কিছু করতে পারেন তেমন কিছু পরিস্থিতিতে এটি আরও ভাল পড়ে (সম্ভবত এই সঠিক পরিস্থিতিটি নয়, তবে আমার একটি ছিল)।
হেনরিক এন

আমার জন্য এটি পুনরায় অর্ডার করলেন। অনেক ধন্যবাদ!
আন্দ্রে জিম্পেল

49

যেহেতু 4.1আপনি ActiveRecord::QueryMethods#unscopeডিফল্ট সুযোগের সাথে লড়াই করতে ব্যবহার করতে পারেন :

class User < ActiveRecord::Base
  default_scope { where tester: false }
  scope :testers, -> { unscope(:where).where tester: true }
  scope :with_testers, -> { unscope(:where).where tester: [true, false] }
  # ...
end

এটা বর্তমানে করা সম্ভব unscopeভালো জিনিস: :where, :select, :group, :order, :lock, :limit, :offset, :joins, :includes, :from, :readonly, :having

তবে তবুও দয়া করে default_scopeআপনি যদি ব্যবহার করতে পারেন তবে এড়িয়ে চলুন । এটি আপনার নিজের ভালোর জন্য।


এই উত্তরটি বেশি হওয়া উচিত
স্টিফেন করউইন

14

আপনি with_exclusive_scopeপদ্ধতিটি ব্যবহার করে একটি ডিফল্ট স্কোপ ওভাররাইড করতে পারেন । তাই:

foos = Foo.with_exclusive_scope { :conditions => ["baz = ?", baz] }

3
সত্য নয়, এটি সবেমাত্র স্থানান্তরিত হয়েছে: apidock.com/rails/ActtiveRecord/Scoping/ClassMethods/…
কেভিন

5

রেল 3 ডিফল্ট_স্কোপটি রেল 2 এর মতো ওভাররাইড হয়ে যায় বলে মনে হয় না।

যেমন

class Foo < ActiveRecord::Base
  belongs_to :bar
  default_scope :order=>"created_at desc"
end

class Bar < ActiveRecord::Base
  has_many :foos
end

> Bar.foos
  SELECT * from Foo where bar_id = 2 order by "created_at desc";
> Bar.unscoped.foos
  SELECT * from Foo;  (WRONG!  removes the "has" relationship)
> Bar.foos( :order=>"created_at asc" )  # trying to override ordering
  SELECT * from Foo where bar_id = 2 order by "created_at desc, created_at asc"

আমার অ্যাপে, পোস্টগ্রেএসকিউএল ব্যবহার করে, ডিফল্ট স্কোপে ক্রম WINS। আমি আমার সমস্ত ডিফল্ট_স্কোপ অপসারণ করছি এবং এটিকে সব জায়গায় স্পষ্টভাবে কোডিং করছি।

পিটফল রেলস 3!


1
আপনার ব্যবহার করতে হবেBar.foos.reorder(:created_at => :asc)
ইভান স্টানা

5

রেল 3+ এর সাথে আপনি আনস্কোপড এবং মার্জারের সংমিশ্রণটি ব্যবহার করতে পারেন:

# model User has a default scope
query = User.where(email: "foo@example.com")

# get rid of default scope and then merge the conditions
query = query.unscoped.merge(query)

এটি আমার পক্ষে কাজ করেছিল, প্রথমে আনস্কোপ না করে কল করা (4..২ রেয়েল):User.unscoped.where(email: "foo@example.com")
নিক ১

3

Ails.১+ রেলগুলিতে (এবং সম্ভবত এর আগেও তবে এটি পরীক্ষা করেছি এটি 5.1-তে কাজ করে) একটি নির্দিষ্ট কলামটি আনস্কোপ করা সম্ভব, যা ইমো হ'ল এমন একটি ফ্যাশনকে অপসারণের জন্য আদর্শ সমাধান যা default_scopeকোনও নামকৃত সুযোগের ভিতরে ব্যবহার করা যেতে পারে can ওপিগুলির ক্ষেত্রে default_scope,

Foo.unscope(where: :bar)

অথবা

scope :not_default, -> { unscope(where: :bar) }
Foo.not_default

উভয়ই কোনও স্কয়ার ক্যোয়ারিতে ফলাফল দেবে যা আসল সুযোগটি প্রয়োগ করে না, তবে অন্যান্য শর্তগুলি আরেলের সাথে সংযুক্ত হয়ে যা কিছু প্রয়োগ করবে তা প্রয়োগ করে।


2

ঠিক আছে, আপনি সবসময় পুরানো সময় প্রিয় find_by_sqlসম্পূর্ণ প্রশ্নের সাথে ব্যবহার করতে পারেন । উদাহরণস্বরূপ: Model.find_by_sql ("আইডি = 123 থেকে" মডেলগুলি নির্বাচন করুন ")

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.