2017-01-31 47 views
1

與在before_save回調修改子記錄它的父掙扎。修改子記錄在before_save回調

子記錄是Photo,它具有一個屬性main這是一個布爾值。

父記錄是Dealhas_many :photos

修改記錄的表格嵌套來進行更改deal和用戶還可以更改photo的屬性或添加或刪除photos

這裏是擦。我要始終有一個main照片,我打算做一個before_save回調,在那裏我檢查的照片,並且如果在列表中沒有照片main我在列表中設置主要爲true的第一張照片。

它不保存子記錄,我會想到它。我已經添加調試語句,這樣我可以證明,該方法被調用,我也能說出的主要價值被標記爲真......它只是不被保存。我誤解了這個回調?光棚會很棒。多謝你們!

class Deal < ActiveRecord::Base 

    has_many :photos, dependent: :destroy 
    accepts_nested_attributes_for :photos, allow_destroy: :true 

    before_save :set_main_photo 


    ### bunch of other unrelated stuff 

    private 
    def set_main_photo 
    if self.photos 
     if self.photos.main.nil? 
     self.photos.first.main = true 
     end 
    end 
    end 
end 

回答

2

這裏有一些事情正在進行,但您的主要問題是以這種方式修改孩子不會自動保存記錄。您需要更新您的set_main_photo才能在子記錄上撥打.save。當你在它,一些其他的變化是謹慎的:

def set_main_photo 
    if photos.any? 
    unless photos.main.present? 
     photos.first.update_attribute :main, true 
    end 
    end 
end 

有了這個做了,現在你已經在具有代表其關係與條件上Photo屬性尷尬的方式結合DealPhotosDeal,並Deal管理該屬性。更好的方法是創建一個新的關係建模,內Deal保持責任屬性完全:

class Deal 
    has_many :photos 
    belongs_to :main_photo, class_name: 'Photo' 
end 

class Photo 
    belongs_to :deal 
end 

這可讓您只需設置deal.main_photo = deal.photos.first然後deal.save

+1

第一個例子只有在交易已被持續時纔有效。它可以通過使用'assign_attribute'來代替。但後來的例子首先是一個更好的主意。 – max