Question

Supposons que nous ayons un site de photographie. Tout auteur peut souscrire aux mises à jour de tout autre auteur. Il est évident que si l'auteur A est abonné à l'auteur B qui ne veut pas dire que B est abonné à A. Nous construisons des modèles

class Author < ActiveRecord::Base
  has_many :subscriptions
  has_many :subscribed_by_author, :through => :subscriptions, :source => :subscribed_to
end

class Subscription < ActiveRecord::Base
  belongs_to :author
  belongs_to :subscribed_to, :class_name => "Author", :foreign_key => "subscribed_to"
end

De cette façon, nous pouvons utiliser

  1. some_author.subscribed_by_author -. La liste des auteurs à qui some_author est abonnée
  2. Pour tout abonnement, nous pouvons connaître les deux extrémités (qui est abonné à qui)

Mais la question est de savoir comment obtenir la liste des personnes abonnées à un auteur utilisant des rails seulement (ne pas utiliser SQL ordinaire) i.e. obtenir la réponse à: « Qui est souscrit some_author »

Question: est-il la capacité de Rails pour obtenir la relation de travail des deux côtés dire non seulement l'écriture some_author.subscribed_BY_author mais ayant some_author_subscribed_TO_author? S'il y a un, alors qu'est-ce?

P.S. solution évidente consiste à

  1. Modifier la conception de base de données, l'ajout d'une colonne "direction"
  2. Créer 2 enregistrements chaque fois qu'un abonnement est créé
  3. Ajouter au modèle auteur

    has_many: subscribed_BY_author,: par =>: abonnements: source =>: subscribed_to,: conditions => "direction = 'par'"

    has_many: subscribed_TO_author,: par =>: abonnements: source =>: subscribed_to,: conditions => "direction = 'à'"

Mais je me demande s'il y a une solution sans changer la conception de base de données.

Était-ce utile?

La solution

# Author model
has_many :subscriptions_to, :class_name => "Subscription", :foreign_key => "subscribed_to"
has_many :subscribed_to_author, :through => :subscriptions_to, :source => :author

Pour autant que je sais - ça marche! :)

Autres conseils

J'utilise HABTM simple pour quelque chose de simple comme ça, mais vous allez avoir besoin d'une table de jointure, peu importe quoi.

create_table :subscriptions do |t|
  t.column :author_id, :integer
  t.column :subscriber_id, :integer
end

Auteur Point à elle:

class Author < ActiveRecord::Base
  has_and_belongs_to_many :subscribers
    :class_name => "Author",
    :join_table => "subscriptions",
    :association_foreign_key => "subscriber_id"

  def subscriptions # "subscribers" is already included above
    self.subscribers.find(:all, :subscriber_id=>author.id) # hopefully not too 
  end                                                      # much SQL
end

Si vous êtes vraiment engagé à vos noms de méthode:

  def subscribed_to_author
    subscribers
  end

  def subscribed_by_author(author)
    self.subscribers.find(:all, :subscriber_id=>author.id)
  end

Créer des connexions (je fais SubscriptionsController être Resty)

SubscriptionsController < ApplicationController
  def create
    @author = Author.find(params[:author_id] # author to be subscribed to
    @user = current_user # user clicking the "subscribe" button

    @author.subscribers << @user # assuming authors should only 
    @author.save                 # be able to subscribe themselves
  end
end

noms d'affichage, ou quoi que

@author.subscribers.each do |s|
  s.name
end
# ...or...and...also...
<%= render :partial => @author.subscribers -%>
<%= render :partial => @author.subscriptions -%>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top