রেলগুলি ডিফল্ট_স্কোপ ব্যবহার করার বিরুদ্ধে প্রায়শই সুপারিশ করা হয় কেন?


125

সব জায়গা উপর ইন্টারনেট ব্যক্তিকে উল্লেখ যে পাগল ব্যবহার একটি খারাপ ধারণা, এবং শীর্ষ হিট Stackoverflow তে এটি কিভাবে ওভাররাইট চলেছেন। এটি বিশৃঙ্খলা অনুভব করে এবং একটি স্পষ্ট প্রশ্ন উপস্থাপন করে (আমার ধারণা)।default_scopedefault_scope

সুতরাং: কেন রেল default_scopeব্যবহারের বিরুদ্ধে সুপারিশ করা হচ্ছে?

উত্তর:


192

সমস্যা ঘ

আসল উদাহরণটি বিবেচনা করি:

class Post < ActiveRecord::Base
  default_scope { where(published: true) }
end

ডিফল্ট করার প্রেরণা published: true, অপ্রকাশিত (প্রাইভেট) পোস্টগুলি দেখাতে চাইলে আপনাকে অবশ্যই প্রকাশিত হতে হবে তা নিশ্চিত করা হতে পারে। এ পর্যন্ত সব ঠিকই.

2.1.1 :001 > Post.all
  Post Load (0.2ms)  SELECT "posts".* FROM "posts"  WHERE "posts"."published" = 't'

আচ্ছা এটি আমাদের প্রত্যাশা থেকে অনেক বেশি। এখন চেষ্টা করুন:

2.1.1 :004 > Post.new
 => #<Post id: nil, title: nil, published: true, created_at: nil, updated_at: nil>

এবং সেখানে আমাদের ডিফল্ট সুযোগ নিয়ে প্রথম বড় সমস্যা রয়েছে:

=> ডিফল্ট_স্কোপ আপনার মডেল প্রারম্ভিককরণকে প্রভাবিত করবে

যেমন একটি মডেল একটি নতুন নির্মিত উদাহরণে, default_scopeপ্রতিফলিত হবে। সুতরাং আপনি সম্ভবত অপ্রকাশিত পোস্টগুলি তালিকাভুক্ত না করার বিষয়ে নিশ্চিত হতে চেয়েছিলেন, আপনি এখন পূর্বনির্ধারিত পোস্টগুলি তৈরি করছেন।

সমস্যা 2

আরও বিস্তৃত উদাহরণ বিবেচনা করুন:

class Post < ActiveRecord::Base
  default_scope { where(published: true) }
  belongs_to :user
end 

class User < ActiveRecord::Base
  has_many :posts
end

প্রথম ব্যবহারকারীদের পোস্ট পেতে দেয়:

2.1.1 :001 > User.first.posts
  Post Load (0.3ms)  SELECT "posts".* FROM "posts"  WHERE "posts"."published" = 't' AND "posts"."user_id" = ?  [["user_id", 1]]

এটি প্রত্যাশিত মনে হচ্ছে (ব্যবহারকারীর_আইডি সম্পর্কে অংশটি দেখতে ডানদিকে সমস্ত দিক থেকে স্ক্রোল করা নিশ্চিত করুন)।

এখন আমরা সমস্ত পোস্টের তালিকা পেতে চাই - অপ্রকাশিত অন্তর্ভুক্ত - লগ ইন করা ব্যবহারকারীর দর্শনের জন্য বলি। আপনি বুঝতে পারবেন আপনাকে 'ওভাররাইট' করতে হবে বা এর প্রভাবটি 'পূর্বাবস্থা' করতে হবে default_scope। দ্রুত গুগলের পরে আপনি সম্ভবত এটি সম্পর্কে সন্ধান করবেন unscoped। এরপরে কী ঘটে দেখুন:

2.1.1 :002 > User.first.posts.unscoped
  Post Load (0.2ms)  SELECT "posts".* FROM "posts"

=> আনসোপড করা সমস্ত স্কোপগুলি সরিয়ে দেয় যা সাধারণত আপনার নির্বাচনের ক্ষেত্রে অ্যাসোসিয়েশন সহ (তবে সীমাবদ্ধ নয়) সাধারণত প্রয়োগ হতে পারে।

এর বিভিন্ন প্রভাবগুলি ওভাররাইট করার একাধিক উপায় রয়েছে default_scope। ডানটি পাওয়া খুব দ্রুত জটিল হয়ে যায় এবং আমি যুক্তি দিয়ে বলব যে default_scopeএটি প্রথম স্থানে ব্যবহার না করা একটি নিরাপদ পছন্দ হবে।


2
গাদা করতে: আপনি যখন ডিফল্টরূপে কিছু সমিতি লোড করতে আগ্রহী তখনই আমি ডিফল্ট_স্কোপটি কেবলমাত্র কার্যকর খুঁজে পাই। ডিফল্ট_স্কোপ {উত্সাহী_লোড ([: বিভাগ, মন্তব্যসমূহ])}} যাহোক!!! আপনি যদি প্রোডাক্টকাউন্টের মতো এই মডেলটিতে গণনা ক্যোয়ারী করেন তবে এটি সমস্ত পণ্যের জন্য সহযোগীতা লোড করবে। এবং যদি আপনার কাছে 50 কে রেকর্ড থাকে তবে আপনার গণনা কোয়েরিটি 15 মিমি থেকে 500 মিমি পর্যন্ত চলে গেছে, কারণ আপনি যা চান তা গণনা করার পরেও আপনার ডিফল্ট_স্কোপটি সমস্ত কিছুতে যোগ দেবে।
কনুং

16
আমার কাছে দেখে মনে হচ্ছে সমস্যাটি সমস্যা 2unscopeddefault_scope
ক্যাপ্টেন ফোগেটে

4
পছন্দ করুন আমি এখনও মনে করি ডিফল্ট_স্কোপের সম্ভাব্য অসুবিধাগুলি হিসাবে অনস্ক্রিপডের ত্রুটিগুলি উপস্থাপন করা ভাল ধারণা। বেশিরভাগ অ-তুচ্ছ মামলায় ডিফল্ট_স্কোপ ব্যবহারের ফলে আপনাকে আনস্কোপড ব্যবহার করা প্রয়োজন। এটি দ্বিতীয় ডিগ্রি ক্যাভিয়েট (উন্নত শর্তের অভাবে), কোনও পদ্ধতি গবেষণা করার সময় এড়ানো সহজ।
wrtsprt

1
আপনার উত্তরের ব্যবহারের ক্ষেত্রে সমস্যাটি হ'ল এমন অনেকগুলি মামলা রয়েছে যখন আপনি অপ্রকাশিত পোস্টগুলি সন্ধান করতে চান। আসলে, আমি যুক্তি দিয়ে বলব যে প্রকাশিত পোস্টগুলি সন্ধান করা একটি বিশেষ ক্ষেত্রে। আপনি প্রকাশিত পোস্টগুলি একবার চান যখন কেউ পাবলিক পৃষ্ঠাটি দেখছেন। তবে এমন অনেক সময় রয়েছে যখন আপনি অপ্রকাশিত পোস্ট দেখতে চান।
বি সেভেন

3
আমি একটি ভাল ব্যবহার default_scopeহয় যখন আপনি চান সাজাতে হবে কিছু: default_scope { order(:name) }
ব্যবহারকারী 2985898

9

ব্যবহারের না আরেকটি কারণ default_scopeহলো যখন তুমি কোন মডেল একটি দৃষ্টান্ত দিয়ে একটি 1 অনেক সম্পর্ক আছে যা মুছে ফেলার করছি default_scopeমডেল

উদাহরণস্বরূপ বিবেচনা করুন:

    class User < ActiveRecord::Base
      has_many :posts, dependent: :destroy
    end 

    class Post < ActiveRecord::Base
      default_scope { where(published: true) }
      belongs_to :user
    end

কলিং user.destroyসমস্ত পোস্ট মুছে ফেলবে publishedতবে তা পোস্টগুলি মুছে ফেলবে না unpublished। সুতরাং ডাটাবেসটি একটি বিদেশী কী লঙ্ঘন ছুঁড়ে ফেলবে কারণ এতে এমন রেকর্ড রয়েছে যা ব্যবহারকারীর আপনি মুছে ফেলতে চান উল্লেখ করে।


6

ডিফল্ট_স্কোপ প্রায়শই এর বিরুদ্ধে প্রস্তাবিত হয় কারণ ফলাফল সেটটি সীমাবদ্ধ করার জন্য এটি কখনও কখনও ভুলভাবে ব্যবহৃত হয়। ডিফল্ট_স্কোপের একটি ভাল ব্যবহার হল ফলাফল সেটটি অর্ডার করা।

আমি whereডিফল্ট_স্কোপ ব্যবহার করা থেকে দূরে থাকব এবং এর জন্য একটি সুযোগ তৈরি করব।


1
দ্বিতীয় সমস্যা "আনস্কোপ করা সমস্ত সংস্থানগুলি সরিয়ে দেয় যা সাধারণত আপনার নির্বাচনের ক্ষেত্রে প্রযোজ্য হতে পারে, সহ (তবে সীমাবদ্ধ নয়) সহ" default_scopeকেবলমাত্র উপস্থিত থাকলেও এখনও বিদ্যমান order। এই আচরণটি unscopedবেশ অপ্রত্যাশিত।
জ্যাক Xu

1

আমার জন্য না একটি খারাপ ধারণা কিন্তু সাবধানতার সাথে ব্যবহার করা আবশ্যক !. একটি ক্ষেত্র রয়েছে যখন আমি সর্বদা নির্দিষ্ট রেকর্ডগুলি গোপন রাখতে চেয়েছিলাম।

  1. সাধারণত default_scopeডিবি ডিফল্ট মানের সাথে অবশ্যই মিলবে (যেমন { where(hidden_id: nil) }:)
  2. যখন আপনি পুরোপুরি নিশ্চিত হন যে আপনি এই রেকর্ডগুলি দেখাতে চান, সবসময় এমন unscopedপদ্ধতি থাকে যা আপনার এড়ানো হবেdefault_scope

সুতরাং এটি নির্ভর করবে এবং আসল প্রয়োজনগুলি।


0

আমি কেবলমাত্র default_scopeকিছু প্যারামিটারগুলিতে থাকা ascবা descসমস্ত পরিস্থিতিতে অর্ডার করার জন্য কেবল দরকারী বলে মনে করি । নইলে আমি এটিকে প্লেগের মতো এড়িয়ে চলি

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