2010-04-20 41 views
1

我有兩個模型與HABTM協會,讓我們說書和作者。如何避免保存一個空白模型,其屬性可以是空的

class Book 
    has_and_belongs_to_many :authors 
end 

class Author 
    has_and_belongs_to_many :books 
end 

作者有一組屬性(例如名字,姓氏,年齡)可以全部爲空(請參閱驗證)。

validates_length_of :first_name, :maximum => 255, :allow_blank => true, :allow_nil => false 

在books_controller,我下面給所有作者追加到一本書,一個步:

@book = Book.new(params[:book]) 
@book.authors.build(params[:book][:authors].values) 

我的問題:什麼是避免作家哪些字段的保存最簡單的方法都是空白的,以防止數據庫中的「噪音」太多?

此刻,我執行以下操作:

validate :must_have_some_data 

def must_have_some_data 
    empty = true 
    hash = self.attributes 
    hash.delete("created_at") 
    hash.delete("updated_at") 
    hash.each_value do |value| 
    empty = false if value.present? 
    end 

    if (empty) 
    errors.add_to_base("Fields do not contain any data.") 
    end 
end 

也許有一個更優雅,Rails的樣的方式來做到這一點。

謝謝。

回答

1

短一點

def must_have_some_data 
    hash = self.attributes 
    hash.delete("created_at") 
    hash.delete("updated_at") 
    errors.add_to_base("Fields do not contain any data.") if hash.select{|k,v| !v.blank?}.empty? 
end 

其實我覺得,你應該確認沒有所有屬性,而只是特定的屬性,您所期待存在

def must_have_some_data 
    valid_fields = ['first_name', 'second_name', 'last_name'] 
    errors.add_to_base("Fields do not contain any data.") if self.attributes.select{|k,v| valid_fields.include? k and !v.blank?}.empty? 
end 

UPD 在這種情況下,您還應該檢查控制器中的作者字段。所以你的作者字段必須在單獨的參數組中。

def create 
    book = Book.new(params[:book]) 
    params[:authors].each do |author| 
    book.authors.build(author) unless author.attributes.each{|k,v| !v.blank?}.empty? 
    end 
    if book.save 
    ... 
    end 
end 
+0

感謝您的幫助。如果你編輯你的答案,我會再次投票(我不小心按了兩次按鈕)。 我的問題仍然如下: 當我做@ book.save時,如果其中一個關聯的作者沒有值(由於驗證),對象不會被保存。我想防止這種行爲。作者字段可以是空的,不應該在空時保存,但書應該。任何想法? – auralbee 2010-04-20 16:40:08

+0

好的,我已更新回答 – fl00r 2010-04-20 20:52:42

+0

再次感謝。隨着你的代碼中,我得到了以下錯誤:未定義的方法'屬性的陣列 這是我如何解決它: DEF創建 書= Book.new(PARAMS [:書]) PARAMS [:作者]。每做|鍵,值|除非params [:authors] [key] .select {| k,v | !v.blank?}空? end if book.save ... end end – auralbee 2010-04-21 08:05:59

1

把這個本本型號:

validates_associated :authors, :on => :create 

除非你想無效筆者對象被忽略不計,但沒有保存。那麼當前的解決方案是解決它的一種方法。

您使用的是哪種版本的導軌? accepts_nested_attributes_for可能在這種情況下使用。

1

你可以改變一個行:)

def create 
    book = Book.new(params[:book]) 
    params[:authors].each do |author| 
    # book.authors.build(author) unless author.attributes.each{|k,v| !v.blank?}.empty? 
    book.authors.build(author) unless author.all? {|key,val| val.empty?} 
    end 
    if book.save 
    ... 
    end 
end