Ruby on rails 如何创建;“双面”;Rails中的多对多关系?
假设我们有一个摄影网站。任何作者都可以订阅以接收来自任何其他作者的更新。显然,如果作者A订阅了作者B,这并不意味着B订阅了A。所以我们构建模型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
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
类作者:订阅,:源=>:订阅
结束
类订阅“作者”;外部密钥=>“已订阅”
结束
这样我们就可以使用
某个作者。由某个作者订阅,而且让某个作者订阅?如果有,那是什么
注:显而易见的解决办法是
更改数据库设计,添加名为“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 -%>