【问题标题】:Creating a simple many-to-many self-join association in Rails在 Rails 中创建一个简单的多对多自连接关联
【发布时间】:2014-11-27 22:35:12
【问题描述】:

我正在尝试为我的 Artist 模型创建一个简单的多对多关联。我已经尝试按照示例here 进行操作,但由于某种原因,它只是没有针对我的特定项目进行翻译。我基本上只是希望用户属于组并在我的显示视图中反映他们的成员身份。

<!-- Shows the list of groups an artist belongs to -->

<% if @artist.groups.any? %>
  <%= @artist.groups.each do |group| %>
    <%= group.name %>
  <% end %>
<% end %>

<!-- Shows the members of the groups -->

<% if @artist.members.any? %>
    <p>
      <b>Members:</b>
      <% @artist.members.each do |member| %>
        <%= member.name %>
      <% end %>
    </p>
<% end %>

我目前有一个带有 has_one 关联的用户模型设置并且效果很好。现在我只需要将它变成一个多对多关联就可以调用@artist.groups。与@artist.group。现在是否需要连接表才能使其正常工作?

class Artist < ActiveRecord::Base
  attr_accessor :group_id      

  has_many :members, class_name: 'Artist', foreign_key: 'group_id'
  belongs_to :group, class_name: 'Artist', foreign_key: 'group_id'
end

【问题讨论】:

  • 你有一个叫Group的类吗?
  • 不,我使用User 类来代表组。
  • 我不知道你的应用程序的细节,但这对我来说并没有真正的概念意义。一个对象如何同时代表一个用户和一组用户?
  • 顺便说一下,我认为您不需要为belongs_to :group 包含foreign_key: 'group_id'belongs_to 关联将自动查找外键 name_of_association_id,如果您使用的不是默认值,您只需明确指定外键。
  • 让我改写我的代码。我从艺术家模型(音乐)和团体模型开始。随着我进一步进行开发,我发现两个模型的代码完全相同。我认为使用自联接会更有意义。

标签: ruby-on-rails ruby associations self-join


【解决方案1】:

您肯定需要一个用于多对多关联的连接表。

试试这样的(这是从记忆中,所以可能需要一些调整):

class Membership
  # attributes "artist_id" and "group_id"
  belongs_to :member, class_name: "Artist"
  belongs_to :group, class_name: "Artist"
end

class Artist
  # no foreign keys required
  has_many :group_memberships, class_name: "Membership", foreign_key: :group_id
  has_many :members, through: :group_memberships

  has_many :memberships, foreign_key: :member_id
  has_many :groups, through: :memberships
end

那么你的观点可以和问题中的一样。

您可能还想为 memberships 表添加唯一索引:

add_index :memberships, :member_id
add_index :memberships, :group_id
add_index :memberships, [:member_id, :group_id], unique: true

...在您的Artist 模型中使用适当的validates_uniqueness_of 验证。

【讨论】:

  • 我刚刚编辑了这个;我最初的答案不太奏效(“组”和“成员”的命名方式错误。)现在再试一次。
  • 好的,所以设法将这些属性添加到连接表中。我遇到的唯一问题是视图中第一个条件中的错误:SQLite3::SQLException: no such column: memberships.member: SELECT 1 AS one FROM "artists" INNER JOIN "memberships" ON "artists"."id" = "memberships"."group_id" WHERE "memberships"."member" = ? LIMIT 1
  • 糟糕,是的,这是一个错字。 foreign_key: :member 应该是 foreign_key: :member_id。我将编辑我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多