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