我正在尝试创建一篇文章。
class Article < ActiveRecord::Base
belongs_to :article_skill
attr_accessible :articles_skill_attributes
accepts_nested_attributes_for :articles_skill
end
class ArticlesSkill < ActiveRecord::Base
attr_accessible :description, :name
has_many :articles
end
这是article/new.html.erb
<%= article_form.fields_for :articles_skill, @article.articles_skill do |b|%>
<label class="medium"><span class="red">*</span> Skill</label>
<%= b.select :id, options_for_select(ArticlesSkill.all.collect{|m| [m.name, m.id]}) %>
<%end%>
此处article_form
是@article
表单对象的构建器。
如果我尝试保存@article
对象,则显示此错误。
Couldn't find ArticlesSkill with ID=1 for Article with ID=
答案 0 :(得分:6)
我几天来一直在努力解决这个问题。做了很多搜索..它转到了rails控制台并通过抛出异常进行搜索,而不是取得任何进展。
在这个问题上查看这个答案,了解它为什么会发生,以及可能的解决方法。 Use rails nested model to *create* outer object and simultaneously *edit* existing nested object?
请注意,使用此处提供的第一个选项会创建一个安全漏洞,如http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2010-3933
中所述答案 1 :(得分:4)
fields_for
来电中的第二个参数似乎没必要。当articles_skill
到达该参数时,ActiveRecord正在对@article
的关联进行查找,但由于@article
是新的并且尚未保存,因此它没有ID并触发错误
<%= article_form.fields_for :articles_skill do |b|%>
<label class="medium"><span class="red">*</span> Skill</label>
<%= b.select :id, options_for_select(ArticlesSkill.all.collect{|m| [m.name, m.id]}) %>
<% end %>
答案 2 :(得分:1)
我只能建议一种解决方法。它有效,但我不喜欢它 - 我想要一些开箱即用的解决方案。
我假设你有一个功能:
def articles_skill_params
params.require(:articles_skill).permit(:description,:name, article_attributes:[])结束
添加功能
def articles_skill_params2
params.require(:articles_skill).permit(:description, :name)
end
添加其他功能:
def set_article
article_id = articles_skill_params[:article_attributes][:id]
article = Article.find(article_id)
@articles_skill.articles << article
@articles_skill.save
end
更改您的ArticlesSkillController #create:
def create
@articles_skill = ArticlesSkill.new(articles_skill_params2)
set_article
respond_to do |format|
if @articles_skill.save
format.html { redirect_to @articles_skill, notice: 'Article skill was successfully created.' }
format.json { render :show, status: :created, location: @articles_skill }
else
format.html { render :new }
format.json { render json: @articles_skill.errors, status: :unprocessable_entity }
end
end
end
如您所见,我们只是从父对象创建中排除嵌套属性(从而消除错误),然后在以后手动添加它们。
答案 3 :(得分:0)
如果您只是希望人们能够选择现有技能,则根本不需要嵌套属性(这对于您可能希望人们能够从创建文章的同一表单创建文章技能时非常有用)。您只想将article_skill_id
设置为现有值,这样就可以执行
<%= form_for(@article) do |f| %>
...
<label class="medium"><span class="red">*</span> Skill</label>
<%= f.select :article_skill_id, ArticlesSkill.all.collect{|m| [m.name, m.id]}) %>
<% end %>