Rails 模型形式 f.select 不将所选值分配给模型键

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

很抱歉这个问题,但我现在已经为这个问题苦苦挣扎了几个小时,而且在任何地方都找不到答案。

事情是这样的,我有一个 rails 应用程序,其中 "Reservation" 和 "Space" 模型具有以下关系:

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


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

当用户创建新的预订时,他可以在表单中从下拉列表 (f.select) 中选择可供他使用的空间。表单中的 f.select 如下所示:

  <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>

select 它应该为正在创建的预订中的键 "space_id" 分配一个值(创建列的 table)。但是当我在 Rails 控制台中查看最后一个预订时,space_id 的值是 "nil"。我做错了什么?

非常感谢您的帮助

预订控制器文件:

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 控制器文件:

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

以及完整的预订表:

<%= 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 %>

很确定您需要在强参数中允许 space_id 属性。

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

发生的事情是,当您创建预订时,您正在传递一组参数,即 reservation_params

的输出
@reservation = Reservation.new(reservation_params)

如果您的强参数中不允许 space_id,则创建时它将为 nil。

如果这不是问题,您能否 post 哪些参数正在获取服务器,以及 reservation_params 的输出是什么。