2009-04-13 38 views
4

我正在寫一個小型的瀏覽器遊戲作爲學習RoR的項目,我對它很陌生。我該如何改進這個Rails代碼?

這是一個由cronjob定期調用的小方法。

我猜應該有添加元素到魔藥數組,然後在最後做一個批量保存的某種方式,我也不喜歡每次循環獲得項目數時碰到數據庫再次爲市場。

def self.restock_energy_potions 
    market = find_or_create_market 

    potions = EnergyPotion.find_all_by_user_id(market.id) 

    while (potions.size < 5) 
    potion = EnergyPotion.new(:user_id => market.id) 
    potion.save 
    potions = EnergyPotion.find_all_by_user_id(market.id) 
    end  
end 

回答

8

我不知道我在理解你的問題。你在找這樣的東西嗎?

def self.restock_energy_potions 
    market = find_or_create_market 
    potions = EnergyPotion.find_all_by_user_id(market.id) 
    (potions.size...5).each {EnergyPotion.new(:user_id => market.id).save } 
    end  
end 

請注意範圍內的三重點;如果已經有5個,你不想創建一個藥水。

另外,如果你的藥水被鏈接了(例如通過has_many),你可以通過market.potions屬性創建它們(我猜這裏是關於用戶和市場 - 細節取決於您的模型設置)並將它們一次全部保存。不過,我認爲數據庫節省不會很大。

+0

是的,這看起來接近我之後的解決方案,但有沒有辦法一次保存所有新葯?例如,創建您需要的額外3,然後只進行一次數據庫調用?或者這只是想微觀優化? – Kirschstein 2009-04-13 18:35:51

0

假設您的市場/用戶has_many藥水,你可以這樣做:

def self.restock_energy_potions 
    market = find_or_create_market 
    (market.potions.size..5).each {market.potions.create(:user_id => market.id)} 
end 
0

一)使用協會:

class Market < AR::Base 
    # * note that if you are not dealing with a legacy schema, you should 
    # rename user_id to market_id and remove the foreigh_key assignment. 
    # * dependent => :destroy is important or you'll have orphaned records 
    # in your database if you ever decide to delete some market 
    has_many :energy_potions, :foreign_key => :user_id, :dependent => :destroy 
end 

class EnergyPotion < AR::Base 
    belongs_to :market, :foreign_key => :user_id 
end 

二)不需要添加每一個後重新加載的關聯。也移動功能 到模型:

find_or_create_market.restock 

class Market 
    def restock 
    # * note 4, not 5 here. it starts with 0 
    (market.energy_potions.size..4).each {market.energy_potions.create!} 
    end 
end 

C)也注意到創造!而不是創造。 你應該檢測錯誤。 錯誤處理取決於應用程序。 你的情況,因爲你從cron運行它可以做幾件事 *發送電子郵件與警報 *捕獲異常並記錄它們,(exception_notifier插件,或hoptoad託管服務) *打印到stderror和配置cron發送錯誤一些郵件。

def self.restock_potions 
    market = find_or_create 
    market.restock 
    rescue ActiveRecord::RecordInvalid 
    ... 
    rescue 
    ... 
    end