2010-04-18 23 views
2

我有一個假設名爲Pets的控制器/模型。寵物有如下聲明:如何在Ruby on Rails中處理這種類型的模型驗證

belongs_to :owner 
has_many :dogs 
has_many :cats 

不是最好的例子,但同樣,它證明了我想要解決的問題。現在,當請求作爲HTTP POST發送到http://127.0.0.1/pets時,我想創建一個Pets實例。這裏的限制是,如果用戶沒有提交至少一隻狗或一隻貓,它應該失敗驗證。它可以同時具有,但不能同時缺失。

在Ruby on Rails中如何處理這個問題?狗不關心貓是否存在,反之亦然。任何人都可以顯示一些示例代碼,說明Pets模型看起來會如何確保一個或另一個存在,否則失敗?請記住,狗和貓不是Pets模型的屬性。如果兒童資源不可用,我不確定如何避免創建寵物。

errors.add也接受一個屬性,在這種情況下,沒有特定的屬性失敗。這幾乎是一個缺失的「虛擬」組合。參數可以以cat_name =「bob」和dog_name =「stew」的形式出現,基於屬性,我應該可以創建一個新的貓或狗,但我需要知道它們中至少有一個存在。

回答

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來在你的控制器中創建新的貓和狗。

+0

感謝您給我一個開始尋找的地方。請注意,如果我問問寵物控制器在這種情況下的外觀如何?我是否試圖創建一個新的貓實例和一個新的狗實例,如果一個參數存在並讓其他人擔心? – randombits 2010-04-18 16:54:57

+0

是的,讓你的模型擔心驗證。我已經包含一個簡單的控制器示例。 – molf 2010-04-18 17:05:07

+0

正是我所期待的,非常感謝幫助我更好地理解問題。 – randombits 2010-04-18 17:14:04