【问题标题】:Multi level associations in railsRails 中的多级关联
【发布时间】:2010-11-24 15:14:49
【问题描述】:

我正在创建一个应用程序来跟踪整个赛季的足球队。但我被困在数据库的设计上。一个固定装置有一支主队和一支客队。我创建了一个夹具模型,它有两个外键——home_team 和 away_team,但我无法让关联正常工作。有任何想法吗?每个赛程都属于一个联赛。

【问题讨论】:

    标签: ruby-on-rails table-relationships


    【解决方案1】:

    简单的答案是:

    class Fixture < ActiveRecord::Base
      belongs_to :home_team, :class_name => "Team", :foreign_key => :home_team
      belongs_to :away_team, :class_name => "Team", :foreign_key => :away_team
    end
    
    class Team < ActiveRecord::Base
      has_many :fixtures
    end
    

    但是如果你这样做是不好的,因为 Team.fixtures 将不起作用。

    class Team < ActiveRecord::Base
      has_many :home_fixtures, :class_name => "Fixtures", :foreign_key => :home_team
      has_many :away_fixtures, :class_name => "Fixtures", :foreign_key => :away_team
    end
    

    会给你两个集合...但是聚合它们必须在 ruby​​ 中进行,这会很恶心。

    class Team < ActiveRecord::Base
      def fixtures(*args)
        home_fixtures.all(*args) + away_fixtures.all(*args)
      end
    end
    

    这也有它的问题,排序和限制都会被搞砸(嘿,双关语,谁知道?)。

    class Team < ActiveRecord::Base
      has_many :fixtures, :finder_sql => 'SELECT * FROM fixtures where (home_team = #{id} or away_team = #{id})'
      has_many :home_fixtures, :class_name => "Fixtures", :foreign_key => :home_team
      has_many :away_fixtures, :class_name => "Fixtures", :foreign_key => :away_team
    end
    

    这很丑陋,但可能会起作用。 finder_sql 似乎可以满足需要。

    另一种选择是使用named_scope:

    class Fixture < ActiveRecord::Base
      named_scope :for_team_id, lambda{|team_id| {:conditions => ['(home_team = ? or away_team = ?)', team_id, team_id]} }
      belongs_to :home_team, :class_name => "Team", :foreign_key => :home_team
      belongs_to :away_team, :class_name => "Team", :foreign_key => :away_team
    end
    
    class Team < ActiveRecord::Base
      def fixtures
        Fixtures.for_team_id(id)
      end
    end
    

    最后一个解决方案是我坚持使用的解决方案,因为它是一个作用域,它的行为很像只读关联,并防止:finder_sql 可能进一步发生的古怪(我的意思是真的?如何它知道如何合并更多的条件?它有时会做一个子查询,一个子查询?只是这里不需要吗?)。

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      假设你有一个Team 模型和一个Something 模型,后者将有home_team_idaway_team_id

      class Something < ActiveRecord::Base
        belongs_to :home_team, :class_name => 'Team'
        belongs_to :away_team, :class_name => 'Team'
      

      您将它们称为something.away_teamsomething.home_team

      【讨论】:

        猜你喜欢
        • 2023-03-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多