Возбудить исключение при добавлении объекта в коллекцию, которая уже существует - PullRequest
2 голосов
/ 06 февраля 2012

Я добавляю объекты в коллекцию с помощью << </p>

current_user.followers<<users

Я хотел бы поймать исключение, когда пользователь в пользователях уже существует в коллекции подписчиков.Как я могу это сделать?

Спасибо.

PS.В Google очень сложно найти результаты, набрав «<<», есть имя для вызова этого метода? </p>

Ответы [ 3 ]

7 голосов
/ 06 февраля 2012

Вы можете переопределить метод << для ассоциации фолловеров.Также обратите внимание, что :push и :concat также являются псевдонимами для :<<, поэтому вы также должны их переопределить.Это определение, которое вы должны вставить в переопределенный метод связи, чтобы вызвать ошибку, если подписчик уже существует.

class User < ActiveRecord::Base
  has_many :followers do
    def <<(*records)
      result = true
      load_target if @owner.new_record?
      transaction do
        flatten_deeper(records).each do |record|
          raise_on_type_mismatch(record)
          raise 'Record Already Exists' if @owner.send(@reflection.name).exists? record
          add_record_to_target_with_callbacks(record) do |r|
            result &&= insert_record(record) unless @owner.new_record?
          end
        end
      end

      result && self
    end
    alias_method :push, :<<
    alias_method :concat, :<<
  end
end
2 голосов
/ 06 февраля 2012

Вы можете использовать обратный вызов before_add:

has_many :followers,
         :through => :whatever,
         :before_add => Proc.new { |user, follower|
           raise "Duplicate follower" if user.followers.include?(follower)
         }

Если вы просто пытаетесь игнорировать дубликаты, вы можете использовать опцию: uniq:

has_many :followers,
         :through => :whatever,
         :uniq => true

(модель соединениятаблица будет содержать дубликаты, но они будут игнорироваться).

1 голос
/ 06 февраля 2012

<< называется left shift operator, но в контексте коллекции он используется для вставки объекта в коллекцию.

Вы можете достичь решения, сделав вставку с помощью метода экземпляра пользовательского класса.,

class User < ActiveRecord::Base
  def add_follower(follower)
    raise "Duplicate follower" if followers.include?(follower)
    followers << follower
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...