2012-12-31 17 views
0

我正在試驗一些概念(實際上是通過構建1978年數據庫WHATSIT的RoR版本來玩和學習)。從數組構建ILIKE子句

它基本上是一個has_many:通過結構與主題 - >標籤< - 價值。我試圖通過使用查詢文本字段來輸入命令來複制一些命令行結構。基本上是這樣的:What's steve's phone

總之,大多數搜索使用ILIKE。我雖然通過允許OR條件使用某種形式的數組來增強它。像What's steve's [son,daugher]。我通過直接創建ILIKE子句來實現它,但不能用字符串替換。

def bracket_to_ilike(arrel,name,bracket) 
    bracket_array = bracket.match(/\[([^\]]+)\]/)[1].split(',') 
    like_clause = bracket_array.map {|i| "#{name} ILiKE '#{i}' "}.join(" OR ") 
    arrel.where(like_clause) 
end 

bracket_to_ilike(tags,'tags.name','[son,daughter]')產生類似條款tags.name ILiKE 'son' OR tags.name ILiKE 'daughter'

而且它得到了關係,但所有人都在談論使用形式("tags.name ILiKE ? OR tags.name ? ",v1,v2,vN..),我以爲我會問,如果任何人有如何做任何想法那。

動態創建變量可以從我搜索的內容中獲得,但不支持。我只是想知道是否有人試圖創建一個方法,可以添加一個具有可變數字參數的where子句。我嘗試將where子句發送給關係,但它不喜歡那樣。

史蒂夫

回答

0

感謝菲利普指點我在正確的方向。

  • 我不知道,你可以傳遞一個數組的where子句 - 這開闢了一些選項
  • 我曾用圖示操作幾次,但它並沒有打我,它實際上創造一個對象(變量)

[兒子,女兒]的東西只是一個控制檯練習,看看我能做什麼,但不知道我會怎麼做。我結束了模型關聯並創建了陣列,並實現了OR搜索。

def array_to_ilike(col_name,keys) 
    ilike = [keys.map {|i| "#{col_name} ILiKE ? "}.join(" OR "), *keys ] 
    #ilike = [keys.size.times.map{"#{col_name} ILIKE ?"}.join(' OR '), *keys ] 
    #both work, guess its just what you are use to. 
end 

然後我讓管道(|)字符在我的題目,標籤,值的搜索,所以的whatsit風格問題

  • What's Steve's Phone Home|Work =>顯示家庭和工作電話
  • steve phone home|work的「 s的東西只是爲了顯示
  • steve son|daughter =>顯示兒童
  • phone james%|lori% =>顯示任何人的姓名電話號碼與詹姆斯和洛瑞開始
  • james%|lori% =>轉儲誰的名字上的任何人的所有信息與詹姆斯或洛瑞開始

然後查詢解析命令,如果它遇到|在任何的話,它會做這樣的事情:

t_ilike = array_to_ilike('tags.name',name.split("|")) 
# or I actually stored it off on the inital parse 
t_ilike = @tuple[:tag][:ilike] ||= ['tags.name ilike ?',tag] 

再次,這僅僅是一個學習鍛鍊創建非CRUD類來處理解析和搜索。

史蒂夫

0

幾件事情要注意在你的代碼...當bracket_array的元素之一包含一個單引號

  • 會發生什麼?
  • 如果我更進一步並設置一個元素來說「'; drop tables ...」會發生什麼?

我第一次重構你的代碼會看看Arel是否可以做到這一點。或者Sequeel,或者他們現在稱之爲「metawhere」的寶石。我的第二個刺會是這樣的:

arrel.where([ bracket_array.size.times.map{"#{name} ILIKE ?"}.join(' OR '), *bracket_array ]) 

我沒有測試它,但這個想法是使用bracket_array的大小產生的邏輯與的條件字符串,然後使用圖示操作者通過在所有的價值。

+0

你讓我更接近,但時間循環返回一個固定的數字,給予和連接錯誤。回到我的地圖循環並使用splat,它給出了類似於子句和變量的權利。起初它給了我一個And子句,但我認爲是因爲我的標籤實例搞砸了。 'tags.where(* [bracket_array.map {| i |「#{name} ILiKE?」} .join(「OR」),* bracket_array])'工作。現在我只需要明白爲什麼要在哪裏取數組參數。這個實驗又是爲了學習更多的Ruby。 – appleII717

+0

@ appleII717是的,你說得對。我應該有'bracket_array.size.times.map'(缺少.map)。我更新了我的帖子。 –