2013-11-01 40 views
1

我需要一種方法來通過數據庫並返回適當的結果。在這種情況下,它按作者,標題,出版日期或ISBN代碼搜索書籍。我決定使用where()方法,但我遇到了兩個問題:'where'方法中的正則表達式

1)我無法搜索多個字段。它很容易尋找一個標題:

def self.browse(query) 
    if query.nil? 
     nil 
    else 
     self.where("title REGEXP :query", query: query) 
    end 
end 

,但我不知道如何設置它尋找標題或作者或ISBN等試圖

self.where("(title OR author OR publishing_date OR isbn) REGEXP :query", query: query) 

但它不工作

和第二,我希望我的查詢只匹配單詞的開頭或結尾。在MySQL Workbench中它非常容易,但我很難在Rails中做到這一點。這是我到目前爲止已經試過(和失敗):

self.where("title REGEXP :query", query: /^(query)*$/) 

self.where("title REGEXP /^:query/", query: query) 

self.where("title REGEXP :query", query: $"query"^) 

不用說,在互聯網上我發現了許多不同的文檔或教程,有一句話說「^」應該是在年底,另一方面,它應該在開始時...

+0

我會後通過加入'.to_sql'繼續調試你在哪兒打電話。這將吐出ActiveRecord生成的SQL查詢,以便您可以將其與您想要的進行比較。 – theodorton

回答

1

1)你會想在你的where sql中使用括號和AND和OR子句:

(title IS NOT NULL AND title REGEXP :id_query) OR (name IS NOT NULL AND name REGEXP :name_query) 

2)你會想同時使用^(begin ning的行)和$(行尾),像這樣。

(^something|something$) 

下面是我與我自己的代碼匹配的整個事情的一個例子。用自己的列更換標識和名稱,並把多餘或在那裏對陣多列

Charity.where("(id IS NOT NULL AND id REGEXP :id_query) OR (name IS NOT NULL AND name REGEXP :name_query)", id_query:'1', name_query:'(^a|a$)') 

Here is the to_sql output of the above: 

Charity.where("(id IS NOT NULL AND id REGEXP :id_query) OR (name IS NOT NULL AND name REGEXP :name_query)", id_query:'1', name_query:'(^a|a$)').to_sql 
=> "SELECT `charities`.* FROM `charities` WHERE ((id IS NOT NULL AND id REGEXP '1') OR (name IS NOT NULL AND name REGEXP '(^a|a$)'))" 
+0

我幾乎在那裏,但與$運算符有問題。我用它像你在例子中做的,但它不正確地查找以我的查詢結束的記錄。例如,當參數是「ord」時,「戒指之王」不在返回的範圍內。 (當參數是「lor」時) – Leo

+0

啊,這是因爲$意味着「行尾」,如果您在字段中檢查多個單詞,$不適用於您。相反,看看這裏的答案MySQL字邊界匹配器:http://stackoverflow.com/questions/7261496/more-efficient-word-boundary-query-in-mysql – Houen

0

創建SQL查詢,並傳遞到ActiveRecord的執行方法,它將EXCUTE SQL查詢,不需要ActiveRecord的查詢更改

sql query = "your sql query" 
ActiveRecord::Base.connection.execute(sql query) 
1

這應做到:

self.where("title REGEXP ? OR author REGEXP ? OR publishing_date REGEXP ? OR isbn REGEXP ?", query, query, query, query) 

「?」將按照包含的變量進行排序。如果您想對每列使用相同的正則表達式,那麼只需按原樣插入代碼

至於第二部分,您可能需要檢查LIKE運算符。

要匹配以給定的字符串開始列你會怎麼做:

self.where("title LIKE ?", (query + "%")) 

而且以匹配特定的字符串結尾列:

self.where("title LIKE ?", ("%" + query)) 
0

您可以使用or

class MyARModel < ActiveRecord::BAse 
    scope :search, ->(rgx) do  
    where('title REGEXP ?', rgx) 
    .or('author REGEXP ?' rgx) 
    .or('publishing_date REGEXP ?' rgx) 
    .or('isbn REGEXP ?' rgx) 
    end 
#...