简体   繁体   中英

rails 4 - using has_and_belongs_to_many association

I have two types of data: Team and Game . A team can belong to more than one game (eg. a college can play basketball, football, and soccer), and each game naturally has many teams that play in the league.

class Game < ActiveRecord::Base
  has_and_belongs_to_many :teams
end

class Team < ActiveRecord::Base
  has_and_belongs_to_many :games
end

There's a table in the db with two columns to hold these relationships:

create_table "games_teams", id: false, force: true do |t|
  t.integer "game_id"
  t.integer "team_id"
end

So far so good.

I need to build a form to add new Teams but I can't get the Game to show up correctly:

<%= form_for @team, :html => {:class => 'form-horizontal form', :role => 'form'} do |f| %>
  <%= f.collection_select(:game_id, Game.all, :id, :name) %>

This throws an error undefined method game_id for #<Team:0x007fa1af68f2d8>

How do I properly insert game_id when working with a Team object, and team_id when adding a Game ? I realize these ought to handle a "multi-select" scenario, but at the moment I can't get any of it to work.

Thanks!

The answer you're looking for is to use game_ids[] instead:

#View
<%= f.collection_select(:game_ids, Game.all, :id, :name) %>

#Controller
def create
   @team = Team.new(Team_params)
   @team.save
end

private

def team_params
    params.require(:team).permit(game_ids: [])
end

This should set the collection values for has_and_belongs_to_many data. I'll have to test this when I get into the office - it definitely works, but whether the syntax is right is what I've got to find

The first parameter on collection_select is an attribute from the object that is been described. So, this line

f.collection_select(:game_id, Game.all, :id, :name)

Try to call game_id on the object team , which fails.

I'm not sure if there is a direct method supported by rails to help you construct this associations. You can always construct a solution with select_tag and options_for_select (with mutiple: true since it is a has_and_belongs_to_many , send an array of game_ids to your action and deal with it manualy.

You might also take a look on this rails cast

Try using association instead of collection_select

<%= form_for @team, :html => {:class => 'form-horizontal form', :role => 'form'} do |f| %>
    <%= f.association :game, collection: Game.all.map{|p| [p.id, p.name]}, :label => 'Drive', :prompt => "Select Game" %>

I believe you want to use has_many through instead of has_and_belongs_to_many. like:

class Game < ActiveRecord::Base
  has_many :game_teams
  has_many :teams, :through => :game_teams
end

class Team < ActiveRecord::Base
  has_many :game_teams
  has_many :games, :through => :game_teams
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM