加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – Rails 3.2.2 – has_many through

发布时间:2020-12-17 03:28:23 所属栏目:百科 来源:网络整理
导读:试图重构代码以提供干净的关联 游戏有一个HOME_TEAM和一个AWAY_TEAM TEAM有许多游戏作为HOME_TEAM或AWAY_TEAM GAME和TEAM之间的关联是直接的HABTM但我需要表示与GAME相关联的两个TEAM中的哪一个是HOME_TEAM,哪个是AWAY_TEAM.我是通过添加额外的字段和关联来
试图重构代码以提供干净的关联

游戏有一个HOME_TEAM和一个AWAY_TEAM

TEAM有许多游戏作为HOME_TEAM或AWAY_TEAM

GAME和TEAM之间的关联是直接的HABTM但我需要表示与GAME相关联的两个TEAM中的哪一个是HOME_TEAM,哪个是AWAY_TEAM.我是通过添加额外的字段和关联来实现的,但这显然非常潮湿而不是干燥.我知道答案已经过去,但我似乎已经脑部崩溃,并且无法完全理解这一点.

基本上我希望能够做Game.teams(返回两个团队的集合)和Game.home_team(获取并设置TEAM到home_team)和Game.away_team(获取并设置TEAM到away_team)

很抱歉提出这样一个直截了当的声音查询,但它只是离我而去

class Game < ActiveRecord::Base
  belongs_to :home_team
  belongs_to :away_team
  has_and_belongs_to_many :teams
end

class HomeTeam < ActiveRecord::Base
  belongs_to :team
  has_one :games
end

class AwayTeam < ActiveRecord::Base
  belongs_to :team
  has_one :games
end

class Team < ActiveRecord::Base
  has_and_belongs_to_many :games
  has_many :away_teams
  has_many :home_teams
end

所有帮助非常感谢

彼得

解决方法

要做你想做的事,你应该使用has_many:through而不是hatbm.有关详细信息,请参阅 here.简而言之,好处是您可以将其他变量添加到连接表中.在您的情况下,一个名为home_team的布尔值.

所以这就是我要做的.首先,创建一个关联表(因为我没有太多的想象力,我称之为参与):

create_table :participations,do |t|
  t.integer :game_id,:null => false
  t.integer :team_id,:null => false
  t.boolean :home_team
end

正如您所看到的,与您的gameteams表不同,这个表有一个id.您可以为其添加属性.
然后,我会使用这些模型:

class Participation < ActiveRecord::Base
  belongs_to :game
  belongs_to :team
end

class Game < ActiveRecord::Base
  has_many :participations,:dependent => :destroy
  has_many :teams,:through => :participations
end

class Team < ActiveRecord::Base
  has_many :participations,:dependent => :destroy
  has_many :games,:through => :participations
end

所以为了获得一个游戏团队,你可以做@ game.teams.

现在,要获得home_team和away_team,请将这些方法添加到您的Game模型中:

def home_team
  self.teams.joins(:participations).where("participations.home_team IS ?",true).first
end

def away_team
  self.teams.joins(:participations).where("participations.home_team IS ?",false).first
end

然后你就可以做@ game.home_team和@ game.away_team.

Peter’s edit: Ok,so for mysql you’ll have to use different where
statements:

self.teams.joins(:participants).where(“participants.home_team = ?”,true).first
self.teams.joins(:participants).where(“participants.home_team IS NULL”).first

I can either use ” = ?”,true and “!= ?”,true –OR– IS NOT NULL and
IS NULL

我认为你应该尝试使用where(“participant.home_team =?”,false)

好的,所以至少有两种方法来建立您的团队.

>您让用户选择哪个团队正在回家
>你认为第一支球队是主队

如果你去1号,你应该使用一个单选按钮让用户决定.像这样的东西:

<%= label_tag :home,'Home Team' %><br />
<%= label_tag :home_team_1,'Team 1' %><%= radio_button_tag :home_team,1 %>
<%= label_tag :home_team_2,'Team 2' %><%= radio_button_tag :home_team,2 %>

因此,如果params [:home_team] == 1,则第一支球队是主队,如果params [:home_team] == 2,则第二支球队是主队.

如果你选择2号,那么,你应该在你的表单中有这样的东西,将你的游戏添加到游戏中:

<%= label_tag :name,'Home Team' %>
  <%= text_field_tag :name,nil,:name => "home[]" %>

  <%= label_tag :name,'Away Team' %>
  <%= text_field_tag :name,:name => "away[]" %>

那么在你的控制器中你可以做类似的事情

@game = Game.new(params[:game])

home = Team.create(params[:home])
# or
home = Team.find_or_create_by_name(params[:home][:name])
@game.participations.create(:team_id => home.id,:home_team => true or 1)

away = Team.find_or_create_by_name(params[:away][:name])
@game.participations.create(:team_id => away.id,:home_team => false or 0)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读