I have a form that is intended to submit two models, the first model has_one
of the other model, Student_Detail
.
Many users on here have helped me with some errors that I encountered already, and now my form submits successfully, but only submits the primary model, Participant
.
I've submitted the form a few times and it stores all information that is a direct attribute of the Participant
model. In active admin the Participant
model data populates, but no Student_Detail
records exist.
In the console, Student_Detail
data is non-existent.
Form:
<%= form_for @participant, url: {action: "create"} do |f| %>
<%= f.label :first_name, 'First:' %>
<%= f.text_field :first_name %>
<%= f.label :last_name, 'Last:' %>
<%= f.text_field :last_name %>
<%= f.label :gender, 'Sex:' %>
<%= f.select :gender, ['Male', 'Female'] %>
<br>
<br>
<%= f.label :birthdate, 'Birthdate:' %>
<%= f.date_field :birthdate %>
<%= f.label :email, 'Email:' %>
<%= f.text_field :email %>
<%= f.label :phone, 'Phone:' %>
<%= f.text_field :phone %>
<%= f.label :street_name, 'Street Number & Name:' %>
<%= f.text_field :street_name %>
<%= f.label :city, 'City:' %>
<%= f.text_field :city %>
<%= f.label :state, 'State:' %>
<%= f.text_field :state %>
<%= f.label :zip, 'Zip:' %>
<%= f.text_field :zip %>
<!-- <%= f.label :role, 'Role:' %>
<%= f.select :role, ['Reader'] %> -->
<br>
<br>
<%= f.fields_for @participant.student_detail do |student_detail_field| %>
<%= student_detail_field.label :nationality, 'Nationality:' %>
<%= student_detail_field.text_field :nationality %>
<%= student_detail_field.label :religion, 'Religion:' %>
<%= student_detail_field.text_field :religion %>
<%= student_detail_field.label :need_ride, 'Do you need help getting to the church building?' %>
<%= student_detail_field.select :need_ride, ['Yes','No'] %>
<br>
<br>
<%= student_detail_field.label :has_spouse, 'Marital Status:' %>
<%= student_detail_field.select :has_spouse, ['married', 'single'] %>
<br>
<br>
<%= student_detail_field.label :spouse_name, "If married, spouse's name:" %>
<%= student_detail_field.text_field :spouse_name %>
<%= student_detail_field.label :english_level, 'English Level:' %>
<%= student_detail_field.select :english_level, ['Low', 'Medium Low', 'Medium', 'Medium High', 'High'] %>
<%= student_detail_field.label :expectation, 'What are your expectations for the program?:' %>
<%= student_detail_field.text_area :expectation %>
<%= student_detail_field.label :length_of_stay, 'About how long will you be in town?:' %>
<%= student_detail_field.select :length_of_stay, ['Less than 1 Year', '1 Year', '1-2 Years', '2-3 Years', '3+ Years'] %>
<%= student_detail_field.label :exact_length, 'Please tell us exactly how long you plan to be in town:' %>
<%= student_detail_field.text_area :exact_length %>
<% end %>
Models:
class Participant < ApplicationRecord
validates :last_name, presence: true
# validates :gender, inclusion: { in: %w(male female) }
validates :phone, presence: true
has_one :volunteer_detail, :dependent => :destroy
accepts_nested_attributes_for :volunteer_detail, :allow_destroy => :true
has_one :student_detail, :dependent => :destroy
accepts_nested_attributes_for :student_detail, :allow_destroy => :true
end
-
class StudentDetail < ApplicationRecord
belongs_to :participant
end
Controller:
class ParticipantsController < ApplicationController
def new
@participant= Participant.new
@studentdetail= @participant.build_student_detail(participant: @participant)
end
def create
@participant = Participant.create(participant_params)
@participant.save
if @participant.save
flash[:success] = "Successfully Registered!"
#email notifes admin of new registration
NotifyMailer.notify_email(@participant).deliver_later
redirect_to '/signup'
end
end
def edit
end
def update
end
def show
end
def index
end
private
def participant_params
params.require(:participant).permit(:first_name, :last_name, :gender, :email, :birthdate, :phone,
:street_name, :city, :state, :zip, student_detail_attributes: [:nationality, :religion, :need_ride,
:has_spouse, :spouse_name, :english_level, :expectation, :length_of_stay, :exact_length, :volunteer_id,
:matched, :returned_home, :participant_id])
end
end
Any suggestions or advice is appreciated, I'm trying to get both models to populate with data when the form is submitted, and currently the primary model is the only one working.
I believe the problem here is with the syntax of your fields_for line in your view.
Change
f.fields_for @participant.student_detail do |student_detail_field|
To
f.fields_for :student_detail, @participant.student_detail do |student_detail_field|
I would bet if you put a binging.pry or a puts statement in your controller to see your params the student_detail_attributes aren't even getting to your params. You can just insert
puts params.inspect
in your controller to check if the params are coming through as you expect them. Your strong params syntax looks correct as do the models so I think this is an issue with your views.EDIT
Here's a couple other things to try. As I mentioned in my comment, I normally would not do
@participant = Participant.create(participant_params)
I would just do:
The above will also clean up your code a little. (Also I noticed you don't have a case in this action for what to do when the participant doesn't save - as a side note you should write some code to handle that)
Also if neither of these above work, sometimes I find with accept_nested_attributes I have to set the models as "inverse" of one another. See this article for more information: https://robots.thoughtbot.com/accepts-nested-attributes-for-with-has-many-through -- its about a has_many but I think it should also relate to a has_one -- try in the Participant model:
has_one :student_detail, :dependent => :destroy, inverse_of: :participant
See if either of the above (or a combo of both) gets that nested model saving.