Rails RSpec从集合中删除项目

时间:2014-08-28 20:36:11

标签: ruby-on-rails ruby rspec

我在这个问题上打得太久了......

我的情景:

  

我有一个Rails 4应用程序。我只是在为我的Subscription模型制定一个规范。

这是关系:

subscription (has_one subscriber, has_one batch)
  subscriber_id: int
  batch_id: int

subscriber (has_many subscriptions)
  id: int
  email_address: string

subscription_spec.rb

require 'rails_helper'

describe Subscription do
  before :each do
    @subscriber = Subscriber.create(
        :id => 1,
        :email_address => 'some.subscriber@example.com'
    )
    @batch = Batch.create(
        :id => 1,
        :name => 'Test Batch'
    )
  end

  it 'subscribes a user to a report successfully' do
    @subscriber.subscribe_to! @batch.id
    expect(@subscriber.subscribed_to? @batch.id).to eq(true)
  end

  it 'unsubscribes a user from a report successfully' do
    @subscriber.subscriptions.create(:id => 1, :batch_id => @batch.id)
    expect(@subscriber.subscribed_to? @batch.id).to eq(true)

    @subscriber.unsubscribe_from! @batch.id
    expect(@subscriber.subscribed_to? @batch.id).to eq(false)
  end
end

我的最后一个规格是因为这个错误而失败:

Failure/Error: expect(@subscriber.subscribed_to? @batch.id).to eq(false)

   expected: false
        got: true

自第一个规范通过以来,我知道unsubscribe_from!是罪魁祸首,不是 subscribed_to?

订户#subscribed_to?

def subscribed_to?
  subscriptions.each do |subscription|
    return true if subscription.batch.id == batch_id
  end
  return false
end

订户#unsubscribe_from!

def unsubscribe_from!(batch_id)
  p subscriptions
  Subscription.where(:subscriber_id => self.id, :batch_id => batch_id).destroy_all
  p subscriptions
end

为什么这实际上没有删除?

我也试过

subscriptions.each do |subscription|
  subscriptions.delete(subscription) if subscription.batch_id == batch_id
end

错误:"subscriber_id" cannot be NULL,并且无法在前面的任何地方找到,所以我尝试了倒数第二个解决方案。

1 个答案:

答案 0 :(得分:1)

  

自第一个规范通过以来,我知道unsubscribe_from!是罪魁祸首,不是 subscribed_to?

你确定吗?你知道subscribed_to?的一面,即返回true的一面。根据您的测试失败,它似乎实际上返回了很多。如果我们能够看到它的代码,我们可以将其排除在外。

编辑:好的,有几件事要尝试:

使用您所拥有的关联为您做一些工作,不易出错:

def unsubscribe_from!(batch_id)
  subscriptions.where(:batch_id => batch_id).destroy_all
end

def subscribed_to?(batch_id)
  subscriptions.where(:batch_id => batch_id).exists?
end

有时当你搞乱关联时,你可以重新加载对象,以帮助减轻可能发生的任何缓存:

it 'unsubscribes a user from a report successfully' do
  @subscriber.subscriptions.create(:id => 1, :batch_id => @batch.id)
  expect(@subscriber.subscribed_to? @batch.id).to eq(true)

  @subscriber.unsubscribe_from! @batch.id
  expect(@subscriber.reload.subscribed_to? @batch.id).to eq(false)
end