为什么uniq在另一个对象中使用时会返回一个不合逻辑的答案?

时间:2015-01-12 04:29:11

标签: ruby-on-rails ruby rspec

感谢您的时间。我的RSpec规范中有一个有趣的逻辑错误。下面我提供了两个例子,第一个例子总是失败,而第二个传递。

例如:下面的代码将创建一个失败的规范,期望3但是返回1

it "must not have the same question twice" do
  exam = Exam.new
  q1 = Question.new(question: "What color is the sky?")
  q2 = Question.new(question: "What color is the sky?")
  q3 = Question.new(question: "What sound does a dog make?")
  q4 = Question.new(question: "What sound does a dog make?")
  q5 = Question.new(question: "hello world?")
  exam.questions.push(q1,q2,q3,q4,q5)
  expect(exam.questions.uniq.size).to eql(3)
end

然而,当我使用下面的代码时,用常规数组替换Exam对象,它按预期工作并传递规范。

it "must not have the same question twice" do
  exam = []
  q1 = Question.new(question: "What color is the sky?")
  q2 = Question.new(question: "What color is the sky?")
  q3 = Question.new(question: "What sound does a dog make?")
  q4 = Question.new(question: "What sound does a dog make?")
  q5 = Question.new(question: "hello world?")
  exam.push(q1,q2,q3,q4,q5)
  expect(exam.uniq.size).to eql(3)
end

以下是我的问题对象

中的overrode方法示例
def ==(other)
  question == other.question
end

def eql?(other)
  other.is_a?(self.class) && question.eql?(other.question)
end

def hash
  question.hash
end

1 个答案:

答案 0 :(得分:0)

exam.questions.uniq正在删除ActiveRecord :: Associations :: CollectionProxy的重复项。

exam.uniq正在删除数组的重复项。

如果查看ActiveRecord source,您可以看到记录ID用于确定唯一性而不是相等。

  def distinct
    seen = {}
    load_target.find_all do |record|
      seen[record.id] = true unless seen.key?(record.id)
    end
  end
  alias uniq distinct