2010-05-28 33 views
0

兩種型號:如何搜索這個activerecord示例?

發票

:invoice_num  string 
    :date    datetime 
    . 
    . 
    :disclaimer_num  integer (foreign key) 

免責聲明

:disclaimer_num  integer 
    :version   integer 
    :body    text 

對於每個disclaimer有多個版本,並且將被保存在數據庫中。這是我怎麼寫搜索(簡體):

scope = Invoice.scoped({ :joins => [:disclaimer] }) 
scope = scope.scoped :conditions => ["Invoice.invoice_num = ?", "#{params[:num]}"] 
scope = scope.scoped :conditions => ["Disclaimer.body LIKE ?", "%#{params[:text]}%"] 

然而,上述搜索將搜索再次所有版本的免責聲明。我怎樣才能限制搜索只有最後免責聲明(即version整數是最大的)。

請注意:

發票不保留版本號。新的免責聲明將被添加到免責聲明表並保留舊版本。

回答

2

如果只想從免責條款最新版本的發票,把條件對disclaimer_num。我還建議在Disclaimer中創建一個幫助器方法,以使代碼中的代碼更清晰。

class Disclaimer < ActiveRecord::Base 
    def latest 
    find(:first, :order => "version DESC") 
    end 
end 

scope = scope.scoped :conditions => { :disclaimer_num => Disclaimer.latest } 

我真的希望你爲了簡潔而從你的範圍中刪除了SQL注入預防代碼。

+0

感謝。順便說一句,'範圍'應該是:'scope = scope.scoped:conditions => {:disclaimer_num => Disclaimer.latest.disclaimer_num}' – ohho 2010-06-03 02:16:14

+0

是否diclaimer_num是免責聲明表的主鍵?我假設它是,這就是爲什麼我不需要.disclaimer_num。 – Samuel 2010-06-03 04:08:08

+0

這是一個複合主鍵(如果不計算默認'id'鍵),即':declaimer_num' +':version' – ohho 2010-06-03 06:19:45

0

嗯...我可能只是存儲過程的快樂,但我認爲在這一點上,你會從存儲過程中大大受益(甚至是視圖)是做了這樣的事情:

CREATE PROCEDURE GetRecentDisclaimer @BodyFragmentBeingSearched VARCHAR(200) AS SELECT MAX(版本),disclaimer_num,身體 FROM免責聲明 WHERE 身體像@BodyFragmentBeingSearched GROUP BY disclaimer_num,身體

從那裏,有人寫了一博客AB出來你會如何調用Rails的存儲過程和填充ActiveRecord對象,看看這裏:

http://nasir.wordpress.com/2007/12/04/stored-procedures-and-rails-part-2/

0

添加這兩個條件(可在範圍內進行):

"ORDER BY disclaimer.disclaimer_num DESC" 
"LIMIT 0, 1"