【问题标题】:has_many :through, :source, :source_type returning empty arrayhas_many :through, :source, :source_type 返回空数组
【发布时间】:2011-06-30 11:16:47
【问题描述】:

我有一些 ManagerSoccerTeam 模型。经理“拥有”许多足球队;经理也可以评论足球队,也可以评论其他经理:

ma​​nager.rb

# Soccer teams the manager owns
has_many :soccer_teams, :dependent => :restrict
# Comments the manager has made on soccer teams or other managers
has_many :reviews, :class_name => "Comment", :foreign_key => :author_id, :dependent => :destroy
# Comments the manager has received by other managers
has_many :comments, :as => :commentable, :dependent => :destroy
# Soccer teams that have received a comment by the manager
has_many :observed_teams, :through => :comments, :source => :commentable, :source_type => "SoccerTeam"

soccer_team.rb

# The manager that owns the team
belongs_to :manager
# Comments received by managers
has_many :comments, :as => :commentable, :dependent => :destroy
# Managers that have reviewed the team
has_many :observers, :through => :comments, :source => :author, :class_name => "Manager"

comment.rb

belongs_to :commentable, :polymorphic => true
belongs_to :author, :class_name => Manager

现在,如果我有一位经理对 SoccerTeam 发表评论,我希望找到:

  • manager.reviewssoccer_team.comments 中的 Comment 对象
  • manager.observed_teams 中的 SoccerTeam 对象
  • soccer_team.observers 中的 Manager 对象

虽然第一点和第三点一切正常,但当我调用manager.observed_teams 时,我总是得到一个空数组。要真正获得经理评论过的足球队名单,我需要使用:

manager.reviews.collect{ |review| Kernel.const_get(review.commentable_type).find(review.commentable_id) if review.commentable_type == "SoccerTeam" }

这是丑陋的。我希望简单的manager.observed_teams 可以工作……为什么不行?

编辑

我更进一步了解了它为什么不起作用。其实生成的SQL是:

SELECT "soccer_teams".* FROM "soccer_teams" INNER JOIN "comments" ON "soccer_teams".id = "soccer_teams".commentable_id AND "comments".commentable_type = 'SoccerTeam' WHERE (("comments".commentable_id = 1) AND ("comments".commentable_type = 'Manager'))

虽然我希望它是:

SELECT "soccer_teams".* FROM "soccer_teams" INNER JOIN "comments" ON "soccer_teams".id = "comments".commentable_id AND "comments".commentable_type = 'SoccerTeam' WHERE ("comments".author_id = 1)

所以问题很简单:如何获取该查询? (正如预期的那样,使用:foreign_key:as 的启发式尝试并没有解决问题!)。

【问题讨论】:

    标签: ruby-on-rails model-view-controller has-many-through has-many has-many-polymorphs


    【解决方案1】:

    我认为您只是为 observed_teams 使用了错误的关联。而不是

    has_many :observed_teams, :through => :comments, 
      :source => :commentable, :source_type => "SoccerTeam"
    

    试试这个:

    has_many :observed_teams, :through => :reviews,
     :source => :commentable, :source_type => "SoccerTeam"
    

    还有,

    has_many :reviews, :class_name => :comment, 
      :foreign_key => :author_id, :dependent => :destroy
    

    :comment 应该是'Comment'

    has_many :comments, :as => commentable, :dependent => :destroy
    

    commmentable 应该是:commmentable

    【讨论】:

    • 最后两个是拼写错误……但您肯定明白关联的重点!谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-06
    • 1970-01-01
    • 2013-07-08
    • 2019-03-04
    • 2016-01-20
    • 1970-01-01
    相关资源
    最近更新 更多