如何在Ruby on Rails中处理这种类型的模型验证

时间:2010-04-18 16:24:38

标签: ruby-on-rails activerecord

我有一个假设名为Pets的控制器/模型。宠物有以下声明:

belongs_to :owner
has_many :dogs
has_many :cats

不是最好的例子,但它再次证明了我正在努力解决的问题。现在当一个请求作为HTTP http://127.0.0.1/pets进入时,我想创建一个Pets实例。这里的限制是,如果用户没有提交至少一只狗或一只猫,它将无法通过验证。它可以同时拥有两者,但它不能同时缺失。

如何在Ruby on Rails中处理这个问题?如果猫存在,狗不在乎,反之亦然。任何人都可以显示一些示例代码,了解Pets模型的外观,以确保其中一个或另一个存在,否则会失败?请记住,狗和猫不是宠物模型的属性。如果没有可用的儿童资源,我不确定如何避免创建宠物。

errors.add也有一个属性,在这种情况下,没有特定的属性失败。这几乎是一个缺失的“虚拟”组合。参数可能以cat_name =“bob”和dog_name =“stew”的形式出现,根据属性,我应该能够创建一个新的猫或狗,但我需要知道它们中至少存在一个。

1 个答案:

答案 0 :(得分:1)

您正在寻找errors.add_to_base。这应该可以解决问题:

class Pet < ActiveRecord::Base
  belongs_to :owner
  has_many :dogs
  has_many :cats

  validate :has_cats_or_dogs

  def has_cats_or_dogs
    if dogs.empty? and cats.empty?
      errors.add_to_base("At least one dog or cat required")
    end
  end
end

如果您想将cat_namedog_name传递给控制器​​操作,它可能如下所示:

class PetsController < ApplicationController
  # ...

  def create
    @pet = Pet.new(params[:pet])
    @pet.cats.build(:name => params[:cat_name]) if params[:cat_name]
    @pet.dogs.build(:name => params[:dog_name]) if params[:dog_name]
    if @pet.save
      # success
    else
      # (validation) failure
    end
  end
end

或者,为了更灵活,您可以使用nested attributes在控制器中创建新的猫狗。