5

写真サイトがあるとします。作成者は、他の作成者からの更新を受け取るために購読できます。明らかに、著者 A が著者 B を購読しているからといって、B が A を購読しているとは限りません。したがって、モデルを構築します。

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

このように使用できます

  1. some_author.subscribed_by_author -- some_author が購読している著者のリスト。
  2. どのサブスクリプションでも、両端 (誰が誰にサブスクライブしているか) を知ることができます。

しかし問題は、Rails のみを使用して (プレーン SQL を使用せずに) ある作成者を購読している人のリストを取得する方法です。つまり、「some_author を購読しているのは誰ですか?」

質問: Rails には、関係を両側で機能させる機能、つまり、書くだけでsome_author.subscribed_BY_authorなく持つ機能はありsome_author_subscribed_TO_authorますか? あるとすれば、それは何ですか?

PS明白な解決策は

  1. データベースの設計を変更し、「方向」という名前の列を追加します
  2. サブスクリプションが作成されるたびに 2 つのレコードを作成する
  3. オーサーモデルに追加

    has_many :subscribed_BY_author, :through => :subscriptions, :source => :subscribed_to, :conditions => "direction = 'by'"

    has_many :subscribed_TO_author, :through => :subscriptions, :source => :subscribed_to, :conditions => "direction = 'to'"

しかし、データベースの設計を変更せずに解決策があるのだろうか。

4

2 に答える 2

2

このような単純なものには単純な HABTM を使用しますが、どうしても結合テーブルが必要になります。

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

Author をそれに向けます:

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

メソッド名に本当にコミットしている場合:

  def subscribed_to_author
    subscribers
  end

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

いくつかの接続を作成します (SubscriptionsController を 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

表示名など

@author.subscribers.each do |s|
  s.name
end
# ...or...and...also...
<%= render :partial => @author.subscribers -%>
<%= render :partial => @author.subscriptions -%>
于 2010-02-14T18:01:34.483 に答える
0
# Author model
has_many :subscriptions_to, :class_name => "Subscription", :foreign_key => "subscribed_to"
has_many :subscribed_to_author, :through => :subscriptions_to, :source => :author

私の知る限り、それはうまくいきます!:)

于 2010-02-14T16:32:53.180 に答える