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


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.