has_many,belongs_to有多个外键

时间:2014-05-07 09:46:11

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

我试图通过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

如何更改我的关系,以便我可以这样做?

2 个答案:

答案 0 :(得分:5)

我对Associations and (multiple) foreign keys in rails (3.2) : how to describe them in the model, and write up migrations的回答仅适合您!

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

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

那么有问题吗?

答案 1 :(得分:3)

您可以定义外键

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