mehrere Verknüpfungen unter Verwendung active in Schienen
-
03-07-2019 - |
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?
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"} )