vs find_by_by vs कहाँ


127

मैं रेल के लिए नया हूँ। मैं क्या देखता हूं कि रिकॉर्ड खोजने के कई तरीके हैं:

  1. find_by_<columnname>(<columnvalue>)
  2. find(:first, :conditions => { <columnname> => <columnvalue> }
  3. where(<columnname> => <columnvalue>).first

और ऐसा लगता है कि यह सभी अंत में एक ही एसक्यूएल पैदा करते हैं। इसके अलावा, मेरा मानना ​​है कि कई रिकॉर्ड खोजने के लिए भी यही सच है:

  1. find_all_by_<columnname>(<columnvalue>)
  2. find(:all, :conditions => { <columnname> => <columnvalue> }
  3. where(<columnname> => <columnvalue>)

क्या अंगूठे या सिफारिश का नियम है जिस पर किसी को उपयोग करना है?

जवाबों:


103

जो भी आपको लगता है कि आपकी आवश्यकताओं के अनुसार सबसे अच्छा उपयोग करें।

findविधि आमतौर पर आईडी के आधार पर एक पंक्ति को पुनः प्राप्त करने के लिए इस्तेमाल किया जाता है:

Model.find(1)

यह ध्यान देने योग्य है कि findयदि आइटम आपके द्वारा आपूर्ति किए गए आइटम द्वारा नहीं मिला है तो एक अपवाद को फेंक देगा। उपयोग where(जैसा कि नीचे वर्णित है, जो एक खाली सरणी लौटाएगा यदि विशेषता नहीं मिली है) एक अपवाद को फेंकने से बचने के लिए।

findआम तौर पर इस तरह की चीजों के साथ अन्य उपयोग किए जाते हैं:

Model.all
Model.first

find_byएक सहायक के रूप में उपयोग किया जाता है जब आप एक कॉलम के भीतर जानकारी खोज रहे होते हैं, और यह ऐसे नामकरण सम्मेलनों के साथ मैप करता है। उदाहरण के लिए, यदि nameआपके डेटाबेस में एक कॉलम है, तो आप निम्नलिखित सिंटैक्स का उपयोग करेंगे:

Model.find_by(name: "Bob")

.where सभी कैच अधिक है जो आपको पारंपरिक हेल्पर्स नहीं करने के लिए थोड़ा और अधिक जटिल तर्क का उपयोग करने की अनुमति देता है, और यह उन मदों की एक सरणी लौटाता है जो आपकी शर्तों (या एक खाली सरणी अन्यथा) से मेल खाते हैं।


62
find_byपदावनत नहीं किया जाता है, लेकिन वाक्यविन्यास थोड़ा बदल रहा है। से find_by_name("Bob")करने के लिए find_by(:name, "Bob")
ब्रायन मोरेर्ट्टी

61
@BrianMorearty मेरा मानना ​​है कि आपका मतलब हैfind_by(name: "Bob")
MCB

1
@BrianMorearty मुझे find_by_...पदावनत होने का कोई सबूत नहीं मिला , क्या आपके पास कोई स्रोत है? ऐसा लगता है find_byऔर find_by_...दोनों अभी भी रेल 4 में समर्थित हैं
डेनिस

4
@ डेनिस, आप सही हैं कि यह पदावनत नहीं है, और यही मैंने कहा है। लेकिन मैं अधिक स्पष्ट हो सकता था जब मैंने कहा था "लेकिन वाक्यविन्यास थोड़ा बदल रहा है।" मेरा मतलब था, "लेकिन एक नया वाक्यविन्यास अब भी उपलब्ध है।" नए सिंटैक्स के लिए MCB का सुधार देखें।
बजे ब्रायन मोरेर्टी

3
यह वही उल्लेख 4.0 रिलीज "! Find_by के लिए छोड़कर सभी गतिशील तरीकों _... और find_by _... पदावनत कर रहे हैं" की अधिक जानकारी के रेल में है edgeguides.rubyonrails.org/...
मुकेश सिंह Rathaur

131

जहां ActiveRecord :: Relation देता है

अब find_by कार्यान्वयन पर एक नज़र डालें:

def find_by
  where(*args).take
end

जैसा कि आप देख सकते हैं find_by जहां के समान है, लेकिन यह केवल एक रिकॉर्ड देता है। इस विधि का उपयोग 1 रिकॉर्ड प्राप्त करने के लिए किया जाना चाहिए और जहां कुछ शर्तों के साथ सभी रिकॉर्ड प्राप्त करने के लिए उपयोग किया जाना चाहिए।


1
find_by एक वस्तु लौटाता है, फिर भी एक संग्रह कहाँ वापस आता है।
लात Buttowski

जब सीमा से बाहर क्वेरी मूल्य, find_byबचाव होगा ::RangeErrorसे where(*args) और बदले नहीं के बराबर।
फैन्गिंग

34

Model.find

1- पैरामीटर: खोजने के लिए वस्तु की आईडी।

2- यदि पाया जाता है: यह वस्तु (केवल एक वस्तु) लौटाता है।

3- यदि नहीं मिला है: एक ActiveRecord::RecordNotFoundअपवाद उठाता है।

Model.find_by

1- पैरामीटर: कुंजी / मूल्य

उदाहरण:

User.find_by name: 'John', email: 'john@doe.com'

2- यदि मिला: यह वस्तु लौटाता है।

3- यदि नहीं मिला: रिटर्न nil

नोट: यदि आप इसकाActiveRecord::RecordNotFoundउपयोगकरना चाहतेहैंfind_by!

Model.where

1- पैरामीटर: समान find_by

2- यदि पाया जाता है: यह ActiveRecord::Relationमापदंडों से मेल खाते हुए एक या अधिक रिकॉर्ड रखता है।

3- अगर नहीं मिला: यह एक खाली लौटा ActiveRecord::Relation


31

वहाँ के बीच एक अंतर है findऔर find_byउस में findन मिलने पर, जबकि एक त्रुटि वापस आ जाएगी find_byवापस आ जाएगी अशक्त।

कभी-कभी यह पढ़ना आसान होता है यदि आपके पास एक विधि है find_by email: "haha", जैसे कि विरोध किया गया है .where(email: some_params).first


17

रेल 4 से आप कर सकते हैं:

User.find_by(name: 'Bob')

जो find_by_nameरेल 3 में समतुल्य है।

का उपयोग करें #whereजब #findऔर #find_byपर्याप्त नहीं हैं।


2
एजिस, मैं आपसे सहमत हूं लेकिन मैं इंटरनेट पर खोज कर रहा हूं कि हमें क्यों इस्तेमाल करना चाहिए find_byऔर क्या नहीं find_by_<column_name>। मुझे किसी को जवाब देने के लिए इसकी आवश्यकता है।
6

Agis, क्या आपके पास अपने दावे का समर्थन करने के लिए कोई स्रोत है जो हमें अब find_by_nameरेल 4 में उपयोग नहीं करना चाहिए ? जहाँ तक मुझे पता है, यह पदावनत नहीं हुआ है
डेनिस

क्या ऐसा करने का एक सरल तरीका है, लेकिन कहते हैं कि नाम में वाइल्डकार्ड है, ऐसा कुछfind_by(name: "Rob*")
बैटमैन

1
@ डेनिस दोनों का उपयोग करना संभव है, वे वैध हैं। मैं नया सिंटैक्स पसंद करता हूं क्योंकि एपीआई अधिक सहज आईएमएचओ है। यह है कि मैं इसे खुद कैसे डिजाइन करूंगा :)
अगिस डे

8

स्वीकृत उत्तर आम तौर पर यह सब कवर करता है, लेकिन मैं कुछ जोड़ना चाहता हूं, बस आप को अपडेट करने की तरह से मॉडल के साथ काम करने की योजना बना रहे हैं, और आप एक एकल रिकॉर्ड प्राप्त कर रहे हैं (जिसका idआपको पता नहीं है), फिर find_byहै जाने का रास्ता, क्योंकि यह रिकॉर्ड को पुनः प्राप्त करता है और इसे एक सरणी में नहीं डालता है

irb(main):037:0> @kit = Kit.find_by(number: "3456")
  Kit Load (0.9ms)  SELECT "kits".* FROM "kits" WHERE "kits"."number" = 
 '3456' LIMIT 1
=> #<Kit id: 1, number: "3456", created_at: "2015-05-12 06:10:56",   
updated_at: "2015-05-12 06:10:56", job_id: nil>

irb(main):038:0> @kit.update(job_id: 2)
(0.2ms)  BEGIN Kit Exists (0.4ms)  SELECT 1 AS one FROM "kits" WHERE  
("kits"."number" = '3456' AND "kits"."id" != 1) LIMIT 1 SQL (0.5ms)   
UPDATE "kits" SET "job_id" = $1, "updated_at" = $2 WHERE  "kits"."id" = 
1  [["job_id", 2], ["updated_at", Tue, 12 May 2015 07:16:58 UTC +00:00]] 
(0.6ms)  COMMIT => true

लेकिन अगर आप उपयोग करते हैं whereतो आप इसे सीधे अपडेट नहीं कर सकते

irb(main):039:0> @kit = Kit.where(number: "3456")
Kit Load (1.2ms)  SELECT "kits".* FROM "kits" WHERE "kits"."number" =  
'3456' => #<ActiveRecord::Relation [#<Kit id: 1, number: "3456", 
created_at: "2015-05-12 06:10:56", updated_at: "2015-05-12 07:16:58", 
job_id: 2>]>

irb(main):040:0> @kit.update(job_id: 3)
ArgumentError: wrong number of arguments (1 for 2)

ऐसे मामले में आपको इसे इस तरह निर्दिष्ट करना होगा

irb(main):043:0> @kit[0].update(job_id: 3)
(0.2ms)  BEGIN Kit Exists (0.6ms)  SELECT 1 AS one FROM "kits" WHERE 
("kits"."number" = '3456' AND "kits"."id" != 1) LIMIT 1 SQL (0.6ms)   
UPDATE "kits" SET "job_id" = $1, "updated_at" = $2 WHERE "kits"."id" = 1  
[["job_id", 3], ["updated_at", Tue, 12 May 2015 07:28:04 UTC +00:00]]
(0.5ms)  COMMIT => true

वास्तव में मैं क्या देख रहा था
पॉल ब्रूनैच

2
@kit = Kit.where (संख्या: "3456")। पहला - इससे आप इसे सीधे अपडेट कर सकते हैं और यह सुरक्षित रहने के बाद से यह
पदावनति से

6

स्वीकृत उत्तर के अलावा, निम्नलिखित भी मान्य है

Model.find()आईडी की सरणी को स्वीकार कर सकते हैं, और सभी रिकॉर्ड लौटाएंगे जो मेल खाते हैं। Model.find_by_id(123)सरणी भी स्वीकार करते हैं, लेकिन केवल सरणी में मौजूद पहले आईडी मान को संसाधित करेंगे

