ソーシャル ネットワーキング アプリケーションで Rails 3 にフレンドシップ モデルを実装するにはどうすればよいでしょうか? 質問する

ソーシャル ネットワーキング アプリケーションで Rails 3 にフレンドシップ モデルを実装するにはどうすればよいでしょうか? 質問する

私は現在、小さなソーシャルネットワーキングアプリケーションに取り組んでおり、現在、次のようなモデルを作成しようとしています。友情ユーザーこれまでに私が思いついたのは以下のとおりです。

class User < ActiveRecord::Base

  # ...
  has_many :friendships
  has_many :friends, :through => :friendships

end

class Friendship < ActiveRecord::Base
  belongs_to :user
  belongs_to :friend, :class_name => 'User'
end

私の友情モデルにはフィールドがある確認済み友情を保留中または確認済みとして定義するために使用したいブール値として。

特定のユーザーの保留中のリクエストすべてにアクセスするにはどうすればいいでしょうか?Railsの範囲方法?

current_user.friendships.requests # => [Friendship, Friendship, ...]

素晴らしいことだ。

この関連付けを双方向にするにはどうすればよいでしょうか? 友人リクエストが確認されたら、別の友人を追加するだけで、友人関係テーブルは次のようになります。

| user_id | friend_id | confirmed |
-----------------------------------
| 1       | 2         | true      |
| 2       | 1         | true      |

ベストアンサー1

保留中のすべての友情にアクセスするには、関連付けを使用できます。

has_many :pending_friends,
         :through => :friendships,
         :source => :friend,
         :conditions => "confirmed = 0"  # assuming 0 means 'pending'

友情を双方向にするには、ブール値を確認済み文字列を含む列状態次の 3 つの値のいずれかを持つ列: 'pending'、'requested'、'accepted' (オプションで 'rejected')。これにより、誰がフレンドシップ リクエストを行ったかを追跡できます。

友情リクエストが送信されると (たとえば Foo から Bar へ)、2 つの友情レコード (トランザクションにカプセル化) が作成されます。1 つはリクエスト済み、もう 1 つは保留中であり、それぞれ Bar が Foo から友情をリクエストされていること、および Foo が Bar と保留中の友情を持っていることを反映します。

  def self.request(user, friend)
    unless user == friend or Friendship.exists?(user, friend)
      transaction do
        create(:user => user, :friend => friend, :status => 'pending')
        create(:user => friend, :friend => user, :status => 'requested')
      end
    end
  end

友情が承認されると(たとえば、Bar によって)、両方の友情レコードが承認済みに設定されます。

  def self.accept(user, friend)
    transaction do
      accepted_at = Time.now
      accept_one_side(user, friend, accepted_at)
      accept_one_side(friend, user, accepted_at)
    end
  end

  def self.accept_one_side(user, friend, accepted_at)
    request = find_by_user_id_and_friend_id(user, friend)
    request.status = 'accepted'
    request.accepted_at = accepted_at
    request.save!
  end

これはマイケル・ハートルとアウレリウス・プロチャスカのRailspaceの本の第14章で大部分がカバーされています。ソースコードこれはソリューションを改善するのに役立ちます。

おすすめ記事