param丢失或值为空 - Ruby on Rails

时间:2015-12-11 01:59:13

标签: ruby-on-rails

这是完整的错误。 param丢失或值为空:module_list 它在def module_list_params下面的底部附近抛出错误,其中需要module_list。我已经看了几个问题的其他解决方案,但他们没有帮助我。这是我的代码。

  class ModuleListsController < ApplicationController
  before_action :set_module_list, only: [:show, :edit, :update, :destroy]
  before_action :set_student, only: [:new, :create]

  # GET /module_lists
  # GET /module_lists.json
  def index
    @module_lists = ModuleList.all
  end

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

  # GET /module_lists/new
  def new
    @module_list = @student.module_lists.new
  end

  # GET /module_lists/1/edit
  def edit
  end

  # POST /module_lists
  # POST /module_lists.json
  def create
    @module_list = @student.module_lists.new(module_list_params)

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

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

  # DELETE /module_lists/1
  # DELETE /module_lists/1.json
  def destroy
    @module_list.destroy
    respond_to do |format|
      format.html { redirect_to module_lists_url, notice: 'Module list was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

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

    def module_list_params
      params.require(:module_list).permit(:student_id, :title, :description,     :credit_value)
    end

    def set_student
      @student = Student.find_by(id: params[:student_id]) ||
      Student.find(module_list_params[:student_id])
    end
end

1 个答案:

答案 0 :(得分:0)

错误非常简单 - strong params要求在参数中分配module_list,如下所示:

params: {
   module_list: {
     student_id:   "w",
     title:        "x",
     description:  "y",
     credit_value: "z"
   }
}

每当你打电话给params.require(:module_list)时,它基本上需要按照上面的结构来设置参数。如果他们这样的结构,你将收到控制器需要params的错误,这就是你所拥有的。

此问题可能由多个问题引起,但主要是您没有正确设置form_for。你必须按如下方式设置它:

#app/controllers/modules_list_controller.rb
class ModulesListController < ApplicationController
   def new
     @module_list = ModuleList.new
   end
   def create
     @module_list = ModuleList.new module_list_params
     @module_list.save
   end

这将伴随以下form_for

<%= form_for @module_list do |f| %>
   <%= f.text_field ... %>
<% end %>

由于您似乎正在使用nested routes,我建议如下:

#config/routes.rb
resources :students do
   resources :module_lists, only: [:new, :create]
end

#app/controllers/modules_lists_controller.rb
class ModuleListsController < ApplicationController
   def new
      @module_list = @student.module_lists.new
   end
end

#app/views/module_lists/new.html.erb
<%= form_for [@student, @module_list] do |f| %>
   <%= ... %>
<% end %>

<强>更新

问题在于:

def set_student
   @student = Student.find_by(id: params[:student_id]) ||
      Student.find(module_list_params[:student_id])
end

因为你试图调用module_list_params,所以它确实认为它必须接受一个params哈希,而new动作却不是这样。

在这个例子中(IE,如果你一直使用嵌套资源),你只能通过引用params[:student_id]来逃避:

def set_student
   @student = Student.find params[:student_id]
end

-

进一步检查时,还有另一个问题。

您正在为set_student行动致电new。虽然这应该可以正常工作如果你有嵌套资源(正如我所推荐的那样),如果没有,它将导致问题。

因此,您需要执行以下操作:

#app/controllers/modules_list_controller.rb
class ModuleListController < ApplicationController
   before_action :set_student, only: :create #-> new doesn't have a student

这样您就可以在new操作中使用以下内容:

#app/views/module_lists/new.html.erb
<%= form_for @module_list do |f| %>
   <%= f.collection_select :student_id, Student.all, :id, :name %>