2011-07-30 55 views
2

我有以下場景:如何批量驗證Rails中的關聯

我的模型之一,我們稱之爲'發佈',有多個關聯模型,圖像。

這些圖像中的一個,並且只有一個可以是其Post的關鍵圖像(表示爲Image模型上的布爾標誌,並且通過對使用Post作爲其範圍的Image模型進行驗證來強制執行) 。

當然現在當我要更新主形象標誌,它發生的圖像模型的關鍵標誌被設置爲true,因爲還是有設置爲true的關鍵標誌另一圖片驗證失敗。

我知道,那件事尖叫改造成在Post模型,其鏈接到關鍵圖像關聯,但有一個方法來驗證散裝協會Rails的?

什麼是你拿,你會做出關鍵圖像有關Post模型獨立的協會或者你可以使用布爾標誌?當你想更改主形象,做這樣的事情

# Post.rb 
has_many :images, :conditions => ['primary = ?', false] 
has_one :primary_image, :conditions => ['primary = ?', true] 

回答

3

有一個簡單的解決方案,但它需要一些信任:

  • 刪除驗證「是否只有一個主圖像?」
  • 確保有會添加濾鏡

大好處是,你不必查看在您的控制器或樁模型什麼是唯一一個主要圖像。只需拍攝一張圖像,將is_primary設置爲true並保存即可。

因此設置可能看起來像:

class Post < ActiveRecord::Base 
    has_many :images 

    # some sugar, @mypost.primary_image gets the primary image 
    has_one :primary_image, 
      :class_name => "Image", 
      :conditions => {:is_primary => true } 
end 

class Image < ActiveRecord::Base 
    belongs_to :post 

    # Image.primary scopes on primary images only 
    scope :primary, where(:is_primary => true) 

    # we need to clear the old primary if: 
    # this is a new record and should be primary image 
    # this is an existing record and is_primary has been changed to true 

    before_save :clear_primary, 
       :if => Proc.new{|r| (r.new_record? && r.is_primary) || (r.is_primary_changed? && r.is_primary) } 

    def clear_primary 
    # remove old primary image 
    Image.update_all({:is_primary => false}, :post_id => self.post_id) 
    end 
end 

編輯:

這將在任何情況下工作 - 爲什麼?如果所有驗證成功

  • 整個保存被包裹在一個事務

    • before_save時纔會激活,這意味着如果clear_primary或​​本身出現故障時圖像的保存,everyhing將回滾到原來的狀態。
  • +0

    哇,感謝您的!唯一的問題是,我需要跳過最後update_attribute通話,這似乎並不在Rails的3 – Kitto

    +0

    嗨支持了回調,我還沒有認識到,update_attribute Rails中3已經改變了我改變了代碼,以便它也將與Rails 3一起工作。 – sled

    +0

    我將如何通過設置嵌套形式的單選按鈕來設置主圖像? 我試圖image_form.radio_button(:is_primary,真),但軌給每個單選按鈕,打破每個單選按鈕進入自己的組不同的名稱。 – henryeverett

    -1

    那麼你可以發表你的模型中做到這一點

    # Post.rb 
    def new_primary_image(image_id) 
        primary_image.primary = false 
        Image.find(image_id).primary = true 
    end