Rails has_many自定义ActiveRecord关联

时间:2013-07-04 18:42:20

标签: ruby-on-rails database activerecord

我有一个团队模型和一个Fixtures模型。 Fixtures模型有一个客队和一个主队。我按照this answer中的示例进行操作,并且大部分工作都有效。

class Fixture < ActiveRecord::Base
  belongs_to :home, class_name: 'Team'
  belongs_to :away, class_name: 'Team'
end


class Team < ActiveRecord::Base
  has_many :home_games, :class_name => 'Fixture', :foreign_key => 'home_id'
  has_many :away_games, :class_name => 'Fixture', :foreign_key => 'away_id'
end

我希望能够调用@ team.fixtures来获得所有球队赛程的列表,目前@ team.home_games给了我主场赛程,@ team.away_games让我离开。 如何撰写与has_many :games类似的has_many :home_games,这是最好的方式吗?

1 个答案:

答案 0 :(得分:8)

我认为最好的方法是为此写实例方法

在团队模型中:

def games
  Fixture.where("home_id = ? OR away_id = ?", self.id, self.id)
end

像常规方法一样使用它:

Team.first.games
#=> [<Fixture id: ... >, <Fixture id: ... >, ... ]

这应该返回一个ActiveRecord :: Relation 可以重复使用范围链等。

(这是一个类似的问题,但has_oneRails Model has_many with multiple foreign_keys


此外,您可以使用Team的id创建一个类方法(如果您已经拥有team_id但不是Team实例对象):

class Team < ActiveRecord::Base
  has_many :home_games, :class_name => 'Fixture', :foreign_key => 'home_id'
  has_many :away_games, :class_name => 'Fixture', :foreign_key => 'away_id'

  def games
    Team.games(self.id)
  end

  def self.games(team_id)
    Fixture.where('fixtures.home_id = ? OR fixtures.away_id = ?', team_id, team_id)    
  end
end

并像这样使用它:

Team.games(params[:team_id])
# or
@team = Team.where(id: params[:id]).first
@team.games