I have a nested form that has 3 fields repeated 7 times. I want to do a check that if the first field group is empty, then it will stop the process and return an error asking a user to fill in those fields.
I already have a check in that it will drop any empty field groups from the Create action in the controller, that is the "reject_if: => :all_blank" part of the model. However, it deletes the first entry, which I would instead rather run a check on. This code doesn't work, and I don't know where to go from here besides trying to refine the check_attendee_form method. Any help would be appreciated out there.
Here are the related Models:
class Registration < ActiveRecord::Base
# Database Relationships
belongs_to :event
belongs_to :user
has_many :attendees
# Form relationships
accepts_nested_attributes_for :attendees,
:allow_destroy => true,
:reject_if => :all_blank
class Attendee < ActiveRecord::Base
# Database relationships
belongs_to :event
belongs_to :user
delegate :event, :event_id, to: :registration
# Validations
validates :first_name, :last_name, presence: true
Controller Create and New Actions and Methods
def new
@registration = @event.registrations.new
7.times { @registration.attendees.build }
end
def create
@registration = @event.registrations.new(registration_params)
@registration.user = current_user
check_attendee_form
respond_to do |format|
if @registration.save
format.html { redirect_to event_path(@event), notice: 'You are now registered.' }
format.json { render :show, status: :created, location: @registration }
else
format.html { render :new }
format.json { render json: @registration.errors, status: :unprocessable_entity }
end
end
end
def check_registration
@check = Registration.find_by event_id: @event, user_id: current_user
if @check.nil?
@registration = @event.registrations.new
@registration.user = current_user
else
redirect_to event_path(@event),
notice: "You're already registered!"
end
end
def check_attendee_form
@attendees_check = @registration.find_by(attendees_attributes: params[:first_name])
if @attendees_check.first.nil?
render :new, notice: "You need to put in your name at least!"
else
end
end
And finally, the essential form info:
<%= simple_form_for [@event, @registration], :html => { :class => 'form-horizontal' } do |f| %>
<%= render 'shared/errors', object: @registration %>
<%= f.simple_fields_for :attendees, defaults: { input_html: { class: 'form-horizontal' } } do |a| %>
<div>
<%= a.label :first_name %>:
<%= a.text_field :first_name %>
<%= error_span([:first_name]) %>
<%= a.label :last_name %>:
<%= a.text_field :last_name %>
<%= error_span([:last_name]) %>
<%= a.label :fundraising_goal %>:
<%= a.number_field :fundraising_goal, placeholder: 'No Commas' %>
<%= error_span([:fundraising_goal]) %>
Here are the params that are getting submitted:
{"utf8"=>"✓",
"authenticity_token"=>"dNR5QCBFplsAG0wzy87+hzaKuG6h2Mlb6xpmKEM0Kko=",
"registration"=>{"attendees_attributes"=>{"0"=>{"first_name"=>"",
"last_name"=>"",
"fundraising_goal"=>""},
"1"=>{"first_name"=>"",
"last_name"=>"",
"fundraising_goal"=>""},
"2"=>{"first_name"=>"",
"last_name"=>"",
"fundraising_goal"=>""},
"3"=>{"first_name"=>"",
"last_name"=>"",
"fundraising_goal"=>""},
"4"=>{"first_name"=>"",
"last_name"=>"",
"fundraising_goal"=>""},
"5"=>{"first_name"=>"",
"last_name"=>"",
"fundraising_goal"=>""},
"6"=>{"first_name"=>"",
"last_name"=>"",
"fundraising_goal"=>""}}},
"commit"=>"Create Registration",
"event_id"=>"5"}
How do I access the first array object with attendees_attributes of ID [0] in this form submission?
If you want to ensure that at least one Attendee is entered for a registration, I believe you could drop the check_attendee_form
method and add the following validation to registration.rb:
validate :check_minimum_attendees
def check_minimum_attendees
errors.add(:attendees, 'must be entered') if attendees.size == 0
end