尝试update_attributes时,堆栈级别太深,没有更改

时间:2014-05-26 23:08:16

标签: ruby-on-rails nested-attributes

这种相当复杂的形式可以正常工作,如果有#34;书籍"更改,但在提交params而数据没有变化时会抛出一个不可能调试的stack level too deep错误。有什么想法吗?我已经评论出所有模型中的每个验证和回调都无济于事。

查看:

  = semantic_form_for(@work, :method => :put, :html => {:class => "form-horizontal"}) do |f|
       # some code
            = f.semantic_fields_for(:workcontacts, wc) do |ff|           
            #...
    = f.semantic_fields_for(:books, @book) do |gg|              
      = gg.input :contributor_statement, :input_html => {:class => 'wysihtml5'}

控制器:

  def update
    @work     = Work.find(params[:id])
      respond_to do |format|        
        begin
          if @work.update_attributes(params[:work])
          flash[:success] = "#{@work.title} #{t(:global_save)}"
          format.html { redirect_to :back, :work => @work.id }
          format.json { respond_with_bip(@work) }
        else
          format.html { 
            redirect_to :back, :work => @work.id
            flash[:failure] = "#{@work.errors.full_messages.join(', ')}"
          }
          format.json { respond_with_bip(@work) }
        end
        rescue SystemStackError
          puts $!
          puts caller[0..100]
        end
      end
  end

2 个答案:

答案 0 :(得分:1)

Stack Level Too Deep基本上意味着您的应用中某处有infiniterecursiveloop

-

<强>修正

您的代码似乎有点不合常规,所以我已经为您重构了它:

  def update
    @work = Work.find(params[:id])
      respond_to do |format|        
          if @work.update(work_params)
              format.html {
                  flash[:success] = "#{@work.title} #{t(:global_save)}"
                  redirect_to :back, :work => @work.id
              }
              format.json { respond_with_bip(@work) }
          else
              format.html { 
                 redirect_to :back, :work => @work.id
                 flash[:failure] = "#{@work.errors.full_messages.join(', ')}"
               }
               format.json { respond_with_bip(@work) }
           end
      end
  end

  private

  def work_params
      params.require(:work).permit(:x, :y, :z)
  end

在我看来,这段代码应该适合你。不过,我建议您发布model模型的Work代码 - 如果您使用after_create回调,通常会stack level too deep再次保存(因此绕圈)

答案 1 :(得分:1)

对此感到抱歉,因为它不会帮助灵魂,但是为了完整性而发布解决方案。

工作

has_many :books              , :inverse_of => :work

一本书

  belongs_to :work         , :inverse_of => :books, :touch => :child_updated_at, counter_cache: true

在Book模型中我有

  accepts_nested_attributes_for :work

哪个是罪魁祸首。