![](/img/trans.png)
[英]Having trouble with RSpec 3.1.0 and has_many through relationship with Ruby-on-Rails 4.1
[英]Ruby-on-Rails: Multiple has_many :through possible?
是否有可能有多個has_many :through
在Rails中相互傳遞的關系? 我收到了這樣的建議,作為我發布的另一個問題的解決方案,但一直無法讓它工作。
好友是通過聯接表的循環關聯 。 目標是為friends_comments
創建一個has_many :through
,這樣我就可以帶一個User
並執行類似user.friends_comments
,以便在一個查詢中獲取他的朋友發表的所有評論。
class User
has_many :friendships
has_many :friends,
:through => :friendships,
:conditions => "status = #{Friendship::FULL}"
has_many :comments
has_many :friends_comments, :through => :friends, :source => :comments
end
class Friendship < ActiveRecord::Base
belongs_to :user
belongs_to :friend, :class_name => "User", :foreign_key => "friend_id"
end
這看起來很棒,而且很有意義,但不適合我。 當我嘗試訪問用戶的friends_comments時,這是我在相關部分中遇到的錯誤:
ERROR: column users.user_id does not exist
: SELECT "comments".* FROM "comments" INNER JOIN "users" ON "comments".user_id = "users".id WHERE (("users".user_id = 1) AND ((status = 2)))
當我輸入有效的user.friends時,這是它執行的查詢:
: SELECT "users".* FROM "users" INNER JOIN "friendships" ON "users".id = "friendships".friend_id WHERE (("friendships".user_id = 1) AND ((status = 2)))
因此,它似乎完全忘記了原始的has_many
通過友誼關系,然后不恰當地嘗試將User類用作連接表。
我做錯了什么,或者這根本不可能?
編輯:
Rails 3.1支持嵌套關聯。 例如:
has_many :tasks
has_many :assigments, :through => :tasks
has_many :users, :through => :assignments
不需要下面給出的解決方案。 有關詳細信息,請參閱此截屏視頻。
原始答案
您正在傳遞has_many :through
關聯作為另一個has_many :through
來源的關聯。 我認為它不會起作用。
has_many :friends,
:through => :friendships,
:conditions => "status = #{Friendship::FULL}"
has_many :friends_comments, :through => :friends, :source => :comments
您有三種方法可以解決此問題。
1)寫一個關聯擴展名
has_many :friends,
:through => :friendships,
:conditions => "status = #{Friendship::FULL}" do
def comments(reload=false)
@comments = nil if reload
@comments ||=Comment.find_all_by_user_id(map(&:id))
end
end
現在您可以獲得以下朋友評論:
user.friends.comments
2)向User
類添加方法。
def friends_comments(reload=false)
@friends_comments = nil if reload
@friends_comments ||=Comment.find_all_by_user_id(self.friend_ids)
end
現在您可以獲得以下朋友評論:
user.friends_comments
3)如果您希望這更有效,那么:
def friends_comments(reload=false)
@friends_comments = nil if reload
@friends_comments ||=Comment.all(
:joins => "JOIN (SELECT friend_id AS user_id
FROM friendships
WHERE user_id = #{self.id}
) AS friends ON comments.user_id = friends.user_id")
end
現在您可以獲得以下朋友評論:
user.friends_comments
所有方法都緩存結果。 如果要重新加載結果,請執行以下操作:
user.friends_comments(true)
user.friends.comments(true)
或者更好的是:
user.friends_comments(:reload)
user.friends.comments(:reload)
有一個插件可以解決您的問題,看看這個博客 。
你安裝插件
script/plugin install git://github.com/ianwhite/nested_has_many_through.git
雖然這在過去不起作用,但它現在在Rails 3.1中運行良好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.