Проверка уникальности Ruby on Rails ActiveRecord "has_many: through" - PullRequest
11 голосов
/ 26 февраля 2011

В настоящее время я вставляю новое отношение, каждый раз проверяя, не существует ли оно:

unless Relationship.exists?(:entry_id => entry.id, :tag_id => tag.id)

Как я могу реализовать такую ​​проверку в модели отношений, чтобы она не позволяла иметь более одной связи между одной и той же записью и тегом?

Ответы [ 2 ]

22 голосов
/ 27 февраля 2011
class Relationship < ActiveRecord::Base
  belongs_to :entry
  belongs_to :tag
  validates :tag_id, :uniqueness => { :scope => :entry_id }
end
8 голосов
/ 27 февраля 2011

Предполагая, что ваши модели выглядят примерно так:

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

Вы можете добавить уникальную проверку к вашей Relationship модели соединения:

validates_uniqueness_of :tag_id, :scope => :entry_id

validates_uniqueness_ofМетод гарантирует, что Связь не существует, а опция :scope будет сопоставлять соответствие с данным столбцом.SQL, сгенерированный rails посредством этой проверки, будет выглядеть следующим образом:

SELECT `relationships`.id
FROM `relationships`
WHERE (`relationships`.`tag_id` = <tag id> AND `relationships`.`entry_id` = <entry id>)
LIMIT 1

(который вы заметите, по сути, тот же SQL, сгенерированный вашим явным использованием Relationship.exists?(:entry_id => entry.id, :tag_id => tag.id)), и если запись найдена,проверка не удастся.

Также, как и в любом случае, когда вы хотите проверить уникальность, убедитесь, что у вас есть уникальный ключ на tag_id, entry_id в вашей таблице relationships.См. эту статью и «Параллельность и целостность» страницы API, на которую я ссылался выше, для получения дополнительной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...