在已存在的集合中添加对象时引发异常

时间:2012-02-06 16:16:06

标签: ruby-on-rails activerecord

我正在使用<<

将对象添加到集合中
current_user.followers<<users

当用户中的用户已存在于关注者集合中时,我想捕获异常。我怎么能这样做?

谢谢。

PS。通过输入“&lt;&lt;”在Google上找到结果真的很难,是否有名称来调用此方法?

3 个答案:

答案 0 :(得分:7)

您可以覆盖关注者关联中的<<方法。另请注意,: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

答案 1 :(得分:2)

您可以使用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

(连接模型表将包含重复项,但它们将被忽略)。

答案 2 :(得分:1)

<<被称为left shift operator,但在收集的上下文中,它用于将对象插入到集合中。

您可以通过用户类的实例方法

进行插入来实现解决方案
class User < ActiveRecord::Base
  def add_follower(follower)
    raise "Duplicate follower" if followers.include?(follower)
    followers << follower
  end
end