1

我正在建立一個協作寫作平臺。用戶可以擁有任何項目可以在任何集合中並且屬於任何用戶的項目集合。這導致了一些問題,但。多個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

回答

2

你的第一個問題就是確保您的實例變量是一樣的。一個是大寫字母。應該看起來像這樣:

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

2

這是你的意思嗎? 用戶可以有許多項目。 用戶可以有多個組。

一個項目可以屬於多個用戶。 一個項目可以屬於多個集合。

如果是這樣,您需要多個連接模型。

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