Hi all,
I'm trying to build a simple event registration function and having some trouble figuring the best way to make it work. Code isn't too clean as Ive been hacking at it for a while trying to figure out how to make this work. Registration options (such as, attend lunch, attend dinner, purchase tshirt, etc) are built in the new function and everything seems to work great, but when posted to the create method, only one registration_option is present:
[3] pry(#<RegistrationsController>)> params
=> {"utf8"=>"✓",
"authenticity_token"=>"35ZkbkCGZiiTEgw8Pn/nKnt0mCPTyCl0Lxks4koSOkM=",
"registration_options"=>{"attending"=>"0"},
"registration"=>
{"event_id"=>"4f7e669ebf73141072000005",
"stripe_card_token"=>"tok_PhjUuOtMf8jayw",
"email"=>"
f...@bar.com"},
"action"=>"create",
"controller"=>"registrations"}
Is there a best practice/good example to build from on creating/persisting documents with multiple embedded documents? And what am I doing incorrectly with this to make only a single registration_option being posted? Model definitions and code below. Thanks for any help.
Models:
class Registration
include Mongoid::Document
include Mongoid::Timestamps
field :email
field :total, type: Integer
field :stripe_card_token
embeds_many :registration_options
class RegistrationOption
include Mongoid::Document
field :shortname
field :description
field :price, type: Integer
field :attending, type: Integer
field :required, type: Boolean
field :min_required, type: Integer
field :free_count, type: Integer
embedded_in :registration
end
Controller:
class RegistrationsController < ApplicationController
def new
event = Event.find(params[:event_id])
@registration = event.registrations.build
event.event_options.each do |opt|
@registration.registration_options.build(shortname: opt.shortname, description: opt.description, price: opt.price, required: opt.required, attending: opt.default_attending, free_count: opt.free_count )
end
end
def create
@registration = Registration.new(params[:registration])
if @registration.save_and_process
redirect_to @registration, :notice => "Thank you for registrering!"
else
render :new
end
end
def show
@registration = Registration.find(params[:id])
end
end
View:
<h1>Signing up for <%= @
registration.event.name %></h1>
<%= form_for @registration do |f| %>
<% if @registration.errors.any? %>
<div class="error_messages">
<h2><%= pluralize(@registration.errors.count, "error") %> prohibited this subscription from being saved:</h2>
<ul>
<% @registration.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<% @registration.registration_options.each do |reg_opt| %>
<%= fields_for :registration_options, reg_opt do |opt|%>
<div class="registration_options">
<%= opt.label reg_opt.shortname %> - <%= Money.new(reg_opt.price).format %>/per person
<%= opt.text_field :attending, size: 2, disabled: reg_opt.required, id: "#{reg_opt.shortname}_attending" %><br/>
<%= reg_opt.description %> <% if reg_opt.free_count > 0 %> The first <%= reg_opt.free_count %> are included at no cost as part of your yearly dues <% end %>
</div>
<% end %>
<% end %>
<%= f.hidden_field :event_id %>
<%= f.hidden_field :stripe_card_token %>
<% @registration.update_total %>
Total cost: <%= Money.new(@registration.total).format %>
<div class="field">
<%= f.label :email %>
<%= f.text_field :email %>
</div>
<% if @registration.stripe_card_token.present? %>
Credit card has been provided.
<% else %>
<div class="field">
<%= label_tag :card_number, "Credit Card Number" %>
<%= text_field_tag :card_number, nil, name: nil %>
</div>
<div class="field">
<%= label_tag :card_code, "Security Code on Card (CVV)" %>
<%= text_field_tag :card_code, nil, name: nil %>
</div>
<div class="field">
<%= label_tag :card_month, "Card Expiration" %>
<%= select_month nil, {add_month_numbers: true}, {name: nil, id: "card_month"} %>
<%= select_year nil, {start_year: Date.today.year, end_year: Date.today.year+15}, {name: nil, id: "card_year"} %>
</div>
<% end %>
<div id="stripe_error">
<noscript>JavaScript is not enabled and is required for this form. First enable it in your web browser settings.</noscript>
</div>
<div class="actions">
<%= f.submit "Register" %>
</div>
<% end %>