【问题标题】:Couldn't find ArticlesSkill with ID=1 for Article with ID=对于 ID= 的文章,找不到 ID=1 的 ArticlesSkill
【发布时间】:2023-03-16 05:15:02
【问题描述】:

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

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=

【问题讨论】:

  • 你试过什么?控制器代码?请求的前两行(发送参数)?

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


【解决方案1】:

这几天我一直在努力解决这个问题。做了很多搜索.. 它需要转到 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 中所述

【讨论】:

    【解决方案2】:

    fields_for 调用中的第二个参数似乎没有必要。 ActiveRecord 在到达该参数时正在对 @article 的关联 articles_skill 执行查找,但由于 @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 %>
    

    【讨论】:

      【解决方案3】:

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

      我假设你有一个函数:

      定义文章_技能参数
      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
      

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

      【讨论】:

        【解决方案4】:

        如果您只是希望人们能够选择您根本不需要嵌套属性的现有技能(当您可能希望人们能够从创建文章的相同表单中创建文章技能时,这很有用)。您只想将 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 %>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多