简体   繁体   中英

Rails assign id in model

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM