বনাম সন্ধান করুন_ যেখানে বনাম


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পদ্ধতি সাধারণত ID দ্বারা একটি সারিতে পুনরুদ্ধার করতে ব্যবহার করা হয়:

Model.find(1)

এটি উল্লেখযোগ্য যে findআইটেমটি আপনি সরবরাহ করা গুণাবলী অনুসারে আইটেমটি পাওয়া না গেলে এটি একটি ব্যতিক্রম ছুঁড়ে ফেলবে। whereব্যতিক্রম ছুঁড়ে যাওয়া এড়ানোর জন্য (নীচে বর্ণিত হিসাবে ব্যবহার করুন , যা বৈশিষ্ট্যটি খুঁজে পাওয়া না গেলে খালি অ্যারেটি ফিরিয়ে দেবে) ব্যবহার করুন।

অন্যান্য ব্যবহারগুলি findসাধারণত এই জাতীয় জিনিসগুলির সাথে প্রতিস্থাপিত হয়:

Model.all
Model.first

find_byআপনি যখন কোনও কলামের মধ্যে তথ্য অনুসন্ধান করছেন তখন সহায়ক হিসাবে ব্যবহৃত হবে এবং নামকরণের সম্মেলনের সাথে এটি মানচিত্র করে। উদাহরণস্বরূপ, nameআপনার ডাটাবেজে যদি আপনার একটি কলামের নাম লেখা থাকে, আপনি নীচের বাক্য গঠনটি ব্যবহার করবেন:

Model.find_by(name: "Bob")

.where প্রচলিত সাহায্যকারীরা কখন না করবে তার জন্য আপনাকে কিছুটা আরও জটিল যুক্তি ব্যবহার করতে দেয় এবং এটি আপনার শর্তগুলির সাথে মেলে এমন আইটেমগুলির একটি অ্যারে প্রদান করে (বা অন্যথায় একটি ফাঁকা অ্যারে) all


62
find_byঅবচয় করা হয়নি, তবে সিনট্যাক্সটি কিছুটা পরিবর্তন হচ্ছে। থেকে find_by_name("Bob")থেকে find_by(:name, "Bob")
ব্রায়ান মোরার্টি

61
@BrianMorearty আমি বিশ্বাস করি আপনি বোঝানোfind_by(name: "Bob")
MCB

1
@ ব্রায়ানমোরার্থী অবমানিত find_by_...হওয়ার কোনও প্রমাণ আমি পাইনি , আপনার কি কোনও উত্স আছে? দেখে মনে হচ্ছে find_byএবং find_by_...এটি উভয় এখনও রেল 4 এ সমর্থিত
ডেনিস

4
@ ডেনিস, আপনি ঠিক বলেছেন যে এটি অবহেলিত নয়, এবং আমি যা বলেছিলাম। তবে আমি যখন বলেছিলাম তখন আরও স্পষ্ট হয়ে উঠতে পারতাম "তবে বাক্যবিন্যাসটি কিছুটা পরিবর্তন হচ্ছে।" আমি যা বোঝাতে চেয়েছি তা ছিল "" তবে একটি নতুন সিনট্যাক্স এখন উপলভ্য। " নতুন সিনট্যাক্সের জন্য এমসিবির সংশোধন দেখুন।
ব্রায়ান মোরেয়ার্টি

3
এই উল্লিখিত 4.0 রিলিজ "! Find_by ছাড়া সকল গতিশীল পদ্ধতি _... এবং find_by _... অবচিত করা হয়" এর আরো বিস্তারিত জানার পাগল হয় edgeguides.rubyonrails.org/...
মুকেশ সিং Rathaur

131

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

এখন Find_by বাস্তবায়নটি একবার দেখুন:

def find_by
  where(*args).take
end

আপনি দেখতে পাচ্ছেন যে সন্ধান_বাই যেখানে একই, তবে এটি কেবল একটি রেকর্ড দেয়। এই পদ্ধতিটি 1 রেকর্ড পাওয়ার জন্য ব্যবহার করা উচিত এবং কিছু শর্তযুক্ত সমস্ত রেকর্ড পাওয়ার জন্য কোথায় ব্যবহার করা উচিত।


1
সন্ধান_বাই কোনও বস্তু ফেরত দেয়, তবুও যেখানে সংগ্রহ সংগ্রহ করে।
কিক বাট্টোভস্কি

যখন ক্যোয়ারির মানটি পরিসীমা ছাড়িয়ে যায় , তখন find_byতা উদ্ধার ::RangeErrorকরে where(*args)শূন্য করে দেয়।
1919

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>। কারও উত্তর দেওয়ার জন্য আমার এটি দরকার
22:53

অ্যাগিস, আপনার দাবিটি ব্যাক আপ করার জন্য আপনার কাছে কি কোনও উত্স আছে যে আমরা আর find_by_name4 রেলগুলিতে ব্যবহার করব না? আমি যতদূর জানি, এটি হ্রাস করা হয়নি
ডেনিস

এটি করার সহজ উপায় কি আছে তবে বলুন যে নামটিতে একটি ওয়াইল্ডকার্ড রয়েছে তাই এরকম কিছুfind_by(name: "Rob*")
ব্যাটম্যান 21

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") প্রথম - এই আপনি এটা সরাসরি আপডেট করতে দেয় এবং এটি নিরাপদ যেহেতু এটি থামিয়ে দেওয়া বেঁচে আছে।
পল Brunache

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)

প্রাথমিক কী = আইডি যেখানে সারি দেয় row রিটার্নের ধরণটি 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
এটি প্রশ্নের উত্তর দিতে পারে। তবে গৃহীত উত্তরের পরিবর্তে আপনার দৃষ্টিভঙ্গিটি ব্যবহারের পক্ষে ও কৌশলগুলি বর্ণনা করার চেষ্টা করুন।
বিবেক কুমার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.