আরেল এবং রেলগুলিতে কীভাবে একটি লাইক কোয়েরি করবেন?


115

আমি এরকম কিছু করতে চাই:

SELECT * FROM USER WHERE NAME LIKE '%Smith%';

আরেলে আমার প্রচেষ্টা:

# params[:query] = 'Smith'
User.where("name like '%?%'", params[:query]).to_sql

তবে এটি হয়ে যায়:

SELECT * FROM USER WHERE NAME LIKE '%'Smith'%';

আরেল ক্যোরির স্ট্রিং 'স্মিথ' সঠিকভাবে জড়িয়ে দেয় তবে এটি একটি লাইক স্টেটমেন্ট যা এটি কাজ করে না।

আরেলের মধ্যে কীভাবে একজন লাইক কোয়েরি করতে পারে?

পিএস বোনাস - প্রশ্নের সাথে কোনও মিল আছে কিনা তা দেখার জন্য আমি টেবিলের দুটি ক্ষেত্রের নাম এবং বর্ণনা উভয়ই স্ক্যান করার চেষ্টা করছি। কিভাবে কাজ করবে?


1
আমি বোনাসের জন্য arel উত্তর আপডেট করেছি।
পেড্রো রোলো

উত্তর:


275

আপনি এইভাবে আরএল-তে একটি অনুরূপ ক্যোয়ারী সম্পাদন করেন:

users = User.arel_table
User.where(users[:name].matches("%#{user_name}%"))

পুনশ্চ:

users = User.arel_table
query_string = "%#{params[query]}%"
param_matches_string =  ->(param){ 
  users[param].matches(query_string) 
} 
User.where(param_matches_string.(:name)\
                       .or(param_matches_string.(:description)))

10
ব্যবহারের বিপরীতে where("name like ?", ...), এই পদ্ধতিটি বিভিন্ন ডাটাবেসগুলিতে আরও পোর্টেবল। উদাহরণস্বরূপ, এটি ILIKEকোনও পোস্টগ্রিস ডিবি-এর বিপরীতে কোনও ক্যোয়ারিতে ব্যবহৃত হওয়ার ফলস্বরূপ ।
ডকোবেজেভ

20
এটি কি এসকিউএল ইঞ্জেকশনগুলির বিরুদ্ধে সুরক্ষিত?
সেরেন

7
এটি এসকিউএল ইঞ্জেকশন থেকে সম্পূর্ণ সুরক্ষা দেয় না। ব্যবহারকারীর নামটি "%" এ সেট করার চেষ্টা করুন। ক্যোয়ারী ম্যাচগুলি ফিরিয়ে দেবে
ট্র্যাভিস -১6

5
আমি সরাসরি প্যারামগুলি ব্যবহার করে স্কুএল ইনজেক্ট করার User.where(users[:name].matches("%#{params[:user_name]}%"))চেষ্টা করেছি, আমি চেষ্টা করেছি TRUNCATE users;এবং এই জাতীয় অন্যান্য প্রশ্নগুলি এবং স্কেলের দিক থেকে কিছুই ঘটেনি। আমার কাছে নিরাপদ দেখাচ্ছে
আয়ারলোনরেইস

5
.gsub(/[%_]/, '\\\\\0')মাইএসকিউএল ওয়াইল্ডকার্ড চরগুলি পালানোর জন্য ব্যবহার করুন ।
এরকোলিনো

116

চেষ্টা

User.where("name like ?", "%#{params[:query]}%").to_sql

পুনশ্চ.

q = "%#{params[:query]}%"
User.where("name like ? or description like ?", q, q).to_sql

Aaand এটি অনেক দিন হয়ে গেছে তবে @ cgg5207 একটি পরিবর্তন যুক্ত করেছে (আপনি দীর্ঘ-নামযুক্ত বা একাধিক দীর্ঘ-নামক প্যারামিটারগুলি অনুসন্ধান করতে চলেছেন বা আপনি টাইপ করতে খুব অলস হন) বেশিরভাগ ক্ষেত্রে দরকারী

q = "%#{params[:query]}%"
User.where("name like :q or description like :q", :q => q).to_sql

অথবা

User.where("name like :q or description like :q", :q => "%#{params[:query]}%").to_sql

9
%বিকল্পগুলি স্ট্রিংয়ে পালাতে না পেরে কীভাবে রেলগুলি জানতে পারে ? দেখে মনে হচ্ছে আপনি যদি কেবল একপেশে ওয়াইল্ডকার্ড চেয়েছিলেন তবে ব্যবহারকারীর %উভয় প্রান্তে থাকা একটি কোয়েরি মান জমা দেওয়া থেকে বিরত থাকার কিছুই নেই (আমি জানি যে বাস্তবে, রেলগুলি %কোয়েরি স্ট্রিংটিতে প্রদর্শিত হওয়া থেকে বিরত থাকে, তবে এটি সেখানে মনে হয় অ্যাক্টিভেকর্ড স্তরে এর বিরুদ্ধে সুরক্ষা হওয়া উচিত)।
স্টিভেন

8
এটি কি এসকিউএল ইঞ্জেকশন আক্রমণে ঝুঁকিপূর্ণ নয়?
বেহরং সাইদজাদেহ

7
@ বেহরং 8 নং) ইউজার.এই জায়গাতে ("% # {প্যারামের মতো নাম [: ক্যোরি]}% বা% # {প্যারামের মতো বর্ণনা [: ক্যোয়ারী]}%")। টু_এসকিএলটি দুর্বল হবে তবে আমি যে ফর্ম্যাটটিতে দেখাব সেগুলি হবে ,
রেলগুলি প্যারামগুলি

অফটোপিকের জন্য দুঃখিত আমার কাছে পদ্ধতি to_sqlবা আইআরএল ম্যানেজারের স্ক্যল গিট আছে , কিভাবে ডিবিতে এসকিএলএল চালানো যায়?
0 Скрылевъ

মডেল.ইহোইজ (টু_সক্ল_আরসল্ট)
পেড্রো রোলো

4

প্যারামিটার বাইন্ডিংগুলি ব্যবহার করার জন্য রূবেণ মল্লবীর উত্তর আরও ছোট করা যেতে পারে:

User.where("name like :kw or description like :kw", :kw=>"%#{params[:query]}%").to_sql
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.