4

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

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

4 回答 4

7

几天来我一直在努力解决这个问题。做了很多搜索.. 它需要去 Rails 控制台并通过抛出的异常进行搜索,而不是在这方面取得任何进展。

查看这个问题的答案,了解为什么会发生这种情况,以及可能的解决方法。 使用rails嵌套模型*创建*外部对象并同时*编辑*现有嵌套对象?

请注意,使用此处提供的第一个选项会创建一个安全漏洞,如http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2010-3933中所述

于 2013-06-26T10:06:36.050 回答
4

您调用中的第二个参数fields_for似乎没有必要。ActiveRecord 正在对关联执行查找,以articles_skill了解@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 %>
于 2013-05-06T13:32:10.393 回答
1

我只能建议一种解决方法。它有效,但我不喜欢它 - 我想要一些开箱即用的解决方案。

我假设你有一个功能:

def
article_skill_params params.require(:articles_skill).permit(:description, :name, article_attributes: []) end

添加功能

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

如您所见,我们只是从父对象创建中排除了嵌套属性(从而消除了错误),然后稍后手动添加它们。

于 2016-07-19T13:06:20.563 回答
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 %>
于 2013-05-06T14:09:29.923 回答