设置和查询三个模型之间的ActiveRecord关联

时间:2014-08-29 05:12:02

标签: sql ruby-on-rails activerecord associations model-associations

我是一个新兴的Rails"开发人员"这是我的第一个StackOverflow问题(耶!)。我正在构建一个应用程序(用于我的课程最终项目),允许用户通过预测给定电视节目中的活动和事件来获得积分。到目前为止玩得很开心,但是,却无法构建定义以下模型之间关联的最佳方法。

我研究了三种模型之间的三向关联,但大多数答案(如How to query across three modelsRight association between three models)都没有解决所有三种模型之间的HABTM关联< / em> ...所以你的帮助将不胜感激!

我的问题概述:

一个节目包含许多 剧集 ,每个节目中都有很多 参赛者 (字符)。通过节目联系,参赛者和剧集应该有HABTM关系,但我不需要为我的应用程序分段...

棘手的部分是每个 参赛者 可以在给定的 积分 >插曲 即可。我想做的是记录每个参赛者每集获得的积分,然后在我需要为用户计算积分时查询。

我已经尝试使用 episode_id 作为第三列的联接表 contestants_points 进行实验,但这并没有奏效。我还玩弄了一个表 contestants_episodes_points 的想法,但无法弄清楚如何为该表创建一个新实例。以下是我尝试构建以下模型的方法:

contestant.rb

class Contestant < ActiveRecord::Base
    belongs_to :show
    has_and_belongs_to_many :points, inverse_of: :contestants
    has_many :episodes, through: :points                         # not sure about this
end

示例:参赛者1 = {姓名:&#39; Gloria&#39;年龄:30岁,职业:&#39;护士,show_id:1}

episode.rb

class Episode < ActiveRecord::Base
    belongs_to :show
    has_and_belongs_to_many :points, inverse_of: :episodes
    has_many :contestants, through: :points                    # not sure about this
end

示例:第1集= {show_id:1,air_date:2014/04/02}

point.rb

class Point < ActiveRecord::Base
    belongs_to :show
    has_and_belongs_to_many :contestants, inverse_of: :points
    before_destroy { contestants.clear }
    has_and_belongs_to_many :episodes, inverse_of: :points    
end

示例:第1点= {事件:&#39;参赛者进入参数&#39;,show_id:1,积分:10}

示例:第2点= {事件:&#39;参赛者在第7集&#39;,show_id:1,积分:70}被淘汰

最大的难题:

我应该如何设置所有三个模型之间的关联,以便我可以查询:

  • 参赛者A在第1集中得分多少分?
  • 哪些参赛者在第1集中得分?
  • 参赛者A在第1-5集之间得分多少分?

HABTM是获取我想要的查询结果的正确方法吗?是否有更简单的方法来构建这三个模型?再次感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

我正在经历这一集 - &gt;选手 - &gt;点示例使答案简短明了。

首先提出一些建议:如果您在处理有效记录时遇到任何问题,请跳至rails console

现在您已经提到过,参赛者 belongs_to :show剧集 belongs_to :show

要支持这些关系,您必须在show_idcontestants表中同时显示episodes。这就是rails如何维护关联的方式。因此,每当您创建参赛者或剧集时,您也会将show id传递给他们。

让我们说show id是1。 然后,

show = Show.find 1

现在访问该节目的所有参赛者或剧集:

show.contestants 
# => returns all contestants for show 1
show.episodes
# => returns all episodes for show 1

现在回到你的问题:

  

棘手的部分是每个参赛者都可以得到很多积分   给出的一集。我想做的是记录每个点   参赛者每集获得,然后在我需要时查询   计算用户的积分。

如果我是正确的,参赛者将得分。所以你的关系不正确: 点belongs_to :contenstant

继续前进,因为积分属于参赛者,所以在points表格中会有参赛者列表,再次说明了如何保持关系。

所以让我们创造一个参赛者。

contestant = Contestant.create(name, attributes, show_id, episode_id) # as episode has many contestant 
# => returns contestant

现在创建剧集

episode = Episode.create(name, attributes, show_id)
# => returns episode

要查看该剧集的所有参赛者:

episode.contestants

为参赛者创造积分:

point = Point.create(value, contestant_id)

访问参赛者的分数

contenstant.points 

现在从头开始。

point.contestant
#=> returns contestant to whom it belong

point.contestant.episode 
#=> returns episode in which it was scored

point.contestant.show 
#=> returns the show that point belongs to
PS:这是一个很长的答案,所以即使我试图保持专注,我可能会迷失在中间,如果是这样,请问我会澄清那个特别的事情。

答案 1 :(得分:0)

听起来你需要一集才能在那一集中通过参赛者获得很多积分。

参赛者有积分,剧集有参赛者。从剧集中获取该剧集的点数的方法是通过参赛者。

希望有所帮助。

答案 2 :(得分:0)

当前解决方案

我的一位出色的同学建议我将积分视为事件的实例,并将Point类重命名为 事件 ,然后创建新的 Point 类属于 contestant_id,episode_id event_id

class Event < ActiveRecord::Base
    belongs_to :franchise, inverse_of: :events
    has_many :points
    has_many :contestants, through: :points
    has_many :episodes, through: :points
end

class Point < ActiveRecord::Base
    belongs_to :contestant
    belongs_to :episode
    belongs_to :event
end

现在我可以在控制台中运行以下查询:

> Contestant.first.points
=> # [Point1, Point2, Point3]
> Contestant.first.events
=> # [Event1, Event2, Event3]

现在我可以轻松访问实际的点数。非常容易重组,只需对我的其他10个型号进行最少的更新。谢谢Allen Hsu!