Jmorazano
Jmorazano

Reputation: 47

Rails model form f.select do not assign selected value to model key

sorry for this question but I'm struggling with this issue for hours now and can't find the answer anywhere.

Here is the thing, I have a rails app with "Reservation" and "Space" models with the following relations:

class Reservation < ActiveRecord::Base
    belongs_to :space
    belongs_to :user
end


class Space < ActiveRecord::Base
    belongs_to :condo
    has_many :reservations
end

When the user creates a new Reservation, in the form he gets to choose from a dropdown (f.select) the spaces available for him. The f.select in the form look like this:

  <div class="field">
    <%= @user_spaces = current_user.condo.spaces
        f.select :space_id, 
        options_from_collection_for_select(@user_spaces, :id, :name), :prompt => "Select space"
    %>
  </div>

That select it supose to assign a value to the key "space_id" in the Reservation that is being created (column's table is created). But when I check the last reservation in Rails console, space_id value is "nil". What am I doing wrong?

Thank you very much for your help

Reservation controller file:

class ReservationsController < ApplicationController
  before_action :set_reservation, only: [:show, :edit, :update, :destroy]

  # GET /reservations
  # GET /reservations.json
  def index
    @reservations = Reservation.all
  end

  # GET /reservations/1
  # GET /reservations/1.json
  def show
  end

  # GET /reservations/new
  def new
    @reservation = Reservation.new
  end

  # GET /reservations/1/edit
  def edit
  end

  # POST /reservations
  # POST /reservations.json
  def create
    @reservation = Reservation.new(reservation_params)
    @user = current_user.id
    @reservation.user_id = @user
    respond_to do |format|
      if @reservation.save
        format.html { redirect_to @reservation, notice: 'Reservation was successfully created.' }
        format.json { render :show, status: :created, location: @reservation }
      else
        format.html { render :new }
        format.json { render json: @reservation.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /reservations/1
  # PATCH/PUT /reservations/1.json
  def update
    respond_to do |format|
      if @reservation.update(reservation_params)
        format.html { redirect_to @reservation, notice: 'Reservation was successfully updated.' }
        format.json { render :show, status: :ok, location: @reservation }
      else
        format.html { render :edit }
        format.json { render json: @reservation.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /reservations/1
  # DELETE /reservations/1.json
  def destroy
    @reservation.destroy
    respond_to do |format|
      format.html { redirect_to reservations_url, notice: 'Reservation was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_reservation
      @reservation = Reservation.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def reservation_params
      params.require(:reservation).permit(:eventdate)
    end
end

Space controller file:

class SpacesController < ApplicationController
  before_action :set_space, only: [:show, :edit, :update, :destroy]

  # GET /spaces
  # GET /spaces.json
  def index
    @spaces = Space.all
  end

  # GET /spaces/1
  # GET /spaces/1.json
  def show
  end

  # GET /spaces/new
  def new
    @space = Space.new
  end

  # GET /spaces/1/edit
  def edit
  end

  # POST /spaces
  # POST /spaces.json
  def create
    @space = Space.new(space_params)

    respond_to do |format|
      if @space.save
        format.html { redirect_to @space, notice: 'Space was successfully created.' }
        format.json { render :show, status: :created, location: @space }
      else
        format.html { render :new }
        format.json { render json: @space.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /spaces/1
  # PATCH/PUT /spaces/1.json
  def update
    respond_to do |format|
      if @space.update(space_params)
        format.html { redirect_to @space, notice: 'Space was successfully updated.' }
        format.json { render :show, status: :ok, location: @space }
      else
        format.html { render :edit }
        format.json { render json: @space.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /spaces/1
  # DELETE /spaces/1.json
  def destroy
    @space.destroy
    respond_to do |format|
      format.html { redirect_to spaces_url, notice: 'Space was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_space
      @space = Space.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def space_params
      params.require(:space).permit(:name)
    end
end

And full Reservation Form:

<%= form_for(@reservation) do |f| %>
  <% if @reservation.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@reservation.errors.count, "error") %> prohibited this reservation from being saved:</h2>

      <ul>
      <% @reservation.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :eventdate %><br>
    <%= f.date_select :eventdate %>
  </div>

  <div class="field">
    <%= @user = current_user.condo.spaces
        f.select :space_id, 
        options_from_collection_for_select(@user, :id, :name), :prompt => "Select space"
    %>
  </div>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

Upvotes: 0

Views: 547

Answers (1)

PhilVarg
PhilVarg

Reputation: 4811

pretty sure you need to permit the space_id attribute in your strong params.

def reservation_params
  params.require(:reservation).permit(:eventdate, :space_id)
end

whats happening is that when you go to create a reservation, youre passing in set of params, that is the output of reservation_params

@reservation = Reservation.new(reservation_params)

if space_id is not being permitted in your strong params, then it will be nil when created.

if this is not the issue, can you post what params are getting to the server, and what the output of reservation_params are.

Upvotes: 1

Related Questions