1

ユーザー ('current_user') が他の 2 人のユーザー ('user1' と 'user2') 間の互換性を評価するアプリを作成しようとしています。互換性を肯定的または否定的に評価できます。2 人のユーザーを「互換性がある」と評価すると、同じクラスの 2 つのリソース (双方向性の場合は「positive_connection」と「inverse_positive_connection」) が作成され、それらを「互換性がない」と評価すると、2 つのリソース (「negative_connection」) も作成されます。 ' および 'inverse_negative_connection')。したがって、positive_connection、negative_connection、およびユーザーのモデルがあります。

各評価リソースは、それを作成したユーザーだけでなく、それによって接続されたユーザーにも属しています。肯定的な評価と否定的な評価の両方を持つことが重要です。

これは私の問題です: すべてのユーザー ( @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 に (それぞれ) 否定的および肯定的に接続されているユーザーを見つけるための次の 2 つのクラス メソッドを作成しました。

.
.
.
  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


しかし、それはあまり役に立ちません。私が必要としているのは、 users を取得するメソッドですoverall_positively_connected_to(user)。メソッドには2つの結合が含まれ、次のようになると思います。

  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

私が問題を正しく理解していれば、これをすべて複雑にしている原因の 1 つは、ターゲット ユーザーが User1 または User2 のいずれかにいる可能性があることです。つまり、ID=4 のユーザーのすべての接続が完了した場合、User1 = 4 または User2 = 4 になる可能性があります... そうですか?

もしそうなら、あなたの positive_connections と negative_connections モデル/テーブルに次のようなフィールドがあると仮定します:

  • ID: 主キー
  • ReportingUser: 接続を行っているユーザー
  • UserA: 最初に接続するユーザー
  • UserB: 接続する 2 番目のユーザー

次に、次の (かなり面倒な) 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 を使用してクエリを作成する限り、このページは非常に優れたリソースです。 http://guides.rubyonrails.org/active_record_querying.html

これはあなたが探しているものですか?その場合は、アクティブ レコード クエリの作成に取り組むことができます。(私は問題を誤解しているかもしれないと感じていますが...)

于 2011-06-11T08:47:42.810 に答える