对于ID =的文章,找不到ID = 1的ArticlesSkill

时间:2013-05-06 13:22:43

标签: ruby-on-rails nested-attributes form-for

我正在尝试创建一篇文章。

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=

4 个答案:

答案 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 %>