简体   繁体   English

在Rails4中使用复选框和强参数创建多个条目

[英]Create multiple entries with checkbox and strong params in Rails4

I am having problems with the following scenario: 我在以下情况下遇到问题:

My users do searches by keywords which produces a list. 我的用户通过关键字进行搜索,从而生成列表。 The user has 2 actions either add them to a favorites table or block them using check boxes. 用户有2个动作,要么将它们添加到收藏夹表中,要么使用复选框阻止它们。

The problem I have is that when users click "Add to Favorites" the form passes a list of hashes to my strong params method and I am not able to pass it correctly. 我的问题是,当用户单击“添加到收藏夹”时,表单将哈希列表传递给我的强params方法,而我却无法正确传递它。

I think the problem is that the hash required by strong_params is inside another hash. 我认为问题在于strong_params所需的哈希在另一个哈希内。

Also I have no idea on how to pass the same hash to the BlockController when user click "Block" 我也不知道当用户单击“块”时如何将相同的哈希传递给BlockController

This is the error message: 这是错误消息:

param is missing or the value is empty: {:favorites=>{:name=>"Jon Doe", :title=>"Provider", :company=>"Acme", :location=>"Dubai", :profile=>"Group A", :notes=>""}}

My results.html.erb is 我的results.html.erb是

<table class="table table-striped table-bordered">
  <tr>
      <th class="center">Name</th>
      <th class="center">Title</th>
      <th class="center">Company</th>
      <th class="center">Location</th>
      <th class="center">Profile</th>
      <th class="center">Select</th>

  </tr>
  <%= form_tag favorites_path do %>
        <%= @results.length %>
        <% @results.each do |key,value| %>

            <tr>
              <td><%= value['name'] %></td>
              <td><%= value['title'] %></td>
              <td><%= value['company'] %></td>
              <td><%= value['location'] %></td>
              <td><%= link_to 'Profile', value['profile'],:target => "_blank"%></td>
              <td><%=check_box_tag 'favorite[]',  {:name => value['name'],:title =>value['title'],:company => value['company'],:location => value['location'], :profile=> value['profile'], :notes =>""}%></td>

        </tr>

        <% end %>
    <%= submit_tag "Add to Favorites", name: 'add', class: 'btn btn-primary' %>
    <%= submit_tag "Block Profiles", name: 'block', class: 'btn btn-danger' %>
  <% end %>
</table>

this is how my strong_params method looks: 这是我的strong_params方法的外观:

def favorite_params

  params[:profiles].each do |e|
    params.require(e).permit(:name, :title, :company, :location, :profile, :notes)
  end
end

Any ideas? 有任何想法吗?

Update: 更新:

I am able to pass params as: 我能够将参数传递为:

def favorite_params
      params.permit(:commit,favorite:[])
    end

create method: 创建方法:

def create
    @favorite = Favorite.new(favorite_params)
    @favorite.user_id = current_user.id
    respond_to do |format|
      if @favorite.save
        format.html { redirect_to @favorite, notice: 'Favorite was successfully created.' }
        format.json { render :show, status: :created, location: @favorite }
        format.js { render :show, status: :created, location: @favorite }

      else
        format.html { render :new }
        format.json { render json: @favorite.errors, status: :unprocessable_entity }

      end
    end
 end

Reference to http://api.rubyonrails.org/classes/ActionController/Parameters.html Don't use each, use permit or require directly Try this: http://api.rubyonrails.org/classes/ActionController/Parameters.html的引用不要使用每个,使用许可或直接要求试试看:

params.permit(profiles: {favorites: [:name, :title, :company, :location, :profile, :notes]})
#or :
params.permit(profiles: [{favorites: [:name, :title, :company, :location, :profile, :notes]}])
#=>{:profiles=>{:favorites=>{:name=>"Jon Doe", :title=>"Provider", :company=>"Acme", :location=>"Dubai", :profile=>"Group A", :notes=>""}}}

or : 要么 :

