Frage

Ich baue einen kleinen Mikrobloggingdienst Twitter Stil, in den Benutzer andere Benutzern folgen kann und einen Feed ihrer Nachrichten bekommt

Ich habe die folgenden Modelle:

class Follow < ActiveRecord::Base
  belongs_to :follower, :class_name => "User"
  belongs_to :followee, :class_name => "User"
end

class User < ActiveRecord::Base
  has_many :follows,   :foreign_key => 'follower_id',
                       :class_name => 'Follow'
  has_many :followers, :through => :follows
  has_many :followed,  :foreign_key => 'followee_id',
                       :class_name => 'Follow'
  has_many :followees, :through => :followed
  has_many :messages
end

class Message < ActiveRecord::Base
  belongs_to :user
end

Um einen Feed für den aktuellen Benutzer zu bekommen, möchte ich die folgende SQL-Abfrage ausführen:

SELECT * FROM follows JOIN users JOIN messages WHERE follows.follower_id = current_user.id AND follows.followee_id = users.id AND users.id = messages.user_id;

Was ist der richtige Weg Active dies zu tun?

War es hilfreich?

Lösung

Nicht sicher, was Sie suchen, aber hier ist mein Vorschlag:

Ich gehe davon aus, dass Sie andere Zwecke für die Folgen Klasse haben, sonst sehe ich nicht den Zweck es.

Der „richtige Weg“ (das heißt meine ganz subjektive Art und Weise) zu tun, wäre es tatsächlich so etwas wie dies:

class User < ActiveRecord::Base
  has_and_belongs_to_many :followers, :foreign_key => 'followed_id', 
      :class_name => 'User', :association_foreign_key => 'follower_id', 
      :include => [:messages]
  has_and_belongs_to_many :follows, :foreign_key => 'follower_id', 
      :class_name => 'User', :association_foreign_key => 'followed_id'
  has_many :messages
end

class Message < ActiveRecord::Base
  belongs_to :user
end

Dann erstellen die folgende Tabelle:

create_table :users_users, :id => false do |t|
  t.integer :followed_id
  t.integer :follower_id
end

Und Sie werden eingestellt:

followed = User.find :first
follower = User.find :last

followed.followers << follower

followed.followers.first.messages
followed.followers.first.followers.first.messages # etc...

Aber von dem, was ich es machen, wollen Sie von allen Followern bei gleichzeitig alle Nachrichten zeigen.

Dies sollte möglich sein, zu erreichen Hinzufügen

 has_and_belongs_to_many :followed_messages, :foreign_key => 'follower_id', 
  :class_name => 'Message', :association_foreign_key => 'followed_id'

auf den Benutzer Klasse, aber ich weiß nicht, wie richtig auf diese Weise sein würde. Oder es könnte möglich sein, mit Assoziations Erweiterungen zu erreichen, aber da kann ich wirklich keine Beispiele.

Update: Durch die Veränderung des:. Class_name, wird es mit dem Message.id assoziieren, nicht darüber dachte, so dass es auf diese Weise nicht richtig sein

So ist die einzige „nice“ Option ist durch die User-Klasse gehen, wie im ersten Beispiel. Die einzigen anderen Optionen, die ich sehen kann, ist entweder die Assoziations Erweiterungen (die kann ich Ihnen nicht geben ein Beispiel für) oder vielleicht eine Finder-Anweisung.

 has_many :followed_messages, :class_name => 'Message',
  :finder_sql => 'select * from messages where user_id in(select followed_id from users_users where follower_id = #{id})'

Sie haben wahrscheinlich zu, dass die SQL-Anweisung anpassen, um alles zu arbeiten, aber zumindest sollten Sie das Bild bekommen :)

Andere Tipps

Keijro Arrangement würde besser funktionieren, aber wenn Sie die Follow-Tabelle benötigen, dann können Sie die SQL-Abfrage ausführen Sie wie folgt angegeben:

Follow.all(:joins => { :messages, :users }, :conditions => { "follows.follower_id" => current_user.id, "follows.followee_id" => "users.id", "users.id" => "messages.user_id"} )
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top