2015-09-04 24 views
3

所以,我有以下型號:一種類型的所有多態模型?

class Favorite < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :favoritable, polymorphic: true 
    # Table has a favoritable_id and favoritable_type 
end 

class Book < ActiveRecord::Base 
    has_many :favorites, as: :favoritable 
end 

class Magazine < ActiveBoard::Base 
    has_many :favorites, as: :favoritable 
end 

class User < ActiveRecord::Base 
    has_many :favorites 
end 

當我撥打電話:

user = User.find(1) 
user.favorites 

它帶回所有收藏的書籍和雜誌如預期(基本上是什麼樣子的數據庫與favoritable_id和favoritable_type列/屬性)。當我把這個:

user = User.find(1) 
user.favorites.books 

我得到一個錯誤,指出:

NoMethodError: undefined method 'books' ... 

但是,調用:

user = User.find(1) 
user.favorites.first.favoritable 

這工作得很好。

我不是很懂得如何在這種設置中獲得所有最喜歡的書籍模型?我是我做錯了嗎?

再次感謝。

回答

4

做到這一點的方法:

user.favorites.map {|f| f.favoritable} 

或者,只獲取喜愛的書籍,這樣做:

user.favorites.select { |f| f.favoritable_type == 'book' }.map { |f| f.favoritable } 
+0

好吧,這工作,但返回最喜歡的模型(所有雜誌和書籍)。我怎樣才能得到這些書? – Sean

+0

嘗試更新的答案。 –

+0

好吧,這個作品可以返回所有最喜愛的模型(所有雜誌和書籍)。我怎樣才能得到這些書? – Sean

1

您可以使用代碼UserBook S和Magazine S之間方便地定義關係如下所示:

class User < ActiveRecord::Base 
    has_many :favorites 
    has_many :favorite_books, through: :favorites, source: :favoritable, source_type: 'Book' 
    has_many :favorite_magazines, through: :favorites, source: :favoritable, source_type: 'Magazine' 
end 

現在你可以ea甲硅烷查詢用戶的書籍和雜誌:

user.favorite_books 
user.favorite_magazines 

圖書查詢產生的SQL語句:

SELECT "books".* FROM "books" 
INNER JOIN "favorites" ON "books"."id" = "favorites"."favoritable_id" 
WHERE "favorites"."user_id" = ? AND 
     "favorites"."favoritable_type" = ? 
     [["user_id", 1], ["favoritable_type", "Book"]] 

正如你所看到的,所有在選擇圖書的作業在數據庫中完成。哪個更有效率,然後將完整收藏夾列表提交給客戶端並在那裏進行過濾。

這種方法的另一個優點是它的尺度很好。舉例來說,如果你想知道哪些儒勒·凡爾納的書是由給定用戶收藏,這是很自然的查詢:

user.favorite_books.where('books.author = ?', 'Jules Verne') 
+0

@KMRakibulIslam給予'只是'答覆是不是應該這樣做的方式。我認爲我們都應該爭取更好,甚至更好的答案。如果你能告訴我一個更好的解決問題的方法,我會很樂意向你學習。 – dimakura

+0

@dimakura我真的很喜歡你的解決方案。但是,如果我仍然希望它看起來如何,我該如何做到這一點? users.favorites.books?或users.favorites.magazines?這甚至有可能嗎?或另一種解決方案... users.favorite_books?我是Rails的新手,所以請原諒我這個東西...... – Sean

+0

@Sean,users.favorites.books是不可能的。但是user.favorite_books是可以實現的。我已經更新了我的答案(對於雜誌也是)。 – dimakura