强参数:缺少哈希参数或值为空

时间:2015-10-08 21:05:28

标签: ruby-on-rails ruby parameters

我有一个表单,其中有一个带复选框的表格,以便在我的数据库中选择行并保存ID。

但它给我一个错误:

  

Param丢失或值为空:leadallocation“

我尝试了不同的方法,但仍然没有工作。所以目前我只是想在我的数据库中保存哈希。感谢。

# Never trust parameters from the scary internet, only allow the white list through.
def leadallocation_params
  params.require(:leadallocation).permit(:campaign_id, :company_id, :user_id)
end

请求参数:

{"utf8"=>"✓",
 "authenticity_token"=>"GruGL758jT4FO+t/BTRGLrD2uCGOj/qUCrB5VswquzR9N7JZ/rouLmGZnTE7A+XTARiLwkOy1n3/zMqhzuenmg==",
 "company_ids"=>["38",
 "40"],
 "commit"=>"Create Leadallocation"}

控制器

class LeadallocationsController < ApplicationController
  before_action :set_leadallocation, only: [:show, :edit, :update, :destroy]

  # GET /leadallocations
  # GET /leadallocations.json
  def complete
  end


  def index
    @leadallocations = Leadallocation.all
  end

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

  # GET /leadallocations/new
  def new


    @leadallocation = Leadallocation.new
    @comps =  Company.all
  end

  # GET /leadallocations/1/edit
  def edit
  end

  # POST /leadallocations
  # POST /leadallocations.json
  def create

    @leadallocation = Leadallocation.new(leadallocation_params)

    @leadallocation.company_id = params[:company_ids]


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

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

  # DELETE /leadallocations/1
  # DELETE /leadallocations/1.json
  def destroy
    @leadallocation.destroy
    respond_to do |format|
      format.html { redirect_to leadallocations_url, notice: 'Leadallocation was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

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

    # Never trust parameters from the scary internet, only allow the white list through.
    def leadallocation_params
      params.require(:leadallocation).permit(:campaign_id, :company_id, :user_id)
    end
end

模特

class Leadallocation < ActiveRecord::Base
  belongs_to :campaign
  belongs_to :company
  belongs_to :user
end

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  has_many :activities
  belongs_to :campaign
  has_many :leadallocations

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
end

class Company < ActiveRecord::Base
  belongs_to :campaign
  has_many :subsidiaries
  has_many :leadallocations
end

class Campaign < ActiveRecord::Base
  belongs_to :client
  has_many :leads
  has_many :activities
  has_many :contacts
  has_many :users
has_many :leadallocations

end

的routes.rb

resources :leadallocations

视图

    <h1>New Leadallocation</h1>

<p id="notice"><%= notice %></p>

<h1>Listing Companies</h1>
<%= simple_form_for(@leadallocation) do |f| %>

<table class="table table-bordered">
  <thead>
    <tr>
      <th></th>
      <th>Name</th> 
      <th>Country</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @comps.each do |company| %>
      <tr>
      <td><%= check_box_tag "company_ids[]", company.id %></td>
        <td><%= company.name %></td>
        <td><%= company.country %></td>

      </tr>
    <% end %>
  </tbody>
</table>

<br>
<div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>
<%= link_to 'Back', leadallocations_path %>

2 个答案:

答案 0 :(得分:0)

使用Strong Params的方式要求您的参数符合特定表格。

在这种情况下,你需要将params嵌套在键leadallocation

问题出在您的表单中,而不是check_box_tag,您需要执行f.check_box并使用this documentation查看可用选项。

这会将您的属性嵌套在leadallocation下,如果没有,那么您的模型和表单设置可能会出错。

基本上所有这一切都是说你想要改变你的参数:

 {"utf8"=>"✓",
  "authenticity_token"=>"GruGL758jT4FO+t/BTRGLrD2uCGOj/qUCrB5VswquzR9N7JZ/rouLmGZnTE7A+XTARiLwkOy1n3/zMqhzuenmg==",
  "company_ids"=>["38",
  "40"],
  "commit"=>"Create Leadallocation"}

到此:

 {"utf8"=>"✓",
  "authenticity_token"=>"GruGL758jT4FO+t/BTRGLrD2uCGOj/qUCrB5VswquzR9N7JZ/rouLmGZnTE7A+XTARiLwkOy1n3/zMqhzuenmg==",
  "leadallocation" => {
    "company_ids"=>["38","40"]
  }
  "commit"=>"Create Leadallocation"}

答案 1 :(得分:0)

问题在于:

"company_ids"=>["38", "40"]

应该

"leadallocation" => {
    "company_ids" => ["38", "40"]
}

这是传递给db的Rails对象的标准构造。这就是strong_params结构的原因......

params.require(:top_level_param).permit(:child_params)

-

可以通过简单地使用.permit来解决这个问题:

#app/controllers/leadallocations_controller.rb
class LeadAllocationsController < ApplicationController
    private
    def leadallocation_params
       params.permit(:company_ids)
     end
end

这不是永久修复,而是HACK !!!

修正:

#app/views/lead_allocations/new.html.erb
<%= simple_form_for @leadallocations do |f| %>
    <%= f.collection_check_boxes :company_ids, Company.all, :id, :name %>
    <%= f.submit %>
<% end %>

参考文献:

  

将您需要的数据发送回控制器。请注意f.___ - 这会告诉Rails使用您在@leadallocations周围调用的FormBuilder来构建表单。

简单地说,这意味着您的数据将封装在{"leadallocations" => ...}参数中,而如果您只使用check_box_tag,则会假设数据是独立的。

此外,永远不会使用HTML来设置您的网页样式。使用<br><table> 用于格式化。 CSS是设置应用程序样式的唯一方法。 Your use of <table> seems to be okay;我只是想强调一下,因为大多数人都不了解HTML与CSS的概念。

此外,还有另一个问题 - 与您的关联:

class Leadallocation < ActiveRecord::Base
  belongs_to :company
end

您无法将多个公司ID分配给belongs_to关系:

enter image description here

我见过可以传递[foreign_key]_ids的情况,但不建议这样做;确实是antipattern

您要寻找的是has_and_belongs_to_many

enter image description here

#app/models/leadallocation.rb
class LeadAllocation < ActiveRecord::Base
   has_and_belongs_to_many :company
end

#app/models/company.rb
class Company < ActiveRecord::Base
   has_and_belongs_to_many :leadallocations
end

#join table - companies_leadallocations

这肯定允许您为每个公司关联多个leadallocations,反之亦然。