Validation on a model object is failing despite what I think is the correct parameter value being whitelisted in the controller and passed to the model's constructor. What am I doing wrong?
OuterModel
has_one Location
via locatable
. The latter is created using accepts_nested_attributes_for
and validates only the :country
attribute:
(EDIT: I found the error, it was hidden by code that I initially left out of the code here for simplification. See my answer below)
class OuterModel < Parent
has_one :location, as: locatable
accepts_nested_attributes_for :location
end
class Parent < ActiveRecord::Base
after_create :create_location
end
class Location < ActiveRecord::Base
belongs_to :locatable, polymorphic: true
validates :country, inclusion: {in: ["US", "CA"]}
end
Controller:
class OuterModelsController < ApplicationController
def create
@outer = OuterModel.new(outer_params)
if @outer.save
byebug #debug here
redirect_to outer_path(@outer)
end
end
def outer_params
params.require(:outer).permit(:name, :type,
location_attributes: [:country, :state, :city])
end
end
Using byebug I see the @outer.save
call is satisfied, but the nested location object is not persisted because of a validation error:
(byebug) @outer.persisted? #true
(byebug) @outer.location.persisted? #false
(byebug) @outer.location.valid? #false
(byebug) @outer.location.country #nil
(byebug) @outer.id #6372
(byebug) @outer.location.errors
<ActiveModel::Errors:0x007f1f33c1eae0
@base=#<Location id: nil, city: nil, country: nil, state: nil, locatable_id: 6732, locatable_type: "OuterModel", created_at: nil, updated_at: nil>,
@messages={:country=>["is not included in the list"]}>
However, the controller outer_params method appears to be sending the correct hash to OuterModel.new
:
{"name"=>"A name",
"type"=>"OuterModel",
"location_attributes"=>{
"city"=>"South Deionview", "country"=>"US", "state"=>"IL"
}
}
Why then is the Location.country
value nil
after the call to save, and why is validation failing?
EDIT: logfile (much simplified) pastebin here. It seems like the correct values are being sent as part of the SQL