يقوم SearchCop بتوسيع نماذج ActiveRecord الخاصة بك لدعم محرك بحث النص الكامل مثل الاستعلامات عبر سلاسل الاستعلام البسيطة والاستعلامات المستندة إلى التجزئة. افترض أن لديك نموذج Book
له سمات مختلفة مثل title
author
stock
price
available
. باستخدام SearchCop يمكنك القيام بما يلي:
Book . search ( "Joanne Rowling Harry Potter" )
Book . search ( "author: Rowling title:'Harry Potter'" )
Book . search ( "price > 10 AND price < 20 -stock:0 (Potter OR Rowling)" )
# ...
وبالتالي، يمكنك تسليم سلسلة استعلام بحث إلى النماذج الخاصة بك وستحصل أنت ومسؤولو التطبيق و/أو المستخدمون على ميزات استعلام قوية دون الحاجة إلى دمج خوادم بحث إضافية تابعة لجهات خارجية، حيث يمكن لـ SearchCop استخدام إمكانات فهرس النص الكامل لنظام RDBMS الخاص بك في طريقة حيادية لقاعدة البيانات (حاليًا يتم دعم مؤشرات النص الكامل MySQL وPostgreSQL) وتحسين الاستعلامات لتحقيق الاستخدام الأمثل لها. اقرأ المزيد أدناه.
يتم دعم الاستعلامات المعقدة المستندة إلى التجزئة أيضًا:
Book . search ( author : "Rowling" , title : "Harry Potter" )
Book . search ( or : [ { author : "Rowling" } , { author : "Tolkien" } ] )
Book . search ( and : [ { price : { gt : 10 } } , { not : { stock : 0 } } , or : [ { title : "Potter" } , { author : "Rowling" } ] ] )
Book . search ( or : [ { query : "Rowling -Potter" } , { query : "Tolkien -Rings" } ] )
Book . search ( title : { my_custom_sql_query : "Rowl" } } )
# ...
أضف هذا السطر إلى ملف Gemfile الخاص بالتطبيق الخاص بك:
gem 'search_cop'
ومن ثم تنفيذ:
$ bundle
أو قم بتثبيته بنفسك على النحو التالي:
$ gem install search_cop
لتمكين SearchCop لنموذج، include SearchCop
وحدد السمات التي تريد كشفها لاستعلامات البحث ضمن search_scope
:
class Book < ActiveRecord :: Base
include SearchCop
search_scope :search do
attributes :title , :description , :stock , :price , :created_at , :available
attributes comment : [ "comments.title" , "comments.message" ]
attributes author : "author.name"
# ...
end
has_many :comments
belongs_to :author
end
يمكنك بالطبع أيضًا تحديد كتل search_scope
المتعددة كما تريد:
search_scope :admin_search do
attributes :title , :description , :stock , :price , :created_at , :available
# ...
end
search_scope :user_search do
attributes :title , :description
# ...
end
يقوم SearchCop بتوزيع الاستعلام وتعيينه إلى استعلام SQL بطريقة حيادية لقاعدة البيانات. وبالتالي، فإن SearchCop غير مرتبط بنظام RDBMS محدد.
Book . search ( "stock > 0" )
# ... WHERE books.stock > 0
Book . search ( "price > 10 stock > 0" )
# ... WHERE books.price > 10 AND books.stock > 0
Book . search ( "Harry Potter" )
# ... WHERE (books.title LIKE '%Harry%' OR books.description LIKE '%Harry%' OR ...) AND (books.title LIKE '%Potter%' OR books.description LIKE '%Potter%' ...)
Book . search ( "available:yes OR created_at:2014" )
# ... WHERE books.available = 1 OR (books.created_at >= '2014-01-01 00:00:00.00000' and books.created_at <= '2014-12-31 23:59:59.99999')
يستخدم SearchCop أسلوبي begin_of_year وend_of_year الخاصين بـ ActiveSupport للقيم المستخدمة في إنشاء استعلام SQL لهذه الحالة.
بالطبع، لن تحقق استعلامات LIKE '%...%'
الأداء الأمثل، ولكن راجع القسم أدناه حول إمكانات النص الكامل لـ SearchCop لفهم كيفية تحسين الاستعلامات الناتجة.
نظرًا لأن Book.search(...)
يُرجع ActiveRecord::Relation
، فلديك الحرية في معالجة نتائج البحث مسبقًا أو لاحقًا بكل الطرق الممكنة:
Book . where ( available : true ) . search ( "Harry Potter" ) . order ( "books.id desc" ) . paginate ( page : params [ :page ] )
عندما تقوم بتمرير سلسلة استعلام إلى SearchCop، يتم تحليلها وتحليلها وتعيينها لإنشاء استعلام SQL في النهاية. لكي نكون أكثر دقة، عندما يقوم SearchCop بتوزيع الاستعلام، فإنه يقوم بإنشاء كائنات (عقد)، والتي تمثل تعبيرات الاستعلام (And-، Or-، Not-، String-، Date-، إلخ العقد). لبناء استعلام SQL، يستخدم SearchCop مفهوم الزوار مثل ما هو مستخدم في Arel، بحيث يجب أن يكون هناك زائر لكل عقدة، مما يحول العقدة إلى SQL. في حالة عدم وجود زائر، يظهر استثناء عندما يحاول منشئ الاستعلام "زيارة" العقدة. الزوار مسؤولون عن تطهير المدخلات المقدمة من المستخدم. يتم ذلك بشكل أساسي عبر الاقتباس (السلسلة، اسم الجدول، اقتباس العمود، إلخ). يستخدم SearchCop الأساليب التي يوفرها محول اتصال ActiveRecord للتطهير/الاقتباس لمنع إدخال SQL. على الرغم من أننا لا نستطيع أبدًا أن نكون آمنين بنسبة 100% من المشكلات الأمنية، إلا أن SearchCop يأخذ المشكلات الأمنية على محمل الجد. يرجى الإبلاغ بشكل مسؤول عبر الأمن على flakks dot com في حالة العثور على أي مشكلات متعلقة بالأمن.
يدعم SearchCop حقول json لـ MySQL، بالإضافة إلى حقول json وjsonb وhstore لـ postgres. حاليًا، من المتوقع دائمًا أن تكون قيم الحقول عبارة عن سلاسل ولا يتم دعم أي صفائف. يمكنك تحديد سمات json عبر:
search_scope :search do
attributes user_agent : "context->browser->user_agent"
# ...
end
حيث يكون context
عبارة عن عمود json/jsonb يحتوي على سبيل المثال على:
{
"browser" : {
"user_agent" : " Firefox ... "
}
}
افتراضيًا، على سبيل المثال، إذا لم تخبر SearchCop بمؤشرات النص الكامل الخاصة بك، فسيستخدم SearchCop استعلامات LIKE '%...%'
. لسوء الحظ، ما لم تقم بإنشاء فهرس ثلاثي الأبعاد (postgres فقط)، لا يمكن لهذه الاستعلامات استخدام مؤشرات SQL، بحيث يجب فحص كل صف بواسطة RDBMS الخاص بك عند البحث عن Book.search("Harry Potter")
أو ما شابه. لتجنب عقوبة استعلامات LIKE
، يمكن لـ SearchCop استغلال إمكانات فهرس النص الكامل لـ MySQL وPostgreSQL. لاستخدام فهارس النص الكامل الموجودة بالفعل، ما عليك سوى إخبار SearchCop باستخدامها عبر:
class Book < ActiveRecord :: Base
# ...
search_scope :search do
attributes :title , :author
options :title , :type => :fulltext
options :author , :type => :fulltext
end
# ...
end
سيقوم SearchCop بعد ذلك بتغيير استعلامات SQL الخاصة به بشفافية للسمات التي تحتوي على فهارس النص الكامل إلى:
Book . search ( "Harry Potter" )
# MySQL: ... WHERE (MATCH(books.title) AGAINST('+Harry' IN BOOLEAN MODE) OR MATCH(books.author) AGAINST('+Harry' IN BOOLEAN MODE)) AND (MATCH(books.title) AGAINST ('+Potter' IN BOOLEAN MODE) OR MATCH(books.author) AGAINST('+Potter' IN BOOLEAN MODE))
# PostgreSQL: ... WHERE (to_tsvector('simple', books.title) @@ to_tsquery('simple', 'Harry') OR to_tsvector('simple', books.author) @@ to_tsquery('simple', 'Harry')) AND (to_tsvector('simple', books.title) @@ to_tsquery('simple', 'Potter') OR to_tsvector('simple', books.author) @@ to_tsquery('simple', 'Potter'))
من الواضح أن هذه الاستعلامات لن تُرجع دائمًا نفس النتائج مثل استعلامات أحرف البدل LIKE
، لأننا نبحث عن الكلمات بدلاً من السلاسل الفرعية. ومع ذلك، عادةً ما توفر فهارس النص الكامل أداءً أفضل.
علاوة على ذلك، فإن الاستعلام أعلاه ليس مثاليًا بعد. ولتحسينه بشكل أكبر، يحاول SearchCop تحسين الاستعلامات لتحقيق الاستخدام الأمثل لمؤشرات النص الكامل مع السماح بمزجها مع سمات غير النص الكامل. لتحسين الاستعلامات بشكل أكبر، يمكنك تجميع السمات وتحديد حقل افتراضي للبحث فيه، بحيث لا يجب على SearchCop البحث بعد الآن في جميع الحقول:
search_scope :search do
attributes all : [ :author , :title ]
options :all , :type => :fulltext , default : true
# Use default: true to explicitly enable fields as default fields (whitelist approach)
# Use default: false to explicitly disable fields as default fields (blacklist approach)
end
الآن يمكن لـ SearchCop تحسين الاستعلام التالي، الذي لم يكن الأمثل حتى الآن:
Book . search ( "Rowling OR Tolkien stock > 1" )
# MySQL: ... WHERE ((MATCH(books.author) AGAINST('+Rowling' IN BOOLEAN MODE) OR MATCH(books.title) AGAINST('+Rowling' IN BOOLEAN MODE)) OR (MATCH(books.author) AGAINST('+Tolkien' IN BOOLEAN MODE) OR MATCH(books.title) AGAINST('+Tolkien' IN BOOLEAN MODE))) AND books.stock > 1
# PostgreSQL: ... WHERE ((to_tsvector('simple', books.author) @@ to_tsquery('simple', 'Rowling') OR to_tsvector('simple', books.title) @@ to_tsquery('simple', 'Rowling')) OR (to_tsvector('simple', books.author) @@ to_tsquery('simple', 'Tolkien') OR to_tsvector('simple', books.title) @@ to_tsquery('simple', 'Tolkien'))) AND books.stock > 1
إلى الاستعلام التالي الأكثر أداء:
Book . search ( "Rowling OR Tolkien stock > 1" )
# MySQL: ... WHERE MATCH(books.author, books.title) AGAINST('Rowling Tolkien' IN BOOLEAN MODE) AND books.stock > 1
# PostgreSQL: ... WHERE to_tsvector('simple', books.author || ' ' || books.title) @@ to_tsquery('simple', 'Rowling | Tokien') and books.stock > 1
ماذا يحدث هنا؟ حسنًا، لقد حددنا all
كاسم لمجموعة سمات تتكون من author
title
. نظرًا لأننا، بالإضافة إلى ذلك، حددنا all
ليكون سمة نص كامل، يفترض SearchCop وجود فهرس نص كامل مركب موجود في author
title
، بحيث يتم تحسين الاستعلام وفقًا لذلك. أخيرًا، حددنا all
لتكون السمة الافتراضية للبحث فيها، بحيث يمكن لـ SearchCop تجاهل السمات الأخرى، مثل stock
، طالما لم يتم تحديدها ضمن الاستعلامات مباشرةً (مثل stock > 0
).
سيتم تحسين الاستعلامات الأخرى بطريقة مماثلة، بحيث يحاول SearchCop تقليل قيود النص الكامل داخل الاستعلام، وهي MATCH() AGAINST()
لـ MySQL و to_tsvector() @@ to_tsquery()
لـ PostgreSQL.
Book . search ( "(Rowling -Potter) OR Tolkien" )
# MySQL: ... WHERE MATCH(books.author, books.title) AGAINST('(+Rowling -Potter) Tolkien' IN BOOLEAN MODE)
# PostgreSQL: ... WHERE to_tsvector('simple', books.author || ' ' || books.title) @@ to_tsquery('simple', '(Rowling & !Potter) | Tolkien')
لإنشاء فهرس نص كامل على books.title
في MySQL، استخدم ببساطة:
add_index :books , :title , :type => :fulltext
فيما يتعلق بالمؤشرات المركبة، والتي سيتم استخدامها على سبيل المثال للحقل الافتراضي، all
قمنا بتحديده أعلاه، استخدم:
add_index :books , [ :author , :title ] , :type => :fulltext
يرجى ملاحظة أن MySQL يدعم فهارس النص الكامل لـ MyISAM، واعتبارًا من الإصدار 5.6+ من MySQL، لـ InnoDB أيضًا. لمزيد من التفاصيل حول مؤشرات النص الكامل لـ MySQL، تفضل بزيارة http://dev.mysql.com/doc/refman/5.6/en/fulltext-search.html
فيما يتعلق بـ PostgreSQL، هناك المزيد من الطرق لإنشاء فهرس نص كامل. ومع ذلك، فإن إحدى أسهل الطرق هي:
ActiveRecord :: Base . connection . execute "CREATE INDEX fulltext_index_books_on_title ON books USING GIN(to_tsvector('simple', title))"
علاوة على ذلك، بالنسبة لـ PostgreSQL، يجب عليك تغيير تنسيق المخطط في config/application.rb
:
config . active_record . schema_format = :sql
فيما يتعلق بالمؤشرات المركبة لـ PostgreSQL، استخدم:
ActiveRecord :: Base . connection . execute "CREATE INDEX fulltext_index_books_on_title ON books USING GIN(to_tsvector('simple', author || ' ' || title))"
للتعامل مع القيم NULL مع PostgreSQL بشكل صحيح، استخدم COALESCE في وقت إنشاء الفهرس وعند تحديد search_scope
:
ActiveRecord :: Base . connection . execute "CREATE INDEX fulltext_index_books_on_title ON books USING GIN(to_tsvector('simple', COALESCE(author, '') || ' ' || COALESCE(title, '')))"
زائد:
search_scope :search do
attributes :title
options :title , :type => :fulltext , coalesce : true
end
لاستخدام قاموس PostgreSQL آخر غير simple
، يجب عليك إنشاء الفهرس وفقًا لذلك وتحتاج إلى إخبار SearchCop بذلك، على سبيل المثال:
search_scope :search do
attributes :title
options :title , :type => :fulltext , dictionary : "english"
end
لمزيد من التفاصيل حول مؤشرات النص الكامل لـ PostgreSQL، تفضل بزيارة http://www.postgresql.org/docs/9.3/static/textsearch.html
في حالة الكشف عن سمات غير النص الكامل لاستعلامات البحث (السعر، المخزون، وما إلى ذلك)، فإن الاستعلامات ذات الصلة، مثل Book.search("stock > 0")
، ستستفيد من المؤشرات المعتادة غير النصية. وبالتالي، يجب عليك إضافة فهرس معتاد في كل عمود تعرضه لاستعلامات البحث بالإضافة إلى فهرس النص الكامل لكل سمة نص كامل.
في حالة عدم قدرتك على استخدام فهارس النص الكامل، لأنك على سبيل المثال لا تزال تستخدم MySQL 5.5 أثناء استخدام InnoDB أو RDBMS آخر دون دعم النص الكامل، يمكنك جعل RDBMS الخاص بك يستخدم مؤشرات غير النص الكامل المعتادة لأعمدة السلسلة إذا لم تكن بحاجة إلى حرف البدل الأيسر ضمن استعلامات LIKE
. ما عليك سوى توفير الخيار التالي:
class User < ActiveRecord :: Base
include SearchCop
search_scope :search do
attributes :username
options :username , left_wildcard : false
end
# ...
بحيث يحذف SearchCop حرف البدل الموجود في أقصى اليسار.
User . search ( "admin" )
# ... WHERE users.username LIKE 'admin%'
وبالمثل، يمكنك تعطيل حرف البدل الصحيح أيضًا:
search_scope :search do
attributes :username
options :username , right_wildcard : false
end
عندما تقوم بتحديد حقول متعددة في نطاق البحث، سيستخدم SearcCop افتراضيًا عامل التشغيل AND لتسلسل الشروط، على سبيل المثال:
class User < ActiveRecord :: Base
include SearchCop
search_scope :search do
attributes :username , :fullname
end
# ...
end
لذا فإن بحثًا مثل User.search("something")
سيؤدي إلى إنشاء استعلام بالشروط التالية:
... WHERE username LIKE ' %something% ' AND fullname LIKE ' %something% '
ومع ذلك، هناك حالات لا يكون فيها استخدام AND كعامل التشغيل الافتراضي أمرًا مرغوبًا فيه، لذا يسمح لك SearchCop بتجاوزه واستخدام OR كعامل التشغيل الافتراضي بدلاً من ذلك. سيقوم استعلام مثل User.search("something", default_operator: :or)
بإنشاء الاستعلام باستخدام OR لتسلسل الشروط
... WHERE username LIKE ' %something% ' OR fullname LIKE ' %something% '
أخيرًا، يرجى ملاحظة أنه يمكنك تطبيقه على فهارس/استعلامات النص الكامل أيضًا.
إذا قمت بتحديد سمات قابلة للبحث من نموذج آخر، مثل
class Book < ActiveRecord :: Base
# ...
belongs_to :author
search_scope :search do
attributes author : "author.name"
end
# ...
end
سيقوم SearchCop افتراضيًا eager_load
الارتباطات المشار إليها، عند إجراء Book.search(...)
. إذا كنت لا تريد eager_load
التلقائي أو تحتاج إلى إجراء عمليات خاصة، فحدد scope
:
class Book < ActiveRecord :: Base
# ...
search_scope :search do
# ...
scope { joins ( :author ) . eager_load ( :comments ) } # etc.
end
# ...
end
سيقوم SearchCop بعد ذلك بتخطي أي تحميل تلقائي للارتباط وسيستخدم النطاق بدلاً من ذلك. يمكنك أيضًا استخدام scope
مع aliases
لإجراء عمليات ربط معقدة بشكل تعسفي والبحث في النماذج/الجداول المرتبطة:
class Book < ActiveRecord :: Base
# ...
search_scope :search do
attributes similar : [ "similar_books.title" , "similar_books.description" ]
scope do
joins "left outer join books similar_books on ..."
end
aliases similar_books : Book # Tell SearchCop how to map SQL aliases to models
end
# ...
end
يمكن أيضًا الرجوع إلى جمعيات الجمعيات واستخدامها:
class Book < ActiveRecord :: Base
# ...
has_many :comments
has_many :users , :through => :comments
search_scope :search do
attributes user : "users.username"
end
# ...
end
يحاول SearchCop استنتاج اسم فئة النموذج واسم SQL المستعار من السمات المحددة لاكتشاف تعريفات نوع البيانات تلقائيًا، وما إلى ذلك. وعادةً ما يعمل هذا بشكل جيد. في حالة أنك تستخدم أسماء جداول مخصصة عبر self.table_name = ...
أو إذا كان النموذج مرتبطًا عدة مرات، فلا يمكن لـ SearchCop مع ذلك استنتاج أسماء الفئة وأسماء الأسماء المستعارة لـ SQL، على سبيل المثال
class Book < ActiveRecord :: Base
# ...
has_many :users , :through => :comments
belongs_to :user
search_scope :search do
attributes user : [ "user.username" , "users_books.username" ]
end
# ...
end
هنا، لكي تعمل الاستعلامات، يجب عليك استخدام users_books.username
، لأن ActiveRecord يعين اسمًا مستعارًا مختلفًا لـ SQL للمستخدمين ضمن استعلامات SQL الخاصة به، لأن نموذج المستخدم يرتبط عدة مرات. ومع ذلك، نظرًا لأن SearchCop لا يمكنه الآن استنتاج نموذج User
من users_books
، فيجب عليك إضافة:
class Book < ActiveRecord :: Base
# ...
search_scope :search do
# ...
aliases :users_books => :users
end
# ...
end
لإخبار SearchCop بالاسم المستعار لـ SQL المخصص ورسم الخرائط. بالإضافة إلى ذلك، يمكنك دائمًا إجراء عمليات الانضمام بنفسك عبر كتلة scope {}
بالإضافة إلى aliases
المستعارة واستخدام أسماء SQL المستعارة المخصصة الخاصة بك لتصبح مستقلة عن الأسماء التي تم تعيينها تلقائيًا بواسطة ActiveRecord.
تدعم استعلامات سلسلة الاستعلام AND/and
, OR/or
, :
, =
, !=
, <
, <=
, >
, >=
, NOT/not/-
, ()
, "..."
و '...'
. عوامل التشغيل الافتراضية هي AND
matches
، OR
لها الأسبقية على AND
. لا يمكن استخدام NOT
إلا كمشغل infix فيما يتعلق بسمة واحدة.
تدعم الاستعلامات المستندة إلى التجزئة and: [...]
و or: [...]
، والتي تأخذ مصفوفة من not: {...}
، matches: {...}
، eq: {...}
، not_eq: {...}
, lt: {...}
, lteq: {...}
, gt: {...}
, gteq: {...}
query: "..."
. علاوة على ذلك، query: "..."
يجعل من الممكن إنشاء استعلامات فرعية. تنطبق القواعد الأخرى لاستعلامات سلسلة الاستعلام على الاستعلامات المستندة إلى التجزئة أيضًا.
يوفر SearchCop أيضًا القدرة على تحديد عوامل التشغيل المخصصة عن طريق تحديد generator
في search_scope
. ويمكن بعد ذلك استخدامها مع البحث عن الاستعلام القائم على التجزئة. يعد هذا مفيدًا عندما تريد استخدام عوامل تشغيل قاعدة البيانات غير المدعومة بواسطة SearchCop.
يرجى ملاحظة أنه عند استخدام المولدات، فأنت مسؤول عن تنقية/نقل القيم (انظر المثال أدناه). وإلا فإن المولد الخاص بك سوف يسمح بإدخال SQL. وبالتالي، يرجى استخدام المولدات فقط إذا كنت تعرف ما تفعله.
على سبيل المثال، إذا أردت إجراء استعلام LIKE
حيث يبدأ عنوان كتاب بسلسلة، فيمكنك تحديد نطاق البحث كما يلي:
search_scope :search do
attributes :title
generator :starts_with do | column_name , raw_value |
pattern = " #{ raw_value } %"
" #{ column_name } LIKE #{ quote pattern } "
end
end
عندما تريد إجراء البحث، يمكنك استخدامه على النحو التالي:
Book . search ( title : { starts_with : "The Great" } )
ملاحظة أمنية: سيتم استيفاء الاستعلام الذي تم إرجاعه من المولد مباشرة إلى الاستعلام الذي ينتقل إلى قاعدة البيانات الخاصة بك. يؤدي هذا إلى فتح نقطة حقن SQL محتملة في تطبيقك. إذا كنت تستخدم هذه الميزة، فستحتاج إلى التأكد من أن الاستعلام الذي تعيده آمن للتنفيذ.
عند البحث في الحقول المنطقية والتاريخ والوقت والطابع الزمني وما إلى ذلك، يقوم SearchCop بإجراء بعض التعيينات. الاستعلامات التالية متكافئة:
Book . search ( "available:true" )
Book . search ( "available:1" )
Book . search ( "available:yes" )
إلى جانب
Book . search ( "available:false" )
Book . search ( "available:0" )
Book . search ( "available:no" )
بالنسبة لحقول التاريخ والوقت والطابع الزمني، يقوم SearchCop بتوسيع قيم معينة إلى نطاقات:
Book . search ( "created_at:2014" )
# ... WHERE created_at >= '2014-01-01 00:00:00' AND created_at <= '2014-12-31 23:59:59'
Book . search ( "created_at:2014-06" )
# ... WHERE created_at >= '2014-06-01 00:00:00' AND created_at <= '2014-06-30 23:59:59'
Book . search ( "created_at:2014-06-15" )
# ... WHERE created_at >= '2014-06-15 00:00:00' AND created_at <= '2014-06-15 23:59:59'
تسلسل عمليات البحث ممكن. ومع ذلك، فإن التسلسل حاليًا لا يسمح لـ SearchCop بتحسين الاستعلامات الفردية لمؤشرات النص الكامل.
Book . search ( "Harry" ) . search ( "Potter" )
سوف تولد
# MySQL: ... WHERE MATCH(...) AGAINST('+Harry' IN BOOLEAN MODE) AND MATCH(...) AGAINST('+Potter' IN BOOLEAN MODE)
# PostgreSQL: ... WHERE to_tsvector(...) @@ to_tsquery('simple', 'Harry') AND to_tsvector(...) @@ to_tsquery('simple', 'Potter')
بدلاً من
# MySQL: ... WHERE MATCH(...) AGAINST('+Harry +Potter' IN BOOLEAN MODE)
# PostgreSQL: ... WHERE to_tsvector(...) @@ to_tsquery('simple', 'Harry & Potter')
وبالتالي، إذا كنت تستخدم فهارس النص الكامل، فمن الأفضل أن تتجنب التسلسل.
عند استخدام Model#search
، يمنع SearchCop بشكل ملائم ظهور بعض الاستثناءات في حالة كون سلسلة الاستعلام التي تم تمريرها إليها غير صالحة (أخطاء التحليل، وأخطاء نوع البيانات غير المتوافقة، وما إلى ذلك). بدلاً من ذلك، يقوم Model#search
بإرجاع علاقة فارغة. ومع ذلك، إذا كنت بحاجة إلى تصحيح بعض الحالات، فاستخدم Model#unsafe_search
، مما سيؤدي إلى ظهورها.
Book . unsafe_search ( "stock: None" ) # => raise SearchCop::IncompatibleDatatype
يوفر SearchCop أساليب عاكسة، وهي #attributes
و #default_attributes
و #options
و #aliases
. يمكنك استخدام هذه الطرق لتوفير عنصر واجهة مستخدم للمساعدة في البحث الفردي لنماذجك، على سبيل المثال، والذي يسرد السمات المطلوب البحث فيها بالإضافة إلى السمات الافتراضية، وما إلى ذلك.
class Product < ActiveRecord :: Base
include SearchCop
search_scope :search do
attributes :title , :description
options :title , default : true
end
end
Product . search_reflection ( :search ) . attributes
# {"title" => ["products.title"], "description" => ["products.description"]}
Product . search_reflection ( :search ) . default_attributes
# {"title" => ["products.title"]}
# ...
بدءًا من الإصدار 1.0.0، يستخدم SearchCop الإصدار الدلالي: SemVer
git checkout -b my-new-feature
)git commit -am 'Add some feature'
)git push origin my-new-feature
)