如何避免保存空白模型哪些属性可以为空

时间:2010-04-20 09:58:47

标签: ruby-on-rails ruby validation

我有两个与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这样的方式。

感谢。

3 个答案:

答案 0 :(得分: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 在这种情况下,您还应该检查控制器中的作者字段。因此,您的作者字段必须位于单独的params组中。

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

答案 1 :(得分:1)

把它放在书籍模型中:

validates_associated :authors, :on => :create

除非您希望以无提示方式忽略无效的作者对象,否则不会保存。那么目前的解决方案就是解决问题的一种方法。

您使用的是哪种版本的导轨? accepts_nested_attributes_for可能会在这种情况下使用。

答案 2 :(得分: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