3074
はじめまして、あけましておめでとうございます。

当方、ノンプログラマーの初心者です。

質問があります。 マッチングサイト系のウェブサービスを作ってみようとトライしていますが、
アプリを設計する上でデータベースの考え方としてどのように設計していこうか困っています。

**「ユーザーが登録されていて、興味があればリクエストを送り、マッチング成功すれば、 メッセージのやり取りを行う。」 という処理を行いたいです。**

とりあえずデーターベースは、 ・Userの登録情報のデータ ・投稿（メッセージ）のデータ

のモデルを作成するつもりですが、 マッチングのリクエスト（許可）を取る仕組みをどの様に 考えればいいのか。

とりあえず、私が考えているのは、 ユーザーのデータベースにリクエストがあったことを知らせるカラムを作り、 その情報がお互いのデータベースに入れば、
投稿のデータを使用可能にする。 それだと、複数人のリクエストに対応できなさそうで、マッチングのモデルを作成し、 そこで管理するというイメージで考えています。

どうでしょうか？！ しょうもない質問かもしれませんが、 ご教授願います！m(__)m
CC BY-SA 3.0
2015-01-04T12:53:21.430
3055
2015-01-04T14:33:33.613
5828
question
ruby ruby-on-rails
マッチングサイトのウェブアプリを作ろうと思ってますが、、MODELの考え方(Railsにて）
カラムでやるのは難しいでしょう。

つながりのリクエストをどちらからいつ出したのか、などの扱いもあります。
誰から誰へというリクエストを扱うテーブルと、出されたリクエストを承認した時にレコードを挿入する繋がりのテーブルの2つに分けて扱うのが素直ではないでしょうか。

データ量が数百万件などになってくるとまた別の問題も発生しますが、おそらくそこまでは考慮しないでいいということだと思います。

データベースの設計についての柔らかい読み物をひとつ紹介します。よろしければ参考にどうぞ。

  * <http://www.mahoutsukaino.com/ac/ac2002/datamodel/d01/d01.htm>
CC BY-SA 3.0
2015-01-04T13:47:25.857
3063
2015-01-04T13:47:25.857
452
3055
answer
一案ということで。変数名やメソッド名は適当に付けてるので、(英語として) あまり良くないかも。

  1. Scaffold でモデルなどを作ります。MatchRequest はリクエストしたユーザ (request_user_id), リクエスト対象のユーザ (target_user_id) を持つとします。MatchRequest で相互にリクエストすることで、マッチ完了というルールにします。
```     % rails c

    > rails g scaffold User name:string
    > rails g scaffold MatchRequest request_user_id:integer target_user_id:integer
    
```

  2. とりあえずユーザを作ります。
```     User.create :name => "Nanoha"

    User.create :name => "Fate"
    User.create :name => "Hayate"
    
```

  3. [Association](http://guides.rubyonrails.org/association_basics.html "Active Record Associations") を設定しましょう。MatchRequest を経由して、UserとUserが N:N の関係になります。
```     # app/models/user.rb

    class User < ActiveRecord::Base
      has_many :sent_match_requests, :class_name => MatchRequest, :foreign_key => :request_user_id
      has_many :targeted_match_requests, :class_name => MatchRequest, :foreign_key => :target_user_id
    
```

```     # app/models/match_request.rb

    class MatchRequest < ActiveRecord::Base
      belongs_to :request_userm, :class_name => User
      belongs_to :target_user, :class_name => User
    end
    
```

  4. MatchRequest の情報を入れます。
```     MatchRequest.create :request_user_id => 1, :target_user_id => 2

    MatchRequest.create :request_user_id => 2, :target_user_id => 1
    MatchRequest.create :request_user_id => 3, :target_user_id => 1
    MatchRequest.create :request_user_id => 2, :target_user_id => 3
    MatchRequest.create :request_user_id => 3, :target_user_id => 2
    
```

  5. 確認します。
```     % rails c

    > fate = User.find_by :name => "Fate"
    > fate.sent_match_requests
    # => 略
    > fate.targeted_match_requests
    # => 略
    
```

  6. マッチしたユーザを返す User#matchers を作ります。ActiveRecord を真面目に使えばもう少しスマートに書けそう。
```     # app/models/user.rb

    class User < ActiveRecord::Base
      ...
      def matchers
        requester_ids = targeted_match_requests.pluck(:request_user_id)
        sent_match_requests
          .eager_load(:target_user)
          .select { |r| requester_ids.include? r.target_user_id }
          .map { |r| r.target_user }
      end
    end
    
```

  7. 確認します。マッチしたユーザが表示されました。他のユーザでも試してみてください。
```     > fate.matchers

    => [#<User:0x007fac3075f7b8
      id: 1,
      name: "Nanoha",
      created_at: Sun, 04 Jan 2015 13:07:30 UTC +00:00,
      updated_at: Sun, 04 Jan 2015 13:07:30 UTC +00:00>,
     #<User:0x007fac3076f2f8
      id: 3,
      name: "Hayate",
      created_at: Sun, 04 Jan 2015 13:07:38 UTC +00:00,
      updated_at: Sun, 04 Jan 2015 13:07:38 UTC +00:00>]
    
```
CC BY-SA 3.0
2015-01-04T14:33:33.613
3074
2015-01-04T14:33:33.613
76
3055
answer