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

Ruby on rails 在Rails4中使用复选框和强参数创建多个条目,ruby-on-rails,ruby-on-rails-4,hash,strong-parameters,Ruby On Rails,Ruby On Rails 4,Hash,Strong Parameters,我在以下场景中遇到问题: 我的用户通过关键字进行搜索,从而生成一个列表。用户有两个操作:将它们添加到收藏夹表或使用复选框阻止它们 我遇到的问题是,当用户单击“添加到收藏夹”时,表单将哈希列表传递给我的strong params方法,而我无法正确地传递它 我认为问题在于强_参数所需的散列在另一个散列中 此外,我不知道当用户单击“块”时如何将相同的哈希传递给BlockController 这是错误消息: param is missing or the value is empty: {:favori

我在以下场景中遇到问题:

我的用户通过关键字进行搜索,从而生成一个列表。用户有两个操作:将它们添加到收藏夹表或使用复选框阻止它们

我遇到的问题是,当用户单击“添加到收藏夹”时,表单将哈希列表传递给我的strong params方法,而我无法正确地传递它

我认为问题在于强_参数所需的散列在另一个散列中

此外,我不知道当用户单击“块”时如何将相同的哈希传递给BlockController

这是错误消息:

param is missing or the value is empty: {:favorites=>{:name=>"Jon Doe", :title=>"Provider", :company=>"Acme", :location=>"Dubai", :profile=>"Group A", :notes=>""}}
我的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>
有什么想法吗

更新:

我可以通过以下方式传递参数:

def favorite_params
      params.permit(:commit,favorite:[])
    end
创建方法:

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
提及 不要使用每一个,使用许可证或直接要求 试试这个:

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=>""}}}
或:

更新

根据OP对视图的修改,
收藏夹参数应为:

params.require(:favorite)
然后在create操作中,使用each创建数组的每个成员,因为选中了pass string as value复选框,我们必须再次将字符串求值为hash

favorite_params.each do |fp|
  f=Favorite.new(eval(fp))
  f.user_id = current_user.id
  f.save
end
但是使用eval传输参数是不安全的。我建议您将视图修改为:

<%= 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 %>
然后将您的
收藏夹参数更改为:

params.require(:favorites).select{|k,v| v[:checked]}.map{|k,v| v.except(:checked)}
使用select获取所有选中的成员,除了复选框生成的
选中的
散列键之外,因此可以获得如下散列数组:

[{"name"=>"Jon Doe", "title"=>"Provider", "company"=>"Acme", "location"=>"Dubai", "profile"=>"Group A", "notes"=>""}]
然后您可以安全地使用
收藏夹参数
,而无需评估

但就我而言,你的要求与我的要求非常相似。因此,您可以研究使用
接受嵌套的属性来简化代码。

参考 不要使用每一个,使用许可证或直接要求 试试这个:

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=>""}}}
或:

更新

根据OP对视图的修改,
收藏夹参数应为:

params.require(:favorite)
然后在create操作中,使用each创建数组的每个成员,因为选中了pass string as value复选框,我们必须再次将字符串求值为hash

favorite_params.each do |fp|
  f=Favorite.new(eval(fp))
  f.user_id = current_user.id
  f.save
end
但是使用eval传输参数是不安全的。我建议您将视图修改为:

<%= 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 %>
然后将您的
收藏夹参数更改为:

params.require(:favorites).select{|k,v| v[:checked]}.map{|k,v| v.except(:checked)}
使用select获取所有选中的成员,除了复选框生成的
选中的
散列键之外,因此可以获得如下散列数组:

[{"name"=>"Jon Doe", "title"=>"Provider", "company"=>"Acme", "location"=>"Dubai", "profile"=>"Group A", "notes"=>""}]
然后您可以安全地使用
收藏夹参数
,而无需评估

但就我而言,你的要求与我的要求非常相似。因此,您可以研究使用
接受嵌套的属性来简化代码。

参考 不要使用每一个,使用许可证或直接要求 试试这个:

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=>""}}}
或:

更新

根据OP对视图的修改,
收藏夹参数应为:

params.require(:favorite)
然后在create操作中,使用each创建数组的每个成员,因为选中了pass string as value复选框,我们必须再次将字符串求值为hash

favorite_params.each do |fp|
  f=Favorite.new(eval(fp))
  f.user_id = current_user.id
  f.save
end
但是使用eval传输参数是不安全的。我建议您将视图修改为:

<%= 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 %>
然后将您的
收藏夹参数更改为:

params.require(:favorites).select{|k,v| v[:checked]}.map{|k,v| v.except(:checked)}
使用select获取所有选中的成员,除了复选框生成的
选中的
散列键之外,因此可以获得如下散列数组:

[{"name"=>"Jon Doe", "title"=>"Provider", "company"=>"Acme", "location"=>"Dubai", "profile"=>"Group A", "notes"=>""}]
然后您可以安全地使用
收藏夹参数
,而无需评估

但就我而言,你的要求与我的要求非常相似。因此,您可以研究使用
接受嵌套的属性来简化代码。

参考 不要使用每一个,使用许可证或直接要求 试试这个:

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=>""}}}
或:

更新

根据OP对视图的修改,
收藏夹参数应为:

params.require(:favorite)
然后在create操作中,使用each创建数组的每个成员,因为选中了pass string as value复选框,我们必须再次将字符串求值为hash

favorite_params.each do |fp|
  f=Favorite.new(eval(fp))
  f.user_id = current_user.id
  f.save
end
但是使用eval传输参数是不安全的。我建议您将视图修改为:

<%= 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 %>
然后将您的
收藏夹参数更改为:

params.require(:favorites).select{|k,v| v[:checked]}.map{|k,v| v.except(:checked)}
使用select获取所有选中的成员,除了复选框生成的
选中的
散列键之外,因此可以获得如下散列数组:

[{"name"=>"Jon Doe", "title"=>"Provider", "company"=>"Acme", "location"=>"Dubai", "profile"=>"Group A", "notes"=>""}]
然后您可以安全地使用
收藏夹参数
,而无需评估


但就我而言,你的要求与我的要求非常相似。因此,您可以学习使用
接受嵌套的属性来简化代码。

我正在回家的路上,因此必须使用手机键入新答案。我的拼写可能错了

正如您在控制台中看到的。您应该只使用所需的收藏夹数组

params.require(:favorite)
然后在创建操作中使用each创建数组的每个成员

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

我在回家的路上,所以必须用我的手机键入新的答案。我的拼写可能错了

正如您在控制台中看到的。您应该只使用所需的收藏夹数组

params.require(:favorite)
然后在创建操作中使用each创建数组的每个成员

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

我在回家的路上,所以必须用我的手机键入新的答案。我的拼写可能错了

正如您在控制台中看到的。您应该只使用所需的收藏夹数组

params.require(:favorite)
然后在创建操作中使用each创建数组的每个成员

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

我在回家的路上,所以必须用我的手机键入新的答案。我的拼写可能错了

正如您在控制台中看到的。您应该只使用所需的收藏夹数组

params.require(:favorite)
然后在创建操作中使用each创建数组的每个成员

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

谢谢,但不起作用-它通过了强参数,但在def create中崩溃,出现以下错误:``{“profiles”=>[]}未经允许的参数:utf8,Authentity\u token,add``您可以发布您的create方法的代码吗。我更新了答案,以显示返回的强参数、require和permit返回方式不同可能导致create方法出错的结果。我可以使用
params.permit(:commit,favorite:[])传递参数,但不知道create将如何处理