Model.find([1,2,3])
Model.find_by_id([1,2,3])

5

आपकी सूचियों में दोनों # 2 को पदावनत किया जा रहा है। आप अभी भी उपयोग कर सकते हैं find(params[:id])

आम तौर पर, where()ज्यादातर स्थितियों में काम करता है।

यहाँ एक महान पोस्ट है: http://m.onkey.org/active-record-query-interface


1
महान पद मौजूद नहीं है।
नितिन


3

अब तक दिए गए जवाब सभी ठीक हैं।

हालांकि, एक दिलचस्प अंतर यह है कि Model.findआईडी द्वारा खोज की जाती है; यदि पाया जाता है, तो यह एक Modelवस्तु (सिर्फ एक रिकॉर्ड) लौटाता है, लेकिन ActiveRecord::RecordNotFoundअन्यथा फेंकता है।

Model.find_byके समान है Model.findऔर आपको अपने डेटाबेस में किसी भी कॉलम या कॉलम के समूह को खोजने देता है, लेकिन nilयदि कोई रिकॉर्ड खोज से मेल नहीं खाता है तो यह वापस आ जाता है ।

Model.whereदूसरी ओर एक Model::ActiveRecord_Relationवस्तु देता है जो एक सरणी की तरह है जिसमें सभी रिकॉर्ड होते हैं जो खोज से मेल खाते हैं । यदि कोई रिकॉर्ड नहीं मिला, तो यह एक खाली Model::ActiveRecord_Relationवस्तु देता है।

मुझे उम्मीद है कि ये निर्णय लेने में आपकी मदद करेंगे जो किसी भी समय उपयोग करने के लिए।


3

मान लीजिए मेरे पास एक मॉडल है User

  1. User.find(id)

एक पंक्ति देता है जहाँ प्राथमिक कुंजी = आईडी। वापसी प्रकार Userऑब्जेक्ट होगा ।

  1. User.find_by(email:"abc@xyz.com")

इस मामले में मिलान विशेषता या ईमेल के साथ पहली पंक्ति देता है। वापसी प्रकार Userफिर से ऑब्जेक्ट होगा ।

नोट: - User.find_by(email: "abc@xyz.com")के समान हैUser.find_by_email("abc@xyz.com")

  1. User.where(project_id:1)

उन सभी उपयोगकर्ताओं को उपयोगकर्ता तालिका में लौटाता है जहां विशेषता मिलान होती है।

यहां रिटर्न टाइप ActiveRecord::Relationऑब्जेक्ट होगा । ActiveRecord::Relationक्लास में रूबी का Enumerableमाड्यूल शामिल है, ताकि आप इसे ऐरे की तरह ऑब्जेक्ट का उपयोग कर सकें और इस पर ट्रैस कर सकें।


0

किसी भी ओपन सोर्स तकनीक के साथ काम करने का सबसे अच्छा हिस्सा यह है कि आप इसकी लंबाई और चौड़ाई का निरीक्षण कर सकते हैं। इस लिंक को चेकआउट करें

find_by ~> निर्दिष्ट शर्तों से मेल खाता पहला रिकॉर्ड पाता है। कोई निहित आदेश नहीं है इसलिए यदि आदेश मायने रखता है, तो आपको इसे स्वयं निर्दिष्ट करना चाहिए। यदि कोई रिकॉर्ड नहीं मिला है, तो रिटर्न शून्य है।

ढूँढें ~> निर्दिष्ट शर्तों से मेल खाते हुए पहले रिकॉर्ड को ढूँढता है, लेकिन यदि कोई रिकॉर्ड नहीं मिला है, तो यह एक अपवाद को बढ़ाता है लेकिन यह जानबूझकर किया जाता है।

उपरोक्त लिंक को चेकआउट करें, इसमें सभी स्पष्टीकरण हैं और निम्नलिखित दो कार्यों के लिए मामलों का उपयोग करें।


-5

मैं व्यक्तिगत रूप से उपयोग करने की सलाह दूंगा

where(< columnname> => < columnvalue>)

1
यह प्रश्न का उत्तर दे सकता है। लेकिन स्वीकार किए गए उत्तर के बजाय अपने दृष्टिकोण का उपयोग करने के पेशेवरों और विपक्षों का वर्णन करने का प्रयास करें।
विवेक कुमार
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.