2015-09-26 47 views
1

Spree插件添加一個作用域。假設:你如何別名或以其他方式覆蓋範圍並調用原始範圍?

class Product 
    scope :in_sale, -> { where(in_sale: true) } 
end 

請注意,actual scope稍微複雜一些。

現在,我要重寫,在我的裝飾:

Spree::Product.class_eval do 
    scope :in_sale, -> { on_hand.where(in_sale: true) } 
end 

相反的複製原執行.where(in_sale: true),我更願意稱之爲原。

如何重新使用原始範圍,有點類似於您通常爲例程方法調用alias_method_chain :foo, :feature

+2

嗯,這不是簡單的別名做的工作嗎? –

+0

@SergioTulentsev,是的。這只是稍微複雜一些,然後在實例方法上定義一個別名,因爲class-eval的事情。也許你可以用一些代碼來回答這個問題,這樣我們就可以解決這個問題了? – berkes

回答

1

沒有真正瞭解什麼是背後的問題,我建議使用:

product.in_sale.on_hand 

,而不是修補Spree::Product類。

如果您仍然需要這一個方法調用,你可以做這樣的:

Spree::Product.class_eval do 
    # alias an old method 
    class <<self 
    alias_method :old_in_sale, :in_sale 
    end 

    # reusing old method in a new one 
    scope :in_sale, -> { old_in_sale.on_hand } 
end 

破碎

此代碼看似作品:

Spree::Product.class_eval do 
    old_in_sale = in_sale 

    # reusing old method in a new one 
    scope :in_sale, -> { old_in_sale.on_hand } 
end 

由於@berkes在他的評論下面,它只對old_in_sale評估一次,並且這個值將來會被重用。它仍然可能產生正確的結果,但不是保證。

+0

不會'old_in_sale = self.in_sale'觸發實際的proc,而是'old_in_sale'包含Prodcucts列表,而不是指向範圍的指針? – berkes

+0

@berkes你是對的。我已經更新了我的答案。順便說一句,舊的代碼在簡單的情況下依然表現良好。 'old_in_sale'包含每個查詢都重用的'ActveRecord :: Relation'。它會被破壞,如果舊的'in_sale'返回將會與我們在第一次執行時得到的不同。 – dimakura