【问题标题】:How do I set up a kind of "belongs_to :through" association without a direct belongs_to?如何在没有直接的 belongs_to 的情况下建立一种“belongs_to :through”关联?
【发布时间】:2011-10-20 09:47:54
【问题描述】:

我知道“belongs_to :through”是无效的。这只是我试图表达我想要实现的目标。等我一会儿……

这就是我所拥有的:

class League
  has_many :divisions
end

class Division
  belongs_to :league
  has_many :teams
end

class Team
  belongs_to :division
  has_many :players
end

class Player
  belongs_to :team
end

现在,为了制作“棒球卡”视图表单,我需要:

name
team.name
team.division.name
team.division.league.name

那么,有没有办法建立一个“belongs_to :through”关联来直接从“players_controller”访问“division.name”而不需要“team”。字首??我必须访问从 'player' 到 'division' 的很多列,所以我正在寻找一种方法来“直接”访问这些列。

一种选择是在“玩家”表中包含一个“division_id”列,但有人告诉我这会破坏关系数据模型,因为如果数据选择功能不正确,它会导致不一致已处理(例如,玩家 A 在 A 组中的 A 组,但玩家 A 的 Division_id 列设置为 B 组)。

是否可以建立“符号链接”,例如“division”现在指代“team.division”,“league”现在指代“team.division.league”??

或者,每次都使用完整路径的唯一真正选择是什么??

希望有人能提供帮助。

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    在模型类中使用委托。

    class Team < ActiveRecord::Base
      belongs_to :division
      has_many :players
    
      delegate :league, to: :division
    end
    

    参考:http://api.rubyonrails.org/classes/Module.html#method-i-delegate

    【讨论】:

    • 这是最好的方法,应该选择而不是blackbird07的。
    • 我同意!
    • 这很优雅,但您需要对对象树中的每一层进行一次查询。因此,如果您只需要顶级对象,则可以将其打包在一个 SQL 查询中。后续会有ofc的查询,但还是只有一个转rails -(query)-&gt; database -(result)-&gt; rails。不幸的是,我不知道用 Rails 查询界面来做这件事。有谁知道吗?
    • 第三个答案回答了我的问题... :)
    • 简单,我也会像这样委派 id delegate :league, :league_id, to: :division
    【解决方案2】:

    你可以试试

    类播放器 所属:团队 has_one :division, :through => :team 结尾

    【讨论】:

    • 不,你不应该这样做。 has_one 关系通过外键建议另一个模型中的 belongs_to 关系。但是Division 不是belongs_to :team,而是has_many :teams,这意味着团队belongs_to :division。 Matt Smith 说对了:你也可以在 Player 类中使用这个逻辑:delegate :division, :to =&gt; :team
    • 我同意你的看法——关于 Rails 的当前状态。但我想知道为什么没有 belongs_to :through.
    • 噢!这适用于最少数量的查询。我觉得应该有belongs_to :through!此外,您的解决方案缓存了division 查询的结果。
    • @JaapHaagmans has_one :through 在这里实际上是正确的,据我所知。has_one 只是 Rails 术语,表示该模型没有外键字段的 1:1 关联——这里的确切情况。 Division belongs_to :team 与这方面无关。
    • @JaapHaagmans delegate 如果您想要的只是Player#division 的定义,则效果很好。但是,如果您使用has_one :through,您将获得所有其他 Rails 关联方法,这些方法有时是需要的。
    【解决方案3】:

    你可以在你的播放器模型中定义一个辅助方法:

    def division
      team.division
    end
    
    def league
      team.division.league
    end
    

    当然,这仅与代码的可读性有关,不会影响所涉及的数据库查询的形式。如果您的语句生成多个 SQL 查询但您只需要一个,请在此处查看 .include 选项:Rails Guides - Active Record Query Interface

    【讨论】:

      猜你喜欢
      • 2017-05-16
      • 1970-01-01
      • 2011-04-21
      • 1970-01-01
      • 2013-04-22
      • 1970-01-01
      • 1970-01-01
      • 2013-07-24
      • 1970-01-01
      相关资源
      最近更新 更多