2011-02-26 15 views

Respuesta

21
class Relationship < ActiveRecord::Base 
    belongs_to :entry 
    belongs_to :tag 
    validates :tag_id, :uniqueness => { :scope => :entry_id } 
end 
7

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.

+0

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

+1

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. –

+0

(se suponía que era * a * su DBMS) –

Cuestiones relacionadas