params.require(:profiles).permit( favorites: [:name, :title, :company, :location, :profile, :notes])
#=>{:favorites=>{:name=>"Jon Doe", :title=>"Provider", :company=>"Acme", :location=>"Dubai", :profile=>"Group A", :notes=>""}}

UPDATE 更新

According to OP's modification of the view, the favorite_params should be: 根据OP对视图的修改, favorite_params应该是:

params.require(:favorite)

Then in the create action use each to create every member of the array, becase check_box pass string as value, we have to eval the string into hash again. 然后在create操作中,使用each来创建数组的每个成员,如果check_box将字符串作为值传递,我们必须再次将该字符串评估为hash。

favorite_params.each do |fp|
  f=Favorite.new(eval(fp))
  f.user_id = current_user.id
  f.save
end

But use eval to transfer the params is not safe. 但是使用eval传递参数是不安全的。 I suggest you to modify your view to: 我建议您将视图修改为:

<%= form_tag favorites_path do %>
  <%= @results.length %>
  <% @results.each do |key,value| %>
    <tr>
      <td><%= value['name'] %></td>
      <td><%= value['title'] %></td>
      <td><%= value['company'] %></td>
      <td><%= value['location'] %></td>
      <td><%= link_to 'Profile', value['profile'],:target => "_blank"%></td>
      <td><%= check_box_tag "favorites[#{value['name']}][checked]", 'checked',true %>
          <%= hidden_field_tag "favorites[#{value['name']}][name]" , value['name'] %>
          <%= hidden_field_tag "favorites[#{value['name']}][title]" , value['title'] %>
          <%= hidden_field_tag "favorites[#{value['name']}][company]" , value['company'] %>
          <%= hidden_field_tag "favorites[#{value['name']}][location]" , value['location'] %>
          <%= hidden_field_tag "favorites[#{value['name']}][profile]" , value['profile'] %>
          <%= hidden_field_tag "favorites[#{value['name']}][note]" , "" %>
      </td>
    </tr>
  <% end %>
  <%= submit_tag "Add to Favorites", name: 'add', class: 'btn btn-primary' %>
  <%= submit_tag "Block Profiles", name: 'block', class: 'btn btn-danger' %>
<% end %>

From this view, you may have params like this: 从这个角度来看,您可能有如下的参数:

{:favorites=>{
  "Jon Doe" => {:checked => "checked", :name=>"Jon Doe", :title=>"Provider", :company=>"Acme", :location=>"Dubai", :profile=>"Group A", :notes=>""},
  "Alberto" => {:name=>"Alberto", :title=>"DS", :company=>"Dufrain", :location=>"chester", :profile=>"", :notes=>""}
  }
}

Then change your favorite_params to : 然后将您的favorite_params更改为:

params.require(:favorites).select{|k,v| v[:checked]}.map{|k,v| v.except(:checked)}

Use select to get all checked members, and except the checked hash key that generated by check_box,so you could get an array of hashes like: 使用select来获取所有选中的成员,以及由check_box生成的checked哈希键,因此您可以得到一个哈希数组,例如:

[{"name"=>"Jon Doe", "title"=>"Provider", "company"=>"Acme", "location"=>"Dubai", "profile"=>"Group A", "notes"=>""}]

Then you could use favorite_params safely without eval. 然后,您可以安全地使用favorite_params而不进行评估。

But on my point, your requiement is so similar as Mark V's question . 但就我的观点而言,您的要求与马克五世的问题如此相似。 So you can study using accepts_nested_attributes_for to simplify your code. 因此,您可以使用accepts_nested_attributes_for进行研究以简化代码。

i am on the way home so have to use my phone to type a new answer. 我在回家的路上,所以必须使用手机输入新答案。 my spell may wrong. 我的咒语可能错了。

as you see in your console. 如您在控制台中看到的。 you should get the favorites array use require only. 您应该只获得收藏夹数组使用要求。

params.require(:favorite)

then in your create action use each to create every member of the array. 然后在您的create动作中,使用each来创建数组的每个成员。

favorite_params.each do |fp|
  f=Favorite.new(fp)
  f.user_id =
  f.save
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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