Suponiendo sus modelos tienen el siguiente aspecto:
class Entry < ActiveRecord::Base
has_many :relationships
has_many :tags, :through => :relationships
end
class Tag < ActiveRecord::Base
has_many :relationships
has_many :entries, :through => :relationships
end
class Relationship < ActiveRecord::Base
belongs_to :entry
belongs_to :tag
end
Se podría añadir una validación único a su Relationship
unirse modelo:
validates_uniqueness_of :tag_id, :scope => :entry_id
El método validates_uniqueness_of
se asegurará de que la relación no ya existe, y la opción :scope
concordará con la columna dada. El SQL generado por los carriles a través de esta validación se verá así:
SELECT `relationships`.id
FROM `relationships`
WHERE (`relationships`.`tag_id` = <tag id> AND `relationships`.`entry_id` = <entry id>)
LIMIT 1
(la que usted notará es esencialmente el mismo SQL generado por el uso explícito de Relationship.exists?(:entry_id => entry.id, :tag_id => tag.id)
), y si se encuentra un registro, validación fallará.
Además, como en cualquier caso en el que desee validar la exclusividad, asegúrese de tener una clave única en tag_id, entry_id
en su tabla relationships
. Consulte this article y la "Concurrencia e integridad" de la página de la API que he vinculado anteriormente para obtener más información.
Gracias, pero ¿cómo agrego las claves únicas, que todavía podría tener el mismo tag_id para otras entradas, y muchas etiquetas diferentes para la misma entrada? add_index "relationships", ["tag_id"],: unique => true - Supongo que me impediría usar el mismo mismo tag_id más de una vez. – krn
Debe crear el índice para * both * columnas. En una migración, se vería como 'add_index: relationships, [: tag_id,: entry_id],: unique => true'. Luego, realice su DBMS, una nueva fila solo entra en conflicto si los valores de ambas columnas coinciden con una fila existente. –
(se suponía que era * a * su DBMS) –