I'm pretty new to rails and trying to get three models to work together with a has_many through relationship, alternate class names on the join model, and a collection_select form to add records to the join model. The three models are below. I have "accepts_nested_attributes_for" for all associations.
User Model
has_many :match_opponents
has_many :home_opponents, :class_name => 'MatchOpponent', :foreign_key => 'home_opponent_id'
has_many :away_opponents, :class_name => 'MatchOpponent', :foreign_key => 'away_opponent_id'
has_many :matches, :through => :match_opponents
Match Model
has_many :match_opponents
has_many :home_opponents, :class_name => 'MatchOpponent', :foreign_key => 'home_opponent_id'
has_many :away_opponents, :class_name => 'MatchOpponent', :foreign_key => 'away_opponent_id'
has_many :users, :through => :match_opponents
Match Opponent Model
belongs_to :user, :inverse_of => :match_opponents
belongs_to :match, :inverse_of => :match_opponents
My Matches Controller for new and create:
def new
@match = Match.new
@match.home_opponents.build
@match.away_opponents.build
end
def create
@match = Match.create(match_params)
@home_opponents = @match.home_opponents.create!(params[:match_opponents])
@away_opponents = @match.away_opponents.create!(params[:match_opponents])
if @match.save
redirect_to @match, notice: 'Match was successfully created.'
end
end
My form:
= simple_form_for @match, html: { multipart: true } do |f|
= simple_fields_for :home_opponents do |ff|
= ff.collection_select :user_id, User.all, :id, :name, {}, {multiple: true}
= simple_fields_for :away_opponents do |ff|
= ff.collection_select :user_id, User.all, :id, :name, {}, {multiple: true}
Relevant permitted parameters for each model:
def match_params
params.require(:match).permit(Match::MATCH_ATTRIBUTES)
end
MATCH_ATTRIBUTES = [:match_opponent_ids => [], :user_ids => [], match_opponents_attributes: MatchOpponent::MATCH_OPPONENT_ATTRIBUTES]
def user_params
params.require(:user).permit(User::USER_ATTRIBUTES)
end
USER_ATTRIBUTES = [:match_opponent_ids => [], :match_ids => [], :match_opponents_attributes: MatchOpponent::MATCH_OPPONENT_ATTRIBUTES]
def match_opponent_params
params.require(:match_opponent).permit(MatchOpponent::MATCH_OPPONENT_ATTRIBUTES)
end
MATCH_OPPONENT_ATTRIBUTES = [:id, :home_opponent_id, :away_opponent_id, :match_id, :user_id]
I've tried a lot of different configurations of the models but can't get multiple records on the join model (MatchOpponent) to save with both match_id and user_id recorded.
Thanks in advance for any help!
First you need to understand more about controller actions. You can read about them in the Rails Guides
For example:
def create
@match = Match.create(match_params)
@home_opponents = @match.home_opponents.create!(params[:match_opponents])
@away_opponents = @match.away_opponents.create!(params[:match_opponents])
if @match.save
redirect_to @match, notice: 'Match was successfully created.'
end
end
Match.create already saves the object, which you save again with if @match.save
. This should look like:
def create
@match = Match.new(match_params)
if @match.save
#create opponents here
redirect_to @match, notice: 'Match was successfully created.'
end
end