I would like to assign the event_option_id to the registration. I can easily do it in the view by adding this to the form:
<%= f.text_field :event_option_id, value: @event_option.id %>
I would like to do it in the model not in the view. For security I'm doing the same for the registration price. Setting the price from the model is working but doing the same thing for the event_option_id is not.
Registration Model:
class Registration < ActiveRecord::Base
belongs_to :event_option
belongs_to :order_item
belongs_to :order
before_save :set_event_options
def order_present
if order.nil?
errors.add(:order, "is not a valid order.")
end
end
def registration_price
self[:price] = event_option.price
end
def event_option_id
self.event_option_id = event_option
end
private
def set_event_options
self[:price] = registration_price
self.event_option_id = event_option_id
end
end
EventOptions model:
class EventOption < ActiveRecord::Base
belongs_to :event
has_many :registrations
end
Create Method in the Registrations controller:
def create
@event_option = EventOption.find(params[:id])
@order = current_order
@registration = @order.registrations.build(registration_params)
#@registration = Registration.new(registration_params)
@order_id = current_order.id
respond_to do |format|
if @registration.save
format.html { redirect_to @registration, notice: 'Registration was successfully created.' }
format.json { render :show, status: :created, location: @registration }
format.js {}
@order.save
session[:order_id] = @order.id
else
format.html { render :new }
format.json { render json: @registration.errors, status: :unprocessable_entity }
end
end
Error in log:
Started POST "/registrations" for 127.0.0.1 at 2016-01-04 21:16:06 -0500
Processing by RegistrationsController#create as JS
Parameters: {"utf8"=>"âo"", "registration"=>{"name"=>"saasas", "lastname"=>"asas"}, "commit"=>"Create Registration"}
EventOption Load (0.0ms) SELECT "event_options".* FROM "event_options" WHERE "event_options"."id" = ? LIMIT 1 [["id", nil]]
Completed 404 Not Found in 8ms (ActiveRecord: 0.0ms)
ActiveRecord::RecordNotFound (Couldn't find EventOption with 'id'=):
app/controllers/registrations_controller.rb:27:in `create'
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_source.erb (0.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb (0.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb (1.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb (44.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/_markup.html.erb (1.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/_inner_console_markup.html.erb within layouts/inlined_string (0.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/_prompt_box_markup.html.erb within layouts/inlined_string (0.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/style.css.erb within layouts/inlined_string (0.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/console.js.erb within layouts/javascript (48.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/main.js.erb within layouts/javascript (0.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/error_page.js.erb within layouts/javascript (0.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/index.html.erb (105.0ms)
I'm reading this part of the rails documentation: http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html , but still can't figure out whats going on.
Update:
Routes:
Rails.application.routes.draw do
resource :cart, only: [:show]
resources :orders
resources :order_items
resources :registrations
resources :event_options
resources :events
resources :charges
root 'events#index'
Registration form - inside event_option show.html.erb:
<%= form_for(@registration, remote: true) do |f| %>
<% if @registration.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@registration.errors.count, "error") %> prohibited this registration from being saved:</h2>
<ul>
<% @registration.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :lastname %><br>
<%= f.text_field :lastname %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I think your controller's create
function is missing params[:id]
.
The easiest way to fix is adding it into your form:
<%= form_for(@registration, remote: true) do |f| %>
<%= hidden_field_tag :id, your_event_option_id %>
### your other stuffs
The error clearly states that Rails is unable to find an EventOption
without an id
:
def create
@event_option = EventOption.find params[:id] #-> :id is not passed to create action
To fix it, just use the param
that's submitted as part of the form:
#app/controllers/registrations_controller.rb
class RegistrationsController < ApplicationController
def create
@order = current_order
@registration = @order.registrations.new registration_params
@registration.save
end
private
def registration_params
params.require(:registration).permit(:event_option_id, :other, :params)
end
end
--
The above would work well if the user could choose the event_option_id
in the form; if you're using a hidden_field
, you'll be better using nested routes
:
#config/routes.rb
resources :event_option do
resources :registrations #-> url.com/event_options/:event_option_id/registrations/new
end
This will set the event_option_id
as part of the top-level params hash, which will be passed to the controller as params[:event_option_id]
(as you have it already):
#app/controllers/registrations_controller.rb
class RegistrationsController < ApplicationController
def create
@event_option = EventOption.find params[:event_option_id]
end
end
Tip - you can declare multiple resources at once:
#config/routes.rb
resource :cart, only: [:show]
resources :orders, :order_items, :registrations, :event_options, :events, :charges
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.