কীভাবে খালি অ্যাক্টিভেকর্ড সম্পর্ক ফিরিয়ে আনবেন?


246

যদি আমার একটি ল্যাম্বডা নিয়ে স্কোপ থাকে এবং এটি যুক্তির মানের উপর নির্ভর করে একটি যুক্তি নেয় তবে আমি জানতে পারি যে কোনও মিল থাকবে না, তবে আমি এখনও কোনও খালি অ্যারে নয়, কোনও সম্পর্ক ফিরিয়ে দিতে চাই:

scope :for_users, lambda { |users| users.any? ? where("user_id IN (?)", users.map(&:id).join(',')) : [] }

আমি আসলে যা চাই তা হ'ল "কিছুই নয়" পদ্ধতি, "সমস্ত" এর বিপরীত, এটি এমন একটি সম্পর্ক ফিরিয়ে দেয় যা এখনও বেঁধে রাখা যেতে পারে, তবে ক্যোয়ারির ফলাফলটি সংক্ষিপ্তসারকৃত হয়।


আপনি যদি কেবল জিজ্ঞাসাটি চালিয়ে যান তবে এটি চালানো এটি একটি সম্পর্ক ফিরিয়ে দেবে: ব্যবহারকারী.হোয়ার ('আইডি ইন (?)', []) ক্লাস => অ্যাক্টিভেকর্ড :: রিলেশন। আপনি কি জিজ্ঞাসাটি পুরোপুরি এড়ানোর চেষ্টা করছেন?
ব্রায়ান ডিটারলিং

1
সঠিক। আমি যদি জানি যে সম্ভবত কোনও মিল থাকতে পারে না, আদর্শভাবে, ক্যোরিটি পুরোপুরি এড়ানো যায়। আমি এটিকে কেবল অ্যাক্টিভেকর্ড :: বেসে যুক্ত করেছি: "ডিফ সেল্ফ.নোন না; যেখানে (: আইডি => 0); শেষ" আমার যা প্রয়োজন তার জন্য ঠিক কাজ করার মতো মনে হচ্ছে।
dzajic

1
> আপনি কি পুরোপুরি জিজ্ঞাসা এড়াতে চেষ্টা করছেন? পুরোপুরি বোঝা যাবে, এক ধরনের খোঁড়া আমাদের তার জন্য ডিবিতে আঘাত করা দরকার
ডোলজেনকো

উত্তর:


478

রেল 4 এ এখন একটি "সঠিক" প্রক্রিয়া রয়েছে:

>> Model.none 
=> #<ActiveRecord::Relation []>

14
এখন পর্যন্ত এটি 3.2 বা তার আগের দিকে পোর্ট করা হয়নি। কেবল প্রান্ত (4.0)
ক্রিস ব্লুম


2
মাত্র ৮.০ রেল নিয়ে চেষ্টা করেছি এবং এটি কাজ করছে। এই বৈশিষ্ট্যটি এটি রেলগুলি 4.0 রিলিজ করেছে।
অভিব্যক্ত

3
@AugustinRiedinger Model.scoped আপনি রেল 3 এ যা যা খুঁজছেন তা করেন
টিম ডিজিগিনস

9
রেল 4.0.0 হিসাবে, Model.noneকাজ করে না। আপনাকে আপনার আসল মডেলের একটি ব্যবহার করতে হবে , যেমন User.noneবা কী আছে what
গ্রান্ট বার্চমিয়ার

77

একটি আরও বহনযোগ্য সমাধান যা "আইডি" কলামের প্রয়োজন নেই এবং ধরে নেই যে 0 এর আইডি সহ একটি সারি থাকবে না:

scope :none, where("1 = 0")

আমি এখনও আরও "সঠিক" উপায় খুঁজছি।


3
হ্যাঁ আমি সত্যিই অবাক হয়েছি যে এই উত্তরগুলি আমাদের কাছে সবচেয়ে ভাল। আমি মনে করি অ্যাক্টিভেকর্ড / আরেল এখনও অবশ্যই অপরিপক্ক। রুবিতে খালি অ্যারে তৈরি করতে যদি আমাকে প্যারামবুলেশনের মধ্য দিয়ে যেতে হয় তবে আমি সত্যিই বিরক্ত হব। মূলত এখানে একই জিনিস।
Purplejacket

যদিও কিছুটা hackish, এই হল পাগল 3.2 জন্য সঠিক উপায়। : পাগল 4, @ steveh7 এর অন্যান্য উত্তর এখানে দেখতে stackoverflow.com/a/10001043/307308
scarver2

scope :none, -> { where("false") }
গ্রাহ্য করুন

43

কারাগারে আসছে 4

4 রেলগুলিতে, একটি চেইনযোগ্য ActiveRecord::NullRelationযেমন কলগুলি থেকে ফিরে আসবেPost.none

এটি বা শৃঙ্খলিত পদ্ধতি নয়, ডাটাবেজে কোয়েরি তৈরি করবে না।

মতামত অনুযায়ী:

