1

我試圖創建一個應用程序,用戶('current_user')對兩個其他用戶('user1'和'user2')之間的兼容性進行評分。他們可以對兼容性進行正面或負面的評價:對兩個用戶進行「兼容」評級,創建同一類別的兩個資源('positive_connection'和'inverse_positive_connection' - 雙向性),並將它們評爲「不兼容」還會創建兩個資源('negative_connection '和'inverse_negative_connection')。所以有positive_connection,negative_connection和user的模型。雙向自我指涉關聯的類方法問題

每個評級資源都屬於創建它的用戶,但也屬於其所連接的用戶。正面評價和負面評價都很重要。

這是我的問題:對每個用戶(@user)頁我想顯示的單獨列表:是overall_positively_connected_to(@user)(即positive_connections.count > negative_ratings.count

  1. 用戶,

    overall_negatively_connected_to(@user)
  2. 用戶(即negative_connections.count > positive_ratings.count)。


我似乎無法做的是寫一個方法翻出只有誰是這些用戶網評爲「兼容」或「不兼容」

從閱讀邁克爾·哈特爾的軌教程(我完全新的這一切),我想我需要寫像這樣在用戶模式:

class User < ActiveRecord::Base 


def self.that_are_compatible_with 

    User.overall_positively_connected_to(user) 
end 
. 
. 
. 


編輯

絕對沒有在所有SQL查詢的知識開始,我寫了查找用戶這兩個類方法被負,正(分別)連接到@user:

. 
. 
. 
    def self.with_neg_connections_to(user) 
    joins(:negative_connections). 
    where(:negative_connections => {:user_a_id => user}) 
    end 

    def self.with_pos_connections_to(user) 
    joins(:positive_connections). 
    where(:positive_connections => {:user_a_id => user}) 
    end 


但這並沒有太大的幫助。我需要的是一種獲取用戶overall_positively_connected_to(user)的方法。我相信該方法會涉及兩個連接,並且去是這樣的:

def self.overall_positively_connected_to(user) 
    joins(:positive_connections).joins(:negative_connections). 
    where((:negative_connections => {:user_a_id => user}).count > (:positive_connections => {:user_a_id => user}).count) 
    end 


但在這裏,我得到完全被卡住:這顯然是不正確的。我找不到其他例子,像任何地方...

任何幫助什麼這將是偉大的,因爲我不知道什麼時候談到SQL查詢。讓我知道是否需要更多的代碼。提前致謝!

回答

1

經過幾天的努力,我決定解決問題的最好方法可能是改變模型 - 通過增加一個額外的「連接」模型,並讓用戶對每個連接投票正面或負面,或減少到一個單一的「連接」模型,其中每個連接的正面或負面字符標記爲+ 1/-1。

this question的答案中可以找到幾種選擇。

0

如果我正確地理解了這個問題,使這一切變得複雜的事情之一是目標用戶可能在User1或User2中。也就是說,如果我們在ID = 4的用戶的所有連接之後,那麼我們可以讓User1 = 4或User2 = 4 ...是嗎?

如果是這樣,那麼假設你的positive_connections和negative_connections型號/表有這樣的字段:

  • ID:主鍵
  • ReportingUser:用戶建立連接
  • 用戶A:第一個用戶連接
  • 用戶B:第二用戶連接

然後將以下(大鼠她凌亂的)SQL會給你倆每個用戶的正極和負極連接的總結:

set @user = 2; 

SELECT DISTINCT 
    @user TargetUser, 
    u.ID as OtherUser, 
    COALESCE(qryPositive.PositiveConnections, 0) as PositiveConnections, 
    COALESCE(qryNegative.NegativeConnections, 0) as NegativeConnections, 
    case 
     when COALESCE(qryPositive.PositiveConnections, 0) > COALESCE(qryNegative.NegativeConnections, 0) 
     then 'positive' 
     when COALESCE(qryPositive.PositiveConnections, 0) < COALESCE(qryNegative.NegativeConnections, 0) 
     then 'negative' 
     else 'neutral' 
    end as Status 
FROM 
    users u 
LEFT JOIN 
    (
     -- The number of positive connections between the @user and each other user 
     SELECT 
      @user TargetUser, 
      a.OtherUser, 
      COUNT(*) as PositiveConnections 
     FROM 
     (
      -- The positive_connections rows with our @user in it 
      -- and the other user that the connection associates them with 
      select -- pc.ID as pcID, pc.UserA, pc.UserB, 
      case 
       when pc.UserA = @user then pc.UserB 
       else pc.UserA 
      end as OtherUser 
      from positive_connections pc 
      where 
      (
       -- Check both columns 
       (pc.UserA = @user) 
       or 
       (pc.UserB = @user) 
      ) 
     ) a 
     GROUP BY 
      OtherUser 
    ) qryPositive 
    on qryPositive.OtherUser = u.ID 

LEFT JOIN 
    (
     -- The number of negative connections between the @user and each other user 
     SELECT 
      @user TargetUser, 
      b.OtherUser, 
      COUNT(*) as NegativeConnections 
     FROM 
     (
      -- The negative_connections rows with our @user in it 
      -- and the other user that the connection associates them with 
      select -- pc.ID as pcID, pc.UserA, pc.UserB, 
      case 
       when pc.UserA = @user then pc.UserB 
       else pc.UserA 
      end as OtherUser 
      from negative_connections pc 
      where 
      (
       -- Check both columns 
       (pc.UserA = @user) 
       or 
       (pc.UserB = @user) 
      ) 
     ) b 
     GROUP BY 
      OtherUser 
    ) qryNegative 
    on qryNegative.OtherUser = u.ID 

WHERE 
    u.ID <> @user 

這需要在SQL的照顧,如果你喜歡(我可以張貼我使用的樣品數據)。現在在rails中,如你已經開始做的那樣,在你的模型中分離出單獨的類方法肯定是個好主意。

就使用rails構建查詢來說,這個頁面是一個非常好的資源。 http://guides.rubyonrails.org/active_record_querying.html

這是你要找的東西嗎?如果是這樣,那麼我們可以開始構建活動記錄查詢。 (我有一種感覺,儘管我可能誤解了這個問題......)

+0

感謝您的答覆澳大利亞。這並不完全是我的意思,但是這使得數據庫結構過於複雜是我的錯。實際上,我想從數據庫中退出那些對任何給定用戶(@user)有更積極或負面聯繫的用戶。最後我通過改變模型解決了這個問題。我將很快發佈我的解決方案作爲答案。無論如何,再次感謝。 – jonic 2011-06-14 09:01:14