Ruby on rails 如何创建;“双面”;Rails中的多对多关系?

Ruby on rails 如何创建;“双面”;Rails中的多对多关系?,ruby-on-rails,database-design,has-many,belongs-to,Ruby On Rails,Database Design,Has Many,Belongs To,假设我们有一个摄影网站。任何作者都可以订阅以接收来自任何其他作者的更新。显然,如果作者A订阅了作者B,这并不意味着B订阅了A。所以我们构建模型 class Author < ActiveRecord::Base has_many :subscriptions has_many :subscribed_by_author, :through => :subscriptions, :source => :subscribed_to end class Subscripti

假设我们有一个摄影网站。任何作者都可以订阅以接收来自任何其他作者的更新。显然,如果作者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
类作者:订阅,:源=>:订阅
结束
类订阅“作者”;外部密钥=>“已订阅”
结束
这样我们就可以使用

  • some_author.subscribed_by_author——某个作者订阅的作者列表
  • 对于任何订阅,我们都可以知道两端(谁订阅了谁)
  • 但问题是如何仅使用rails(而不是使用普通SQL)获得订阅某个作者的用户列表,即获得以下答案:“谁订阅了某个作者?”

    问题:Rails中是否有能力让关系双方都工作,即不仅编写
    某个作者。由某个作者订阅,而且让
    某个作者订阅?如果有,那是什么

    注:显而易见的解决办法是

  • 更改数据库设计,添加名为“direction”的列
  • 每次创建订阅时创建2条记录
  • 添加到作者模型中

    已订阅多个:由作者订阅,:通过=>:订阅,:源=>:订阅,:条件=>“方向='BY'”

    有多个:订阅作者,:通过=>:订阅,:源=>:订阅到,:条件=>“方向='TO'”

  • 但我想知道是否有一种不改变数据库设计的解决方案

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

    据我所知,它是有效的!:)

    对于这样简单的事情,我会使用plain HABTM,但无论如何,您都需要一个连接表

    create_table :subscriptions do |t|
      t.column :author_id, :integer
      t.column :subscriber_id, :integer
    end
    
    向作者指出:

    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
    
    创建一些连接(我将SubscriptionController设置为RESTy)

    subscriptioncontroller
    
    不幸的是,它没有。但它给了我正确的方向,下面的代码起作用了#作者模型有很多:订阅到,:class\u name=>“订阅”,:foreign\u key=>“订阅到”有很多人:订阅了作者,:通过=>:订阅,:来源=>:作者,所以我接受这个答案,但你必须先编辑它以使其正确:)谢谢!修好我的问题一直是我最大的荣幸:)谢谢!这很有帮助。现在我找到了两种解决问题的方法。@Sergii,这就是我在回答中所说的,我删除了它,因为Eric的方法更优越。
      def subscribed_to_author
        subscribers
      end
    
      def subscribed_by_author(author)
        self.subscribers.find(:all, :subscriber_id=>author.id)
      end
    
    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 -%>