简体   繁体   English

多个has_many通过关系

[英]multiple has_many through relationships

I'm setting up a collaborative writing platform. 我正在建立一个协作式写作平台。 A user can have sets of items where any item can be in any set and belong to any user. 用户可以具有项目集,其中任何项目可以在任何集合中并且属于任何用户。 This leads to a few problems though. 这导致了一些问题。

These are my model relationships: 这些是我的模特关系:

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

I can't figure out the "rails way" of handling this correctly. 我无法弄清楚正确处理这个问题的“轨道方式”。

Problem 1: 问题1:

When creating a new item, only the set/item association is stored and not the user: 创建新项目时,仅存储集/项关联,而不是用户:

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 * * 更新 *

To fix problem 1, the best I could figure out was to do the following: 要解决问题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!

Feels very wrong though! 虽然感觉很不对劲!

Problem 2: 问题2:

Assuming the associations table is populated correctly from problem 1, the following controller will return all items owned by the set but disregard user ownership: 假设从问题1正确填充了关联表,以下控制器将返回该集所拥有的所有项,但忽略用户所有权:

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

* UPDATE * * 更新 *

Still no luck finding an answer on this. 仍然没有运气找到答案。 To explain the problem a bit better: 要更好地解释问题:

The following will return only sets that belong to the current user 以下内容仅返回属于当前用户的集合

@sets = current_user.sets.all

However, the following will return only the user's sets but will include ALL of the items for the sets even if they don't belong to the current user. 但是,以下内容仅返回用户的集合,但将包括集合的所有项目,即使它们不属于当前用户。 In other words, the user scope is dropped. 换句话说,用户范围被删除。

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

I've been trying to solve this all day and can't seem to find a lead 我一直试图解决这个问题,似乎无法找到领先优势

Your first problem is making sure your instance variable is the same. 您的第一个问题是确保您的实例变量是相同的。 One is capitalized. 一个是资本化的。 Should look like this: 应该是这样的:

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

Is this what you mean? 你是这个意思吗? A user can have many items. 用户可以拥有许多项目。 A user can have many sets. 用户可以拥有多个集合。

An item can belong to multiple users. 一个项目可以属于多个用户。 An item can belong to multiple sets. 一个项目可以属于多个集合。

If that's the case, you need more than one join model. 如果是这种情况,则需要多个连接模型。

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

In the controller: 在控制器中:

@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

However, here's a different way of looking at it. 但是,这是一种不同的方式来看待它。

In the user model, add this method. 在用户模型中,添加此方法。

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

This way, you only need the Association model to join the users with sets, but you can still access the user.items now. 这样,您只需要Association模型即可将用户加入集合,但您现在仍然可以访问user.items。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM