How to avoid saving a blank model which attributes can be blank

I have two models with a HABTM association, let´s say book and author.

class Book has_and_belongs_to_many :authors end class Author has_and_belongs_to_many :books end

The author has a set of attributes (e.g. first-name,last-name,age) that can all be blank (see validation).

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

In the books_controller, I do the following to append all authors to a book in one step:

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

My question: What would be the easiest way to avoid the saving of authors which fields are all blank to prevent too much "noise" in the database?

At the moment, I do the following:

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

Maybe there is an more elegant, Rails-like way to do that.

Thanks.

-------------Problems Reply------------

A little shorter

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

Actually I think, that you should validate not all attributes, but just specific attributes, which you are expecting to presence

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 In this situation you should also check authors fields in controller. So your authors fields must be in separate params group.

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

put this in the books model:

validates_associated :authors, :on => :create

Unless you want invalid author objects to be silently ignored but not saved. Then the current solution is one way of solving it.

What version of rails are you using? accepts_nested_attributes_for might be of use in this situation.

You can change one line :)

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

Category:ruby on rails Views:8 Time:2010-04-20

Related post

Copyright (C) dskims.com, All Rights Reserved.

processed in 0.218 (s). 11 q(s)