Как обработать этот тип проверки модели в Ruby on Rails - PullRequest
2 голосов
/ 18 апреля 2010

У меня есть контроллер / модель, гипотетически названная Pets. Домашние животные имеет следующие декларации:

belongs_to :owner
has_many :dogs
has_many :cats

Не лучший пример, но опять же, он демонстрирует то, что я пытаюсь решить. Теперь, когда запрос приходит как HTTP POST к http://127.0.0.1/pets, я хочу создать экземпляр Pets. Здесь есть ограничение: если пользователь не отправит хотя бы одну собаку или одну кошку, он не пройдет проверку. Он может иметь и то и другое, но не может быть и того и другого.

Как справиться с этим в Ruby on Rails? Собаки не заботятся, существуют ли кошки, и обратное также верно. Может ли кто-нибудь показать пример кода того, как будет выглядеть модель Pets, чтобы гарантировать, что один или другой существует, или потерпеть неудачу в противном случае? Помните, что собаки и кошки не являются атрибутами модели Pets. Я не уверен, как избежать создания Pets, если его дочерние ресурсы недоступны.

errors.add также принимает атрибут, в этом случае нет конкретного атрибута, который не работает. Это почти «виртуальная» комбинация, которая отсутствует. Параметры могут иметь вид cat_name = "bob" и dog_name = "stew", основываясь на атрибуте, я должен иметь возможность создать новую кошку или собаку, но мне нужно знать, что хотя бы один из них существует.

1 Ответ

1 голос
/ 18 апреля 2010

Вы ищете 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_name или dog_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

Кроме того, для большей гибкости вы можете использовать вложенные атрибуты для создания новых кошек и собак в вашем контроллере.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...