User を拡張するモデル HighSchool (high_school.rb) と、同じく User を拡張するモデル Athlete (athlete.rb) があります。Athlete では、begs_to :high_school があります。HighSchool では、has_many :athletes があります。
HighSchool コントローラーから Athlete を作成しようとすると、begins_to と has_many を追加する前は正常に機能していました (その時点で Athlete に high_school_id 列がなかったため)、壊れます。以下は私が受け取ったエラーです。問題は何ですか?
ActiveRecord::AssociationTypeMismatch (HighSchool(#2194641240) expected, got
String(#2151984260)):
app/controllers/high_school_controller.rb:6:in `new'
app/controllers/high_school_controller.rb:6:in `create_high_school_athlete'
config/initializers/disable_assets_logger.rb:10:in `call'
ここに HighSchoolController があります:
class HighSchoolController < ApplicationController
def create_high_school_athlete
athlete_attributes = params[:athlete]
athlete_attributes = construct_athlete_attributes(athlete_attributes)
@high_school_athlete = Athlete.new(athlete_attributes)
if @high_school_athlete.valid? && @high_school_athlete.save
stat_success = create_athlete_stats(@high_school_athlete, params)
if stat_success[:success]
respond_to do |format|
format.json { render json: { errors: @high_school_athlete.errors.full_messages } }
end
else
@high_school_athlete.destroy
respond_to do |format|
format.json { render json: { errors: stat_success[:error_messages] } }
end
end
else
respond_to do |format|
format.json { render json: { errors: @high_school_athlete.errors.full_messages } }
end
end
end
def create_athlete_stats high_school_athlete, params
@height = high_school_athlete.stat(:height)
@weight = high_school_athlete.stat(:weight)
height_in_inches = (params[:height_feet][:value].nil? ? 0 : params[:height_feet][:value].to_f * 12) + (params[:height_inches][:value].nil? ? 0 : params[:height_inches][:value].to_f)
@height.value = height_in_inches.to_s
@weight.value = params[:weight][:value]
if @height.save && @weight.save
{:success => true, :error_messages => ""}
else
{:success => false, :error_messages => @height.errors.full_messages + @weight.errors.full_messages}
end
end
private
def construct_athlete_attributes athlete_attributes
athlete_attributes[:username] = create_athlete_username(params[:athlete][:first_name], params[:athlete][:last_name])
athlete_attributes[:password] = (36**(16-1) + rand(36**16)).to_s(36)
athlete_attributes[:password_confirmation] = athlete_attributes[:password]
athlete_attributes[:user_type_id] = 1
athlete_attributes[:account_type_id] = 1
athlete_attributes[:state] = current_high_school.state
athlete_attributes[:hometown] = current_high_school.hometown
athlete_attributes[:high_school] = current_high_school.high_school
athlete_attributes[:high_school_id] = current_high_school.id
athlete_attributes
end
これはかなり長い ajax 呼び出しですが、(Rails のログによると) Ajax 呼び出しから直接のパラメーターは次のとおりです。
Started POST "/high_school/create_high_school_athlete" for 127.0.0.1 at 2013-04-10 10:45:29 -0500
Processing by HighSchoolController#create_high_school_athlete as */*
Parameters: {"utf8"=>"✓", "authenticity_token"=>"DIzC7Ix45dbXklLvYjbGf9i1sn67amaJYvG6zs5fhUA=",
"athlete"=>{"first_name"=>"a", "last_name"=>"a", "recruit_year"=>"2015",
"primary_sport_id"=>"6", "primary_sport_primary_position_id"=>"",
"secondary_sport_id"=>"", "email"=>"TEST@blah.com", "birthday"=>""}, "height_feet"=>
{"value"=>"5"}, "height_inches"=>{"value"=>"9"}, "weight"=>{"value"=>"160"}}
最後に、デバッガーを使用して、attributes_attributes (パラメーターとして Athlete.new が呼び出される直前) を出力すると、次のようになります。
(rdb:1) p athlete_attributes
{"first_name"=>"a", "last_name"=>"a", "recruit_year"=>"2015", "primary_sport_id"=>"6",
"primary_sport_primary_position_id"=>"", "secondary_sport_id"=>"",
"email"=>"TEST@blah.com", "birthday"=>"", "username"=>"aa",
"password"=>"c5n9abih4q705yet", "password_confirmation"=>"c5n9abih4q705yet",
"user_type_id"=>1, "account_type_id"=>1, "state"=>"AL", "hometown"=>"blahtown",
"high_school"=>"Blah University", "high_school_id"=>109}