ফিরে আসা অ্যাক্টিভেকর্ড :: নুলারলেশন রিলেশন থেকে উত্তরাধিকার সূত্রে প্রাপ্ত হয় এবং নাল অবজেক্ট প্যাটার্নটি প্রয়োগ করে। এটি নির্ধারিত নাল আচরণের সাথে যুক্ত এবং ডেটাবেসকে জিজ্ঞাসাবাদ না করে সর্বদা রেকর্ডের খালি অ্যারে প্রদান করে returns

দেখুন সোর্স কোড


42

আপনি "কিছুই নয়" নামে একটি স্কোপ যুক্ত করতে পারেন:

scope :none, where(:id => nil).where("id IS NOT ?", nil)

এটি আপনাকে একটি খালি অ্যাক্টিভেকর্ড :: রিলেশন দেবে

আপনি এটিকে একটি প্রারম্ভিক (যদি আপনি চান) তে অ্যাক্টিভেকর্ড :: বেসে যুক্ত করতে পারেন:

class ActiveRecord::Base
 def self.none
   where(arel_table[:id].eq(nil).and(arel_table[:id].not_eq(nil)))
 end
end

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


14
where('1=2')কিছুটা সংক্ষিপ্ত হতে পারে
মার্সিন র্যাকজকোভস্কি

10
আপনি যদি নতুন 'সঠিক' উত্তরে স্ক্রোল না করেন তবে: আপনি Model.noneএটি কীভাবে করবেন।
জো এসি

26
scope :none, limit(0)

একটি বিপজ্জনক সমাধান কারণ আপনার সুযোগটি শৃঙ্খলিত হতে পারে।

User.none.first

প্রথম ব্যবহারকারীকে ফিরিয়ে দেবে। এটি ব্যবহার করা নিরাপদ

scope :none, where('1 = 0')

2
এটি হ'ল সঠিক একটি 'সুযোগ: কোনওটি নয়, যেখানে (' 1 = 0 ')'। অন্যটি যদি আপনার পৃষ্ঠাটি থাকে তবে ব্যর্থ হবে
ফেডারিকো

14

আমি মনে করি যে আমি অন্যান্য বিকল্পগুলির দিকে এটি দেখতে পছন্দ করি:

scope :none, limit(0)

এরকম কিছুতে নেতৃত্ব দেওয়া:

scope :users, lambda { |ids| ids.present? ? where("user_id IN (?)", ids) : limit(0) }

আমি এই এক পছন্দ। আমি নিশ্চিত না কেন where(false)কাজটি করবে না - এটি সুযোগটি অপরিবর্তিত রাখে।
aceofspades

4
সাবধান থাকুন যে limit(0)আপনি কল করুন .firstবা .lastপরে শৃঙ্খলে ডাকলে ওভাররাইড করা হবে , যেহেতু রেলগুলি LIMIT 1সেই ক্যোয়ারিতে যুক্ত হবে ।
জাইকাডেলিক

2
@aceofspades যেখানে (মিথ্যা) কাজ করে না (রেল 3.0) তবে যেখানে ('মিথ্যা') কাজ করে। আপনি সম্ভবত এখন যত্নশীল তা নয় 2013 :)
রিচি

ধন্যবাদ @ রিচি, তার পর থেকে আমি মনে করি আমাদেরও noneনীচে বর্ণিত সম্পর্ক রয়েছে।
aceofspades

3

স্কোপড ব্যবহার করুন:

সুযোগ: for_users, ল্যাম্বদা {| ব্যবহারকারী | users.any? ? যেখানে ("ইউজার_আইডি ইন (?)", ইউজারস.ম্যাপ (&: আইডি) .জাইন (',')): স্কোপড}

তবে, আপনি নিজের কোডটি এর মাধ্যমে আরও সহজ করতে পারেন:

সুযোগ: for_users, ল্যাম্বদা {| ব্যবহারকারী | কোথায় (: user_id => users.map (&: id)) ব্যবহারকারীরা যদি কোন? }

আপনি যদি খালি ফলাফল চান তবে এটি ব্যবহার করুন (যদি শর্তটি সরিয়ে দিন):

সুযোগ: for_users, ল্যাম্বদা {| ব্যবহারকারী | যেখানে (: user_id => users.map (&: id))}

"স্কোপড" বা শূন্যস্থান ফিরিয়ে দেওয়া আমার যা অর্জন তা অর্জন করে না, যা ফলাফলগুলি শূন্যে সীমাবদ্ধ করে। "স্কোপড" বা শূন্যপথে ফিরে আসার সুযোগের কোনও প্রভাব নেই (যা কিছু ক্ষেত্রে কার্যকর তবে আমার ক্ষেত্রে নয়)। আমি আমার নিজের উত্তর নিয়ে এসেছি (উপরে মন্তব্য দেখুন)।
dzajic

আপনার খালি ফলাফলটি ফেরত দেওয়ার জন্য আমি একটি সহজ সমাধান যোগ করেছি :)
প্যান থোমাকোস


1

বৈকল্পিকগুলিও রয়েছে তবে এই সমস্তগুলি ডিবি করার অনুরোধ করছে

where('false')
where('null')

2
বিটিডাব্লু নোট করুন যে এগুলি অবশ্যই স্ট্রিং হওয়া উচিত। where(false)বা where(nil)কেবল উপেক্ষা করা হয়।
মাহমোফ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.