【问题标题】:Optional many to many relationship in rails?轨道中的可选多对多关系?
【发布时间】:2016-11-30 12:34:35
【问题描述】:

有没有办法在 Rails 中产生可选的多对多关系?

我有一个 Client 模型和一个 ClientManager 模型 - 我希望 Client 有 0、1 或多个 client_managers。但我也希望 Clientmanger 能够拥有 0、1 或更多 clients。这可能吗?如何?

使用导轨 5。

为了清晰/目的而更新:我想要客户端管理器,能够管理多个客户端,甚至没有。并且客户端能够由 0、1 或多个客户端管理器管理

【问题讨论】:

  • 为什么不能只使用has_many :client_managers
  • 不清楚您要达到的目标。请包括您当前的模型。默认情况下,has_many 关系可以有零个关联对象。
  • @AlexKojin 如果我只使用 has_many :client_managers,客户经理怎么可能有多个客户需要照顾?
  • @raj 据我了解,has_many 关系可以有零个关联对象。通过输入 belongs_to :user, optional: true 见:github.com/thoughtbot/shoulda-matchers/issues/870 - 但也许我错过了什么
  • 执行此操作时不会有任何空值。 Relation 模型将具有 client_id 列和 manager_id 列。通过在此处输入值建立关系。顺便说一句,这是铁轨方式。

标签: ruby-on-rails ruby-on-rails-5


【解决方案1】:

您也可以使用has_and_belongs_to_many 关联。

你的模型是

class Client < ActiveRecord::Base
  has_and_belongs_to_many :managers
end

class Manager< ActiveRecord::Base
  has_and_belongs_to_many :clients
end

【讨论】:

    【解决方案2】:

    如果是 NxN 关系,您应该创建另一个同时属于 Client 和 ClientManager 的模型。让我们称之为管理,例如:

    rails g model Management client:references client_manager:references 
    

    这会产生类似这样的东西:

    class Management < ActiveRecord::Base
      belongs_to :client
      belongs_to :client_managers
    end
    

    然后,在您的客户端模型上:

      has_many :managements
      has_many :client_managers :through => :managements
    

    在您的 ClientManager 上:

      has_many :managements
      has_many :clients :through => :managements
    

    希望这可以帮助您弄清楚。祝你好运!

    【讨论】:

    • 谢谢!如果客户没有经理,这样的多对多关系不会失败吗?
    • 不!如果您尝试访问一些 client.client_managers,如果没有,它将返回 nil。此外,@geoandri 的答案是一个很好的方法,也可能有效。我不熟悉 rsrs,但这个链接给出了一个很好的例子:coderwall.com/p/i4c8mg/…
    • 想我现在明白了。它甚至不会在中介/连接表中创建一行,因为如果它没有客户端管理器,则不需要关系 - 因此它不会抛出错误 - 没有什么需要处理的说话。将此标记为答案,因为从其他帖子看来,这是进行多对多的最常见方式 - 并允许中间表中的其他行
    • 谢谢!无论如何,其他帖子为什么你不应该使用 HABTM 关系,就像在另一个答案中一样:blog.flatironschool.com/…。祝你好运!
    【解决方案3】:

    这是一个简单的多对多关系,has_many through 关系在ClientClientManager 数据模型之间。为此,您需要在数据库中设置 3 个表 clientsclient_managersprojects

    # models/client.rb
    class Client < ApplicationRecord
      has_many :projects
      has_many :client_managers, through: :projects
    end
    
    # models/project.rb
    # projects table schema should have- client_id:integer client_manager_id:integer
    class Project < ApplicationRecord
      belongs_to :client
      belongs_to :client_manager
    end    
    
    # models/client_manager.rb
    class ClientManager < ApplicationRecord
      has_many :projects
      has_many :clients, through: :projects
    end
    

    访问

    Client.last.client_managers 给出 0、1 或多个与 Client.last 关联的 client_managers

    ClientManager.last.clients 提供 0、1 或多个与 ClientManager.last 关联的客户端

    more info here

    【讨论】:

    • 感谢您的回答和详细的代码示例。现在一切都说得通了!
    猜你喜欢
    • 2013-04-08
    • 2022-11-26
    • 2013-06-10
    • 2013-11-19
    • 2013-01-20
    • 1970-01-01
    • 2016-09-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多