2010-05-30 35 views
0

我有一種情況,用戶提交多模型表單。通過這種形式,我必須將用戶從我的數據庫中隨機分配到他們的帳戶。當我循環訪問數據時,我用布爾型in_use標誌標記了我分配給它們的項目。問題是,在以下情況下:Rails:掛鉤用於在模型附加到其父資源時驗證模型?

2.times do |n| 
    # grab random item which will be parent 
    parent = # some random code to grab an item not in use 
    parent.in_use = 1 
    parent.child.build 
    children << child 
end 

這裏涉及三種模型。父母本身在自己的父母中,因此子女陳述中的子女< <。這裏的問題是一個邊緣條件是抓取一個沒有使用的隨機項的代碼可以抓住同一個父項兩次,因爲我不知道這個鉤子會允許我在添加子項後保存parent.in_use其母公司通過children << child。循環將再次執行,in_use標誌未被保存到數據庫,並且可以再次選擇它。有沒有辦法堅持下去,如果在這樣的情況下驗證失敗,然後再回滾它?

回答

0

這是行不通的嗎?

2.times do |n| 
    # grab random item which will be parent 
    parent = # some random code to grab an item not in use 
    parent.child.build 
    parent.in_use 
    parent.save # <--- save the parent on the db 
    children << child 
end 

我不知道,最後一行,因爲你沒有說明什麼children變量了。我還假設parent.in_use是一種方法,而不是財產(否則你將不得不寫parent.in_use = true或類似的東西)

還有一件事 - 看起來你正在使用一個外部屬性(稱爲in_use或類似的)存儲父母是否有孩子。只計算一下孩子的數量可能會比較簡單。有幾種方法可以做到這一點,但一個很好的折衷辦法是使用自動計數器緩存。

class Parent << ActiveRecord::Base 
    has_many :children, :counter_cache => true #this will had a children_count attribute 

該屬性的名稱就像子表一樣。所以如果你寫has_many :issues,計數器將是issues_Count

您將不得不向children父表的表中添加一個children_count屬性。

然後你可以做if parent.children_count > 0而不是檢查奇怪的parent.in_use屬性。在railscast#23

0

你的問題在櫃檯上緩存

的更多信息是令人沮喪的,因爲你說你的問題在同一個父拉兩次莖,但省略拉父的代碼。然而,代碼爲一個不相干的混淆環境3模型關係留在。

無論如何,我要說這是如何從我的角度來看,我認爲你會同意: 您要求的解決方案你有兩次得到同一個父母(現在在兩個不同狀態的內存中,他們之間有不同的狀態)建立不應該存在的關係,在你的驗證中找出這個關係,在循環中有一個條件來檢查它並重試整個處理。

從我的角度來看,這聽起來像一場噩夢。作爲編寫可怕的錯誤傾向代碼的人,我強烈建議你首先獲得兩個不同的父母。不要讓錯誤在您的應用程序傳播,包含它們的早期,或更好,但防止他們發生的一切:

class YourUnnamedModel < ActiveRecord::Base 
    named_scope :unused , :conditions => { :in_use => false } 
    named_scope :random , :order => 'RANDOM()' 
    named_scope :limited , lambda { |n=1| return :limit => n } 

    def self.example 
    unused.random.limited(2).each do |parent| 
     puts "doing stuff with #{parent.inspect}" 
    end 
    nil 
    end 

end 

警告:對於一些愚蠢的原因(https://rails.lighthouseapp.com/projects/8994/tickets/1274-patch-add-support-for-order-random-in-queries),也可能是您的「RANDOM( )'可以被稱爲別的東西。