Rails范围在规范和控制台中的工作方式不同

时间:2014-02-27 15:09:01

标签: ruby-on-rails rspec rails-console

我有这个班级

class Invoice < ActiveRecord::Base
    scope :last_with_number, -> (firm) {firm.invoices.where('number IS NOT NULL').order("number ASC").last}
end

当我在控制台中运行Invoice.last_with_number(Firm.first).number时,出现此错误

2.0.0p247 :001 > Invoice.last_with_number(Firm.first).number
  Firm Load (1.5ms)  SELECT "firms".* FROM "firms" ORDER BY "firms"."id" ASC LIMIT 1
  Invoice Load (3.1ms)  SELECT "invoices".* FROM "invoices" WHERE "invoices"."firm_id" = $1 AND (number IS NOT NULL) ORDER BY number DESC LIMIT 1  [["firm_id", 1]]
NoMethodError:   Invoice Load (0.7ms)  SELECT "invoices".* FROM "invoices"
undefined method `number' for #<ActiveRecord::Relation::ActiveRecord_Relation_Invoice:0x00000008793198>

但是这个规范通过

 describe Invoice do
    let(:firm)     {FactoryGirl.create(:firm)}
    let(:invoice1)   {FactoryGirl.create(:invoice, customer:customer, firm:firm , number: 2)}
    let(:invoice2)   {FactoryGirl.create(:invoice, customer:customer, firm:firm , number:3)}

    it 'gets the last numberd invoice for spesific firm' do 
        invoice1
        invoice2
        Invoice.last_with_number(firm).number.should eq 3
    end
 end

我可以通过制作像这样的Invoice类方法来解决这个问题

def self.the_really_last(firm)
   last_with_number(firm).last
end

并从

更改范围
scope :last_with_number, -> (firm) {firm.invoices.where('number IS NOT NULL').order("number ASC").last}

scope :last_with_number, -> (firm) {firm.invoices.where('number IS NOT NULL').order("number ASC")}

这将适用于两个地方。

但是,为什么范围在规范和控制台中表现不同?

1 个答案:

答案 0 :(得分:0)

我发现了它的作用。当所有记录都有number = nil时,就会发生这种情况。如果将last放在作用域的末尾,则返回一个包含所有记录的ActiveRecord :: Relation。我做了repo来说明

This rails issue gets a good explanation

为避免混淆,请勿在范围内使用last firstall