2012-08-14 54 views
5

我有一個has_many的遊戲模型:texts。問題是,我必須根據它們屬於哪個遊戲對文本進行不同的排序(是的,很醜,但它是傳統數據)。我創建了一個Text.in_game_order_query(game)方法,它返回適當的順序。參考has_many中的實例(Rails)

我最喜歡的解決方案應該是在Text模型中放置一個默認範圍,但這需要知道他們是哪個遊戲的一部分。我也不想爲每個遊戲的文本創建單獨的類 - 有很多遊戲,更多的遊戲,所有新的遊戲都將使用相同的順序。所以,我有另外的想法:在訂貨的has_many文本,當我知道他們的一部分,該遊戲:

has_many :texts, :order => Text.in_game_order_query(self) 

然而,自我是這裏的班級,這樣是行不通的。

除了每次打電話@game.texts.in_game_order(@game)以外真的沒有其他解決方案嗎?

回答

-1

我認爲,如果你想運行時信息處理,你應該得到這跟做:

has_many :texts, :order => proc{ {Text.in_game_order_query(self)} } 
+0

雙曲花括號給了我一個語法錯誤,並且只有一組{}圍繞它表示「無法訪問proc」。 – Sprachprofi 2012-08-14 10:27:22

+0

抱歉錯字。只有一套大括號。但我不確定,如果這適用於:訂單。我用它:條件。如果proc不起作用,請嘗試使用lambda或Proc.new – 2012-08-14 11:37:11

0

這裏有一個方法,你可以做到這一點,

has_many :texts, :order => lambda { Text.in_game_order_query(self) } 

這是另一種方式,我通常不會推薦(但會工作),

has_many :texts do 
    def game_order(game) 
    find(:all, :order => Text.in_game_order_query(game)) 
    end 
end 

你可以打電話給他們,

game.texts.game_order(game) 
+0

「Can not visit proc」:-( – Sprachprofi 2012-08-14 10:27:45

+0

嘗試使用'has_many:texts,lambda {{:order => Text.in_game_order_query(self)}}' – PradeepKumar 2012-08-14 10:45:36

+0

「錯誤參數的數量(1代表0)「 - 我開始認爲這是不可能的:-(我也嘗試將這個函數移動到遊戲模型,以便我可以做self.in_game_order_query而不必傳遞參數,但沒有運氣。 – Sprachprofi 2012-08-14 12:14:33

1

會的Association extension是一種可能性?

看來,你可以做這項工作:

module Legacy 
    def legacy_game_order 
    order(proxy_association.owner.custom_texts_order) 
    end 
end 

class Game << ActiveRecord::Base 
    includes Legacy 
    has_many :texts, :extend => Legacy 

    def custom_texts_order 
    # your custom query logic goes here 
    end 
end 

這種方式,給定一個遊戲實例,你應該能夠無需自通過訪問實例的自定義查詢:

g = Game.find(123) 
g.texts.legacy_game_order 
3

繼續使用PradeepKumar的想法,我發現下面的解決方案工作

假設一個類Block其中有一個屬性block_type,和co ntainer類(比如頁),你可以有這樣的事情:

class Page 
    ... 

    has_many :blocks do 
    def ordered_by_type 
     # self is the array of blocks 
     self.sort_by(&:block_type) 
    end 
    end 

    ... 
end 

然後當你調用

page.blocks.ordered_by_type 

你得到你想要的東西 - 由proc定義。 很顯然,Proc可能更復雜,並且在SQL調用中不工作,但是在編譯結果集之後。

UPDATE:
我重新閱讀這篇文章和一堆時間後,我的答案,我不知道你是否可以做作爲你基本上表明自己在後的另一種方法是簡單的事情。

如果添加什麼Game的方法稱爲ordered_texts

def ordered_texts 
    texts.in_game_order(self) 
    end 

這是否解決了問題?或者這種方法是否需要與其他Game關係方法鏈接?

3

最近我有一個非常類似的問題,我確信在Rails中這是不可能的,但是我學到了一些非常有趣的東西。

您可以聲明一個作用域的參數,然後不傳入它,它會默認傳遞父對象!

所以,你可以這樣做:

class Game < ActiveRecord 
    has_many :texts, -> (game) { Text.in_game_order_query(game) } 

相信不相信,你沒有在遊戲中通過。 Rails會爲你神奇地做它。你可以簡單地做:

game.texts 

雖然有一個警告。如果您啓用了預加載,這在Rails中目前無法使用。如果這樣做,您可能會收到以下警告:

DEPRECATION警告:關聯作用域的「文本」是實例相關的(作用域塊帶有參數)。預加載在個體實例創建之前發生。這意味着沒有實例被傳遞給關聯作用域。這很可能會導致錯誤或不正確的行爲。加入,預加載和急切加載這些關聯將被棄用,並且將來會被刪除。