2015-11-30 45 views
0

我有一個User模型,可以有很多Websites。例如,我將能夠呼叫User.websites,它將拉起用戶擁有的所有網站的ActiveRecord數組。但每個網站都使用單表繼承(STI)和一個確定網站類型的列,如商業,廣告或論壇。我的問題是,如果用戶擁有一個特定類型的網站,我將創建一個case/when語句來運行一個函數。例如:STI類型列的案例說明

@user = User.first 
case @user.websites 
    when includes?(Commercial) 
     'This user has a commercial website' 
    when includes?(Forum) 
     'This user has a forum website' 
    when include?(Ad) 
     'This user has a advertisement website' 
end 

有沒有人有關於做這種事情的最佳方法的線索?

+2

調用模型上的關係而不是實例對象'@ user'毫無意義 –

+0

@JoeHalfFace我猜這是誤導,我不會調用模態本身。只是它的一個實例。它更像是一個示例佔位符。我會編輯它。謝謝 – sclem72

+0

這些功能做什麼?似乎這個邏輯不應該是用戶模型的責任,而應該是網站模型或另一個可能的PORO。現在,如果一個用戶網站同時包含商業和論壇網站,商業將執行,而不是論壇 – engineersmnky

回答

4

最簡單的方法是使用map方法。只需一行!

@user.websites.select(:type).uniq.map{ 
     |x| puts "This user has a #{x.type.downcase} website" 
    } 

或者如果你想在數組中有這些字符串。

@user.websites.select(:type).uniq.map{|x| x.type.downcase} 

如果你想運行功能。我會建議以友好的方式命名這些功能,例如commercial_cost,forum_cost等。這樣您就可以使用send方法,它可以使代碼緊湊。

@user.websites.select(:type).uniq.map{ |x| @user.send(x.type.downcase + "_cost") } 
2
def types 
    'This user has following websites: ' + 
    websites.pluck(:type).map(&:downcase).join(', ') 
end 
0
#user.rb 

def return_data(*types) 
    types.each do |t| 
    if Website.where(:user_id => self.id, :type=> t).length>0 
     send "method_for_owners_of_#{t}_site" 
    end 
    end 
end 

def method_for_owners_of_Commercial_site 
end 
#... 

@user.return_data(["Commercial"]) 
@user.return_data(["Commercial", "Ad"]) 
... 

根據Rails的API

當你Firm.create(名稱: 「37signals公司」),該記錄將在公司的表型保存 = 「公司」。

+0

注意,這將執行n個查詢,其中n是提供給該方法的類型的數量。即使用戶實例可以通過關聯知道它是否具有給定類型的站點。 – engineersmnky