Согласитесь с действиями, что лучшим подходом будет определение индекса в базе данных для принудительного применения отдельных записей или для добавления в модель валидатора уникальности .
Другой вариант - перехватить вызов метода ActiveRecord create для предотвращения дублирования:
class Example < ApplicationRecord
def self.create( attributes = nil, &block )
attributes.each {|attr| self.create(attr, &block) } if attributes.is_a? Array
return if find_by attributes
super attributes, &block
end
end
Основная идея здесь - прервать работу, если вы уже видите запись с такими же значениями атрибута в базе данных. но затем пусть ActiveRecord продолжит выполнять всю тяжелую работу, вызывая его с помощью super.
Если есть ситуация, когда по какой-то причине вы не можете осуществлять контроль над базой данных, чтобы предотвратить ввод дубликатов, вы можете попробовать подход, при котором вы создаете метод класса для периодической очистки дубликатов из системы.
Вот пример метода, который будет выполнять итерацию по всему набору записей и использовать хеш для отслеживания того, видел ли он значения раньше, удаляя их, если так: итак: Example.dedup
всякий раз, когда вы хотели очистить дубликаты записей.
Для тех, кто хочет следовать дома, вы можете использовать следующую миграцию:
rails g model example user_id:integer value:string
и начальный файл:
examples = Example.create([
{user_id: 1, value: 'A'},
{user_id: 1, value: 'A'},
{user_id: 1, value: 'A'},
{user_id: 1, value: 'A'},
{user_id: 1, value: 'A'},
{user_id: 1, value: 'A'},
{user_id: 1, value: 'A'},
{user_id: 2, value: 'B'},
{user_id: 2, value: 'B'},
{user_id: 3, value: 'C'},
])
в Вашем Widow1.xaml (или Вашем App.xaml, изменяясь на)......
<Window1.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="DefaultStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window1.Resources>