Проверьте, что объект имеет один или несколько связанных объектов - PullRequest
31 голосов
/ 02 марта 2012

Мне нужно убедиться, что при создании продукта у него есть хотя бы одна категория.Я мог бы сделать это с помощью пользовательского класса проверки, но я надеялся, что есть более стандартный способ сделать это.

class Product < ActiveRecord::Base
  has_many :product_categories
  has_many :categories, :through => :product_categories #must have at least 1
end

class Category < ActiveRecord::Base
  has_many :product_categories
  has_many :products, :through => :product_categories
end

class ProductCategory < ActiveRecord::Base
  belongs_to :product
  belongs_to :category
end

Ответы [ 3 ]

60 голосов
/ 02 марта 2012

Существует проверка, которая проверит продолжительность вашей ассоциации.Попробуйте это:

class Product < ActiveRecord::Base
  has_many :product_categories
  has_many :categories, :through => :product_categories

  validates :categories, :length => { :minimum => 1 }
end
37 голосов
/ 14 июля 2014

Гарантирует, что у него есть хотя бы одна категория:

class Product < ActiveRecord::Base
  has_many :product_categories
  has_many :categories, :through => :product_categories

  validates :categories, :presence => true
end

Я считаю, что сообщение об ошибке с использованием :presence более понятно, чем использование length minimum 1 проверки

4 голосов
/ 26 апреля 2012

Вместо решения wpgreenway я бы предложил использовать метод ловушки как before_save и использовать ассоциацию has_and_belongs_to_many.

class Product < ActiveRecord::Base
  has_and_belongs_to_many :categories
  before_save :ensure_that_a_product_belongs_to_one_category

  def ensure_that_a_product_belongs_to_one_category
    if self.category_ids < 1 
      errors.add(:base, "A product must belongs to one category at least")
      return false
    else
      return true
    end
  end   

class ProductsController < ApplicationController
  def create
    params[:category] ||= []
    @product.category_ids = params[:category]
    .....
  end
end

И, на ваш взгляд, использование может использовать, например, options_from_collection_for_select

...