2009-10-27 4 views
0

Я имею следующую проблему:Проверка включения в ActiveRecord has_many ассоциации

У меня есть модель ActiveRecord под названием Widget, который имеет несколько полей, мы будем называть их field_a и field_b, в дополнение к стандартным полям Rails. У меня также есть модель под названием Person, у которой есть много виджетов через ассоциацию has_many (Person.widgets).

В создании действия моего контроллера для виджета я хочу проверить, чтобы новый виджет, созданный из параметров {@widget = Widget.new (params [: widget])}, не существует в Коллекция Person.widgets перед сохранением этого нового виджета в базе данных, но с использованием Person.widgets.include? (@ Widget) не дает мне результатов, которые хотят, если field_a и field_b имеют те же значения, что и виджет в коллекции.

Я предполагаю, что это потому, что новый виджет (@widget) технически не существует в этой коллекции, потому что это новый рекорд, даже если это важные атрибуты (field_a и field_b) может соответствовать одному уже в БД, связанной с экземпляром Person.

Любые мысли о том, как я могу проверить это, чтобы я не создавал функционально повторяющиеся виджеты в db, связанные с тем же экземпляром Person? Я пытался переопределить хэш, eql? и == методы на модели Widget, но это сломало некоторые другие вещи ... слава богу за TDD! :-)

Спасибо, Майк

ответ

0
class Widget 
    before_save :validate_unique_for_person 
    def matches?(w) 
    field_a == w.field_a && field_b == w.field_b 
    end 
    def validate_unique_for_person 
    errors.add("base","widget already exists for person") if person.widgets.any? { |w| matches?(w) && self != w } 
    end 
end 
+0

Спасибо за помощь ... Я пытался получить немного фантазии, но это было трюк! – user197735

0

Есть причина, вы не можете просто использовать ActiveRecord::Validations#validates_uniqueness_of?

validates_uniqueness_of :field_a, :scope => [:person_id, :field_b] 
validates_uniqueness_of :field_b, :scope => [:person_id, :field_a] 

Должен сделать трюк, даже если сообщения о проверке могут быть немного запутанными в разы. Но это то, что для параметра: message для валидации.

+1

Должен иметь возможность пройти с помощью только 'validates_uniqueness_of: person_id,: scope [: field_a,: field_b]' в модели Widgets. – EmFi

+0

Это тоже должно работать, хотя сообщения об ошибках по умолчанию могут заставить ваш разум расплавиться (так как все они будут назад). – cwninja

Смежные вопросы