2011-09-13 6 views
4

私はDBとしてMongoDBを使ってイベントプラットフォームを作成しようとしています。 EventsUsersの多対多の関係が必要です。つまり、関係にプロパティがあることが必要です(具体的にはUsersを確認または確認できません)。Event私はこれがRDBMSには理想的だと認識していますが、私はMongoDBを使用していますので、他の場所で利用していて、引き続き使用したいと考えています。has_many:throughとMongoidをシミュレート

EventにはGuestsを埋め込み、Usersに属しています。このようにして、どのユーザーがイベントに迅速に出席しているのか、そして1つのクエリーしかないのかを知ることができます。しかし、私もEventsUserがすぐに出席しているのを見たいので、それぞれUserEventの配列を持たせたいと思います。

ここにコードの要約を示します。理想的な使用パターンで

# user of the application 
class User 
    has_many :events 
end 

# event that users can choose to attend 
class Event 
    embeds_many :guests 
    has_many :users, :through => :guests  # Won't work 
end 

# guests for an event 
class Guest 
    field :confirmed?, type: Boolean 

    embedded_in :event 
    belongs_to :user 
end 


# Ideal use pattern 
u = User.create 
e = Event.create 
e.guests.create(:user => u, :confirmed => true) 

euuを参照してGuesteへの参照を有しています。

私はhas_many :through行が動作しないことを知っています。どのように同様の機能を得るための任意の提案?私はGuestafter_createコールバックを使用してEventへの参照をUserに追加することを考えていましたが、それはかなりハッキリです。

多分私は間違った道を下った。提案?ありがとう。

答えて

3

イベントIDをユーザーのアレイに格納するだけで済みます。

何らかの理由でイベントが変更されたり、イベントからユーザーが削除されたりすると、アレイを管理する必要があります。しかし、それはトレードオフです。

これで、単一のdb呼び出しでUser.eventsを見つけることができます。

アソシエイションを管理するには、observersを参照してください。

+0

私はあなたの答えを見ました。私は自分の問題を解決する方法を投稿しましたが、オブザーバーを使用することはよりきれいでした。ありがとう! – cbrauchli

+0

ねえ、nodrog、リンクが壊れています。 –

2

モデルでコールバックを使用して終了しました。それはそれがどのように見えるかです。

編集:私はノドッグの答えを見ました。ええ、オブザーバーを使うことはおそらくもっとうまくいきませんでした。ありがとう!

# user of the application 
class User 
    has_and_belongs_to_many :events, inverse_of: nil, dependent: :nullify 
end 

# event that users can choose to attend 
class Event 
    embeds_many :guests 
    index 'guests.user_id', unique: true 
    before_destroy :cleanup_guest_references 

    def cleanup_guest_references 
    self.guests.each do |guest| 
     guest.destroy 
    end 
    end 
end 

# guests for an event 
class Guest 
    field :confirmed?, type: Boolean 

    embedded_in :event, :inverse_of => :guests 
    belongs_to :user 

    after_create :add_event_for_user 
    before_destroy :remove_event_for_user 

    private 
    def add_event_for_user 
     self.user.events.push(self.event) 
    end 
    def remove_event_for_user 
     self.user.events.delete self.event 
     self.user.save 
    end 
end 
+0

誰かがこのようなことをする最善の方法を言うことができますか? –

+0

コールバックが意味をなさないと思います。観察者に非常に似ています。 – kgpdeveloper