2014-02-27 40 views
0

不同我有這個類的Rails範圍工作在規範和控制檯

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")} 

此範圍將工作這兩個地方。

但是,爲什麼示波器和控制檯中的示波器的行爲不同?

+0

對不起,只是一個錯字從不使用lastfirstall。 –

+0

難道你有可能解釋這個錯誤的其他拼寫錯誤嗎?無論如何,控制檯顯示正確的行爲。我會在你的規範中做一個'放入Invoice.last_with_number(公司)'來看看你得到了什麼樣的對象以及爲什麼'number'方法存在。如果它不是'Relation',那麼我會仔細檢查你的範圍定義。 –

+0

隔離一點:當我在'範圍末尾運行'.last'的規格時,它會通過。如果我刪除最後一個並運行規範,我會爲#獲取'undefined method'number'。這裏的問題是一個範圍應該返回一個ActiveRecord :: Relation。但是,當我運行規範時不會。爲什麼? –

回答

0

我發現它做了什麼。當所有記錄都有number = nil時,它會發生。如果將最後一個放在作用域的末尾,它將返回一個包含所有記錄的ActiveRecord :: Relation。我做了這個repo說明

This rails issue gets a good explanation

爲了避免混淆範圍