我似乎无法通过控制器或可能通过视图保存/更新嵌套模型属性。我看到一个错误“未经许可的参数:(取决于我选择更新的模型在这里,例如语言)”。经过几天的研究,我感到失败;感谢您的帮助或指导。
我有一个页面,每个部分都有许多表单,一个编辑模式和一个删除按钮。 一切都在索引页面完成。
Started PATCH "/user_skills/1" for 127.0.0.1 at 2014-12-29 19:21:05 -0600
Processing by UserSkillsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"ArM2OqBIlsM+Vx7YHRq8NtExBp/Z/FmxpRO8xEX8Y9w=", "user_skill"=>{"language"=>{"title"=>"Ruby", "description"=>"A dynamic, elegant and productive object oriented programming language."}}, "button"=>"", "id"=>"1"}
UserSkill Load (0.1ms) SELECT "user_skills".* FROM "user_skills" WHERE "user_skills"."id" = ? LIMIT 1 [["id", 1]]
Unpermitted parameters: language
(0.1ms) begin transaction
(0.0ms) commit transaction
Redirected to http://localhost:3000/user_skills.1
Completed 302 Found in 4ms (ActiveRecord: 0.3ms)
所以我有一个名为user_skill.rb的模型,它应该更新其他三个不同的模型。
# == Schema Information
#
# Table name: user_skills
#
# id :integer not null, primary key
#
class UserSkill < ActiveRecord::Base
has_many :languages
has_many :frameworks
has_many :tools
accepts_nested_attributes_for :languages, :frameworks, :tools, allow_destroy: true
end
我的一个控制器
class UserSkillsController < ApplicationController
def index
load_user
end
def update
load_user
build_skill
save_skill or render 'user_skills'
end
private
def userskill_scoped
UserSkill.all
end
def build_skill
@skill ||= userskill_scoped.build
@skill.attributes = skill_params
end
def load_user
@skill ||= UserSkill.find(1)
end
def skill_params
skill_params = params
skill_params ? skill_params.require(:user_skill).permit(:id, languages_attributes: [:id, :title, :description, :user_skill_id, :_destroy], frameworks_attributes: [:id, :title, :description, :user_skill_id, :_destroy], tools_attributes: [:id, :title, :description, :user_skill_id, :_destroy]) : {}
end
def save_skill
notice = @skill.new_record? ? "User skill was successfully created" : "User skills was successfully updated"
if @skill.save
redirect_to user_skills_path(@skill), notice: notice
else
render 'user_skills'
end
end
这是我的表单,我删除了一些bootstrap div,以便它更容易阅读。工艺对象作为局部变量从集合传递到此表单;它代表记录的实际实例。 e.g
<Language id: 1, title: "Ruby", description: "A dynamic, elegant and productive object oriented ...", url: "http://www.ruby-lang.org", image: nil, created_at: "2014-12-19 02:35:10", updated_at: "2014-12-19 19:57:48", user_skill_id: 1>
irb(main):003:0>
我的表格:
<%= form_for @skill do |f| %>
<%= f.fields_for technology do |f| %>
<h4>Title:</h4>
<%= f.text_field :title, class: 'form-control', :required => true %>
<h4>Content:</h4>
<%= f.text_area :description, class: 'form-control content-text', :required => true %>
<% end %>
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal">Cancel</button>
<%= f.button 'Save', action: 'update', class: "btn btn-default btn-sm", data: {disable_with: "<i class='fa fa-spinner fa-spin'></i> Saving..."} %>
</div>
<% end %>
*更新,添加视图*
这些是我的观点,导致部分形式。 “user_skill#指数”
<% if notice %>
<div class="alert alert-success" role="alert">
<%= notice %>
</div>
<% end %>
<div>
<h1 class="title">My Tools</h1>
<p class="subtitle">Technologies I've worked with...</p>
<hr>
<h3>Programming Languages</h3>
<br>
<%= render partial: 'user_skills/partials/skills', locals: { a: "languages" } %>
<hr>
<h3>Frameworks</h3>
<br>
<%= render partial: 'user_skills/partials/skills', locals: { a: "frameworks" } %>
<hr>
<h3>Other</h3>
<br>
<%= render partial: 'user_skills/partials/skills', locals: { a: "tools" } %>
<br>
<% ["languages","frameworks","tools"].each do |skill| %>
<% @skill.send(skill).each do |technology| %>
<!-- Modal -->
<%= render 'user_skills/partials/modal', technology: technology %>
<% end %>
<% end %>
<br>
<br>
<br>
<br>
<br>
<br>
</div>
_skills partial
<% @skill.send(a).each do |technology| %>
<%= render 'user_skills/partials/skill_panels', :technology => technology %>
<!-- Modal -->
<%= render 'user_skills/partials/modal', :a => a, :technology => technology %>
<% end %>
_skills_panel
<div class="panel panel-default">
<div class="panel-heading">
<%= technology.title %>
</div>
<div class="panel-body">
<%= technology.description %>
</div>
<div class="panel-footer">
<div class="row">
<div class="col-xs-12">
<%= link_to technology.url, technology.url %>
<%= render 'user_skills/partials/edit_buttons', technology: technology %>
</div>
</div>
</div>
</div>
edit_button partial
<div class="col-xs-8 pull-right">
<div class="pull-right edit_skill">
<div class="btn-group" role="group" aria-label="...">
<button type="button" class="btn btn-default btn-xs" data-toggle="modal" data-target='#edit_modal<%= "_#{technology.title.gsub(' ','').gsub('.','_')}" %>'>Edit</button>
<%= button_to "Delete", @skill, method: :delete, data: { confirm: "Are you sure you want to delete?"}, class: "btn btn-default btn-xs pull-right" %>
</div>
</div>
</div>
模态部分
<div class="modal fade" id='edit_modal_<%= technology.title.gsub(' ','').gsub('.','_')%>' tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h3 class="modal-title" id="myModalLabel">Edit Skills</h3>
</div>
<div class="modal-body">
<%= render partial: 'form', locals: { technology: technology} %>
</div>
</div>
</div>
</div>
答案 0 :(得分:1)
您的输入与您的.reqire(...).permit(...)
完全不匹配。
你传入的参数如下:
user_skill: { ..., languages: { ... } }
虽然你预期的参数看起来像这样:
...require(:user_skill).permit(..., languages_attributes: ...
languages
和languages_attributes
之间的不匹配实际上非常重要。那些东西需要匹配或Rails抛出不匹配的参数。 _attributes
的缺失或存在与匹配参数名称中的任何其他字符集一样重要。
不匹配的原因是您的表单设置不正确。我无法分辨为什么,因为您没有在HTML中添加任何内容来指示languages
应该来自哪里。