1

我正在尝试创建一个应用程序,其中用户('current_user')对其他两个用户('user1'和'user2')之间的兼容性进行评分。他们可以对兼容性进行正面或负面评价:给两个用户评分“兼容”会创建两个相同类别的资源(一个“positive_connection”和一个“inverse_positive_connection” - 用于双向性),并且给他们评分“不兼容”也会创建两个资源('negative_connection '和'inverse_negative_connection')。所以有positive_connection、negative_connection和user的模型。

每个评级资源都属于创建它的用户,也属于它连接的用户。拥有正面和负面的评级很重要。

这是我的问题:在每个用户(@user)页面上,我想显示单独的列表:

  1. overall_positively_connected_to(@user)(即positive_connections.count > negative_ratings.count)的用户,并且

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


我似乎无法做的是编写一个方法,只提取那些被网络评为“兼容”或“不兼容”的用户

通过阅读 Michael Hartl 的 rails 教程(我对这一切完全陌生),我认为我需要在 User 模型中编写类似这样的内容:

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 查询一无所知。如果需要更多代码,请告诉我。提前致谢!

4

2 回答 2

1

经过几天的努力,我决定解决问题的最佳方法可能是更改模型 - 通过添加额外的“连接”模型并让用户对每个连接进行正面或负面投票,或者通过精简到单个“连接”模型,其中每个连接的正面或负面特征由 +1/-1 标​​记。

在这个问题的答案中可以找到几个替代方案。

于 2011-06-15T07:58:00.097 回答
0

如果我正确理解了这个问题,那么使这一切变得复杂的一件事是目标用户可能在 User1 或 User2 中。也就是说,如果我们毕竟是 ID=4 的用户的所有连接,那么我们可以有 User1 = 4 或 User2 = 4... 对吗?

如果是这样,那么假设您的 positive_connections 和negative_connections 模型/表具有如下字段:

  • ID:主键
  • ReportingUser:建立连接的用户
  • UserA:第一个连接的用户
  • UserB:第二个连接的用户

然后下面的(相当混乱的)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

这是你要找的东西吗?如果是这样,那么我们可以构建活动记录查询。(我感觉我可能误解了这个问题......)

于 2011-06-11T08:47:42.810 回答