我正在尝试创建一个应用,其中用户('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
)和
overall_negatively_connected_to(@user)
的用户(即negative_connections.count > positive_ratings.count
)。
我似乎无法做的是编写一个类方法,只抽出那些被评为“兼容”或“不兼容”的用户
从阅读Michael Hartl的rails教程(我对这一切都是全新的),我想我需要在用户模型中编写类似的内容:
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查询没有任何线索。如果需要更多代码,请告诉我。提前谢谢!
答案 0 :(得分:1)
经过几天的努力,我决定解决问题的最佳方法可能是改变模型 - 通过添加额外的“连接”模型并让用户对每个模型进行正面或负面投票连接,或通过减小到单个“连接”模型,其中每个连接的正面或负面字符用+ 1 / -1标记。
在this question的答案中可以找到几种替代方案。
答案 1 :(得分:0)
如果我正确理解了这个问题,那么使这一切变得复杂的一个原因是目标用户可能位于User1或User2中。也就是说,如果我们在ID = 4的用户的所有连接之后,那么我们可以让User1 = 4或User2 = 4 ......是吗?
如果是这样,那么假设你的positive_connections和negative_connections模型/表包含如下字段:
然后,下面(相当混乱的)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
这是你要找的东西吗?如果是这样,那么我们可以构建活动记录查询。 (我有一种感觉,虽然我可能误解了这个问题......)