多个has_many通过关系

问题描述:

我正在建立一个协作写作平台。用户可以拥有任何项目可以在任何集合中并且属于任何用户的项目集合。这导致了一些问题,但。多个has_many通过关系

这是我的模型关系:

class Association < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :set 
    belongs_to :item 
end 

class Set < ActiveRecord::Base 
    has_many :associations 
    has_many :users, through: :associations 
    has_many :items, through: :associations 
end 

class Item < ActiveRecord::Base 
    has_many :associations 
    has_many :users, through: :associations 
    has_many :sets, through: :associations 
end 

我想不通的“导轨方式”正确处理此。

问题1:

创建新项时,只有该组/项目相关联地被存储,而不是用户:

class ItemsController < ApplicationController 
    def create 
    @set = current_user.sets.find(params[:set_id]) 
    @set.where(title: params[:item][:title]).first_or_create! 
    end 
end 

* UPDATE *

要解决问题1,最好的办法是做到以下几点:

@set = current_user.sets.find(params[:set_id]) 
@item = Item.where(name: params[:item][:title]).first_or_create! 
Association.where(item_id: @item.id, set_id: @set.id, user_id: current_user.id).first_or_create! 

虽然感觉非常错误!

问题2:

假设的关联表是从问题1正确填充,以下控制器将返回设定,但无视用户所有权拥有的所有物品:

class SetsController < ApplicationController 
    def index 
    @sets = current_user.sets.includes(:items) 
    end 
end 

* UPDATE *

仍然没有运气找到答案。 要解释这个问题好一点:

下面将只返回属于当前用户

@sets = current_user.sets.all 

但是套,下面将只返回该用户的组,但将包括所有物品的即使它们不属于当前用户也是如此。换句话说,用户范围被丢弃。

@sets = current_user.sets.includes(:items) 

我一直在试图解决这一切的一天,似乎无法找到一个领先

+0

将它分成1:Many's ...创建集合的实例。 –

+0

对不起,我没有关注。 – Joshua

你的第一个问题就是确保您的实例变量是一样的。一个是大写字母。应该看起来像这样:

class ItemsController < ApplicationController 
    def create 
    @set = current_user.sets.find(params[:set_id]) 
    @set.where(title: params[:item][:title]).first_or_create! 
    end 
end  
+0

这里只是一个错字。更新 – Joshua

这是你的意思吗? 用户可以有许多项目。 用户可以有多个组。

一个项目可以属于多个用户。 一个项目可以属于多个集合。

如果是这样,您需要多个连接模型。

Class UserItemAssociation < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :item 
end 

Class SetItemAssociation < ActiveRecord::Base 
    belongs_to :set 
    belongs_to :item 
end 

Class Item < ActiveRecord::Base 
    has_many :user_item_associations 
    has_many :users, through: :user_item_associations 

    has_many :set_item_associations 
    has_many :sets, through :set_item_associations 
end 

Class Set < ActiveRecord::Base 
    belongs_to :user 
end 

在控制器:

@set = current_user.sets.find_or_create_by(params[:set_id]) 
@item = @set.items.where(title: params[:item][:title]).first_or_create! 
current_user.items << @item 

然而,这里是看它的方式不同。

在用户模型中添加此方法。

def items 
    self.sets.collect{|set| set.items}.flatten 
    end 

这样,您只需要Association模型即可通过套件加入用户,但您现在仍可以访问user.items。

+0

对,这是我想要解决的情况。查询真正与这个结构堆叠起来。没有一种方法可以让单个关联表跟踪所有关系吗?在轨道外部很容易做到。 – Joshua

+0

即使如此,对于每个关系都有不同的关联表,问题是相同的:当您选择当前用户的所有集合并包含项目时,集合的所有项目将返回而不是作用域为当前用户。 – Joshua

+0

请参阅上面的修改。我从来没有见过任何连接三个不同类的连接表,但绝不会说永远不会。 – styliii