কারাগারে 4 টি লাইক ক্যোয়ারী - অ্যাক্টিভেকর্ডগুলি উদ্ধৃতি যোগ করে


127

আমি এর মতো একটি লাইক কোয়েরি করার চেষ্টা করছি

def self.search(search, page = 1 )
  paginate :per_page => 5, :page => page,
    :conditions => ["name LIKE '%?%' OR postal_code like '%?%'", search, search],   order => 'name'
end

তবে এটি যখন চালানো হয় তখন কিছু উদ্ধৃতি যুক্ত করা হয় যার ফলে এসকিএল স্টেটমেন্টটি এর মতো প্রকাশিত হয়

SELECT COUNT(*)
FROM "schools" 
WHERE (name LIKE '%'havard'%' OR postal_code like '%'havard'%')):

সুতরাং আপনি আমার সমস্যা দেখতে পারেন। আমি রেলস 4 এবং পোস্টগ্রাস 9 উভয়ই ব্যবহার করছি যা আমি কখনই ব্যবহার করি নি তবে নিশ্চিত না যে এটির এবং একটি অ্যাক্টিভেকর্ড জিনিস বা সম্ভবত কোনও পোস্টগ্রিজ জিনিস thing

আমি কীভাবে এটি সেট আপ করতে পারি যাতে আমার '%my_search%'শেষ কোয়েরিতে পছন্দ হয়?

উত্তর:


228

আপনার স্থানধারক একটি স্ট্রিং দ্বারা প্রতিস্থাপিত হয়েছে এবং আপনি এটি সঠিকভাবে পরিচালনা করছেন না।

প্রতিস্থাপন করা

"name LIKE '%?%' OR postal_code LIKE '%?%'", search, search

সঙ্গে

"name LIKE ? OR postal_code LIKE ?", "%#{search}%", "%#{search}%"

6
এটি কি এসকিউএল ইঞ্জেকশনের পক্ষে ঝুঁকিপূর্ণ নয়? মানে, এই searchস্ট্রিংগুলি কি স্যানিটাইজড?
jdscosta91

6
@ jdscosta91 এ ?যেখানে স্যানিটাইজিংয়ের যত্ন নেবে
বাড়ি 9

7
এই পদ্ধতির অধীনে @ বাড়ি9 এর উদাহরণগুলি %এবং _অভ্যন্তর searchস্যানিটাইজ করা হবে না।
ব্যারি কেলি

8
ব্যবহার করার সময় '?' রেলপথে এইভাবে এটি একটি প্যারামিটারাইজড ক্যোয়ারিতে রূপান্তরিত হয়। প্যারামিটারের মধ্যে থাকা ডেটা স্যানিটাইজ করা হয়নি (%) তবে কোয়েরি থেকে প্রসঙ্গটি পরিবর্তন করা এবং এটি প্রক্রিয়াজাত এসকিউএল স্টেটমেন্টগুলিতে রূপান্তর করা অসম্ভব।
ডেভিড হোলজার

50

conditionsরেল 2 থেকে সিনট্যাক্স ব্যবহার না করে , এর whereপরিবর্তে রেল 4 এর পদ্ধতিটি ব্যবহার করুন:

def self.search(search, page = 1 )
  wildcard_search = "%#{search}%"

  where("name ILIKE :search OR postal_code LIKE :search", search: wildcard_search)
    .page(page)
    .per_page(5)
end

দ্রষ্টব্য: উপরের পরিবর্তে প্যারামিটার সিনট্যাক্স ব্যবহার করে? স্থানধারক: এই দু'জনেরই একই স্কয়ার তৈরি করা উচিত।

def self.search(search, page = 1 )
  wildcard_search = "%#{search}%"

  where("name ILIKE ? OR postal_code LIKE ?", wildcard_search, wildcard_search)
    .page(page)
    .per_page(5)
end

দ্রষ্টব্য: ILIKEনামের জন্য ব্যবহার করে - পোস্টগ্রিস কেস লাইক এর সংবেদনশীল সংস্করণ


এটি কি এখনও রেল 5 এর জন্য বৈধ? কারণ আমার যদি Movie.where("title ILIKE :s", s: search_string)এটি SELECT 1 AS one FROM "movies" WHERE (title ILIKE 'test') LIMIT $1অ্যাক্টিভেকর্ড দ্বারা অনুবাদ করা হয়ে থাকে (রেলগুলি 5.1.6) - দয়া করে লক্ষ্য করুন যে আইলিকের পরে কোনও শতাংশের প্রতীক নেই)
সেখমো

@ সেকমো - এটি কাজ করা উচিত, শতাংশ search_stringপরিবর্তনশীল মধ্যে যেতে হবে । আমি মনে করি SELECT 1 AS oneআউটপুটটি কেবল রেল কনসোলে আছে বা আপনি ব্যবহার করছেন limit(1)? এফওয়াইআই: রেল 5.1.6 এ সুরক্ষা সমস্যা রয়েছে, পরিবর্তে 5.1.6.2 বা 5.1.7 ব্যবহার করুন
বাড়ি 9

22

যখন স্ট্রিং ইন্টারপোলেশন কাজ করবে, আপনার প্রশ্নটি 4 রেলগুলি নির্দিষ্ট করে, আপনি এটির জন্য আরেল ব্যবহার করতে এবং আপনার অ্যাপ্লিকেশন ডেটাবেসকে অজ্ঞেয় রাখে।

def self.search(query, page=1)
  query = "%#{query}%"
  name_match = arel_table[:name].matches(query)
  postal_match = arel_table[:postal_code].matches(query)
  where(name_match.or(postal_match)).page(page).per_page(5)
end


নিরীক্ষিত, যদিও এটি এর মতো কিছু হতে পারে: স্কোপ অনুসন্ধান_অ্যাট্রিবিউটস, -> (ক্যোয়ারী, বৈশিষ্ট্য) l arel_attributes = विशेषताগুলি। ম্যাপ {| একটি | arel_table [a]} arel_queries = arel_attributes.map {| a | a.matches (ক্যোয়ারী)} যেখানে ফিরে আসে (arel_queries.reduce {| res, q | res.or q})}
পেদ্রো রলো

8

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

"name LIKE CONCAT('%',?,'%') OR postal_code LIKE CONCAT('%',?,'%')", search, search)


আমি কেবল এটি একটি প্রয়োগে প্রয়োগ করেছি এবং এটি দুর্দান্ত কাজ করেছে। আপনাকে ধন্যবাদ জন।
fuzzygroup

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

5

চেষ্টা

 def self.search(search, page = 1 )
    paginate :per_page => 5, :page => page,
      :conditions => ["name LIKE  ? OR postal_code like ?", "%#{search}%","%#{search}%"],   order => 'name'
  end

আরও তথ্যের জন্য AREL শর্তে ডক্স দেখুন ।


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