Rails 3.2.2 - has_many through

trying to reorganize code to ensure clean association

GAME has HOME_TEAM and AWAY_TEAM

TEAM has many GAMES like HOME_TEAM or AWAY_TEAM

The association between GAME and TEAM is a direct HABTM, but I need to indicate which of the two TEAMS associated with GAME is HOME_TEAM and is AWAY_TEAM. I did this by adding extra fields and associations, but it is obviously very wet, not dry. I know the answer goes through, but I seem to have had a brain crisis, and I cannot solve this problem.

Basically, I want to be able to do Game.teams (returns a collection of both teams) and Game.home_team (get and install TEAM for home_team) and Game.away_team (get and install TEAM to away_team)

Sorry to make such a simple audio request, but it just left me

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 

All help is much appreciated

Peter

+5
source share
1 answer

To do what you want to do, you should use has_many :throughinstead hatbm. See here for more details . In short, it’s good that you can add other variables to the connection table. In your case, the boolean name is home_team.

So here is what I will do. First create an association table (since I don’t have much imagination, I will call this participation):

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

As you can see, unlike your gamma table, this one has an identifier. And you can add attributes to it. Then I will use these models:

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

So, to get the teams in the game, you do @game.teams.

, home_team away_team, :

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 edit: , mysql :

self.teams.joins(: ).where( " .home_team =?", true).first self.teams.joins(: ).where( "members.home_team IS NULL" ). first

"=?", true, "! =?", true --OR-- IS NOT NULL IS NULL

, false where("participants.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, nil, :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)
+7

All Articles