【问题标题】:Has_many, belongs_to with multiple foreign keyshas_many,belongs_to 有多个外键
【发布时间】:2014-05-07 09:46:11
【问题描述】:

我试图通过 has_many,belongs_to 关系将比赛归因于俱乐部。但是,在比赛中,我需要将俱乐部设置为 home_team 或 away_team。为了解决这个问题,我使用了两个foreign_keys。

class Club < ActiveRecord::Base
  has_many :matches
end

class Match < ActiveRecord::Base
  belongs_to :home_team, class_name: 'Club', foreign_key: 'home_team_id'
  belongs_to :away_team, class_name: 'Club', foreign_key: 'away_team_id'
end

这可以使用 home_team_id 和 away_team_id 很好地设置俱乐部。

但是,我无法通过 Club.matches 访问俱乐部的所有比赛。

ERROR:  column matches.club_id does not exist

我怎样才能改变我的关系,这样我才能做到这一点?

【问题讨论】:

  • UsersMessages.from_idMessages.to_id 也有这个问题。我正在尝试has_many :messages, -&gt;(u) {where "from_id = ? or to_id = ?", u.id, u.id}, foreign_key: nil,但没有成功。

标签: ruby-on-rails foreign-keys has-many belongs-to


【解决方案1】:

我对@9​​87654321@ 的回答只适合你!

至于你的代码,这是我的修改

class Club < ActiveRecord::Base
  has_many :matches, ->(club) { unscope(where: :club_id).where("home_team_id = ? OR away_team_id = ?", club.id, club.id) }, class_name: 'Match'
end

class Match < ActiveRecord::Base
  belongs_to :home_team, class_name: 'Club', foreign_key: 'home_team_id'
  belongs_to :away_team, class_name: 'Club', foreign_key: 'away_team_id'
end

有什么问题吗?

【讨论】:

  • unscope 是做什么的?第一个class_name 似乎没有必要。
  • 哇这工作has_many :messages, -&gt;(u) {unscope(where: :user_id).where "from_id = ? or to_id = ?", u.id, u.id} 产生u.messages Message Load (15.6ms) SELECT "messages".* FROM "messages" WHERE (from_id = 1 or to_id = 1)
【解决方案2】:

你可以定义外键

class Club < ActiveRecord::Base
  has_many :home_matches, class_name: 'Match', foreign_key: 'home_team_id'
  has_many :away_matches, class_name: 'Match', foreign_key: 'away_team_id'
end

但我怀疑这会导致更多问题,因为您可能希望获取所有匹配项并按日期排序,您可以通过执行两个查询并添加结果和排序来做到这一点,但坦率地说这很混乱。

我最初的想法是你应该看一个有很多关系的人,你希望能够做到@club.matches

class Club < ActiveRecord::Base
  has_many :club_matches
  has_many :matches, through: :club_matches
end

class ClubMatch < ActiveRecord::Base
  belongs_to :club
  belongs_to :match
  #will have an attribute on it to determine if home or away team
end

class Match < ActiveRecord::Base
  has_many :club_matches
  has_many :clubs, through: :club_matches
end

那你就可以@club.matches

只是我最初的想法,有人可能会想出更好的解决方案

也许你可以只做一个没有关联的查询,这对你来说可能更好,重构更少。例如

class WhateverController < ApplicationController

  def matches
    @club = Club.find(params[:club_id)
    @matches = Match.where("home_team_id = :club_id OR away_team_id = :club_id", {club_id: @club.id}).order(:date)
  end

【讨论】:

  • 我认为您的查询是正确的。在考虑了该解决方案之后,该关联似乎没有必要!谢谢!
  • 别担心,有时您只见树木不见森林。写到一半就写了很多,然后认为你可以在忽略关联的查询中做到这一点。
猜你喜欢
  • 2013-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-06
  • 2021-06-30
  • 1970-01-01
  • 1970-01-01
  • 2012-12-19
相关资源
最近更新 更多