我遇到以下情况的问题:
我的用户通过生成列表的关键字进行搜索。用户有2个操作要么将它们添加到收藏夹表,要么使用复选框阻止它们。
我遇到的问题是,当用户点击“添加到收藏夹”时,表单会将哈希列表传递给我的强参数方法,但我无法正确传递它。
我认为问题在于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>
这是我的strong_params方法的样子:
def favorite_params
params[:profiles].each do |e|
params.require(e).permit(:name, :title, :company, :location, :profile, :notes)
end
end
有什么想法吗?
更新
我可以将params传递给:
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
答案 0 :(得分:2)
参考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=>""}}}
或:
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=>""}}
<强>更新强>
根据OP对视图的修改,favorite_params
应为:
params.require(:favorite)
然后在create action中使用each来创建数组的每个成员,因为check_box将字符串作为值传递,我们必须再次将字符串eval为hash。
favorite_params.each do |fp|
f=Favorite.new(eval(fp))
f.user_id = current_user.id
f.save
end
但是使用eval转移params是不安全的。我建议你修改你的观点:
<%= 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 %>
从这个角度来看,你可能有这样的参数:
{: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=>""}
}
}
然后将favorite_params
更改为:
params.require(:favorites).select{|k,v| v[:checked]}.map{|k,v| v.except(:checked)}
使用select获取所有已检查的成员,并且check_box生成的checked
哈希键除外,这样您就可以得到一个哈希数组,如:
[{"name"=>"Jon Doe", "title"=>"Provider", "company"=>"Acme", "location"=>"Dubai", "profile"=>"Group A", "notes"=>""}]
然后你可以安全地使用favorite_params
而不用eval。
但就我而言,你的要求与Mark V's question非常相似。因此,您可以使用accepts_nested_attributes_for
进行学习以简化代码。
答案 1 :(得分:1)
我正在回家的路上,所以必须用我的手机输入新的答案。我的咒语可能不对。
正如您在控制台中看到的那样。你应该只获得收藏夹阵列使用。params.require(:favorite)
然后在你的创建动作中使用each来创建数组的每个成员。
favorite_params.each do |fp|
f=Favorite.new(fp)
f.user_id =
f.save
end