2012-10-18 23 views
0

我有一個PHP驅動的網站,我正在轉換爲Rails。我目前在MySQL例程中有以下邏輯。將MySQL例程移動到模型

DECLARE FirstWeighinDate DATE; 
DECLARE FirstWeighinWeight DECIMAL(5,1); 
DECLARE MostRecentWeighinDate DATE; 
DECLARE MostRecentWeighinWeight DECIMAL(5,1); 
DECLARE NumberOfWeighins INT(11); 
DECLARE NumberOfDeficitRecords INT(11); 
DECLARE AverageDeficit INT(11); 
DECLARE UserHeight INT(11); 
DECLARE MostRecentBMI DECIMAL(5,1); 

SELECT date INTO FirstWeighinDate FROM tblDeficitEntries WHERE weight IS NOT NULL AND user_id = inUserId ORDER BY date ASC LIMIT 1; 
SELECT weight INTO FirstWeighinWeight FROM tblDeficitEntries WHERE weight IS NOT NULL AND user_id = inUserId ORDER BY date ASC LIMIT 1; 
SELECT date INTO MostRecentWeighinDate FROM tblDeficitEntries WHERE weight IS NOT NULL AND user_id = inUserId ORDER BY date DESC LIMIT 1; 
SELECT weight INTO MostRecentWeighinWeight FROM tblDeficitEntries WHERE weight IS NOT NULL AND user_id = inUserId ORDER BY date DESC LIMIT 1; 
SELECT Height INTO UserHeight FROM tblLogins WHERE id = inUserId LIMIT 1; 
SELECT COUNT(id) INTO NumberOfWeighins FROM tblDeficitEntries WHERE weight IS NOT NULL AND user_id = inUserId; 
SELECT COUNT(id) INTO NumberOfDeficitRecords FROM tblDeficitEntries WHERE user_id = inUserId; 
SELECT (SUM(deficit)/NumberOfDeficitRecords) INTO AverageDeficit FROM tblDeficitEntries WHERE user_id = inUserId; 
SELECT ((MostRecentWeighinWeight * 703)/(UserHeight * UserHeight)) INTO MostRecentBMI; 

SELECT FirstWeighinDate, FirstWeighinWeight, MostRecentWeighinDate, MostRecentWeighinWeight, NumberOfWeighins, NumberOfDeficitRecords, AverageDeficit, MostRecentBMI; 

我相信MVC的情況,該邏輯屬於模型。我不確定如何實現這一點。我認爲應該使用虛擬訪問器來完成這項工作。那是對的嗎?如果我應該在模型之外的某個地方有這個地方,它應該去哪裏?我不希望整個代碼在答案中被轉換,但我會非常感謝將要轉換的幾行代碼,以便我能夠實現這個想法。謝謝!

回答

1

所以,你有兩個模型:有一個用戶,並且用戶有很多關聯的Entry對象。

class User < ActiveRecord::Base 
    has_many :entries 
end 

class Entry < ActiveRecord::Base 
    belongs_to :user 
    #attributes include weight, date 
end 

那麼,這些值呢?

做我認爲你想要的最基本的方法是將所有這些轉換爲你的用戶模型上的方法,使用相關的模型。

例如,

SELECT date INTO FirstWeighinDate FROM tblDeficitEntries WHERE weight IS NOT NULL AND user_id = inUserId ORDER BY date ASC LIMIT 1; 

可以用下面的替換,在用戶等級:

def first_weighin_date 
    entries.order('date asc').first.date 
end 

然後,任何地方,你有一個用戶對象,你可以簡單地調用方法:

u = User.find_by_name('Bob') 
u.first_weighin_date 

現在,如果您打算一次爲很多用戶顯示此信息,那麼您將想要利用急切的加載。例如,這將是非常低效的:

User.all.map(&:first_weigh_in_date) 

它將單獨調用數據庫爲每個用戶對象加載相關條目。 100位用戶? 101數據庫命中。所以告訴Rails先走,並加載所有的對象,因爲你會需要它們:

User.includes(:entries).map(&:first_weigh_in_date) 

現在有隻有兩個調用數據庫,一個加載用戶和一個加載deficit_entries。

+0

你幾乎是正確的,我的模型是用戶和條目。我如何從我的視角訪問first_weighin_date?使用虛擬訪問器? – Brandon

+0

這是一個在模型上定義的方法,所以你可以調用它。如果'u'是你的用戶對象,'u.first_weighin_date'會計算並返回該值。 – MrTheWalrus

+0

完美,謝謝! – Brandon