简体   繁体   中英

Ruby on Rails - SystemStackError (stack level too deep) when doing after_update

In my Post model, when a post is updated, I want to do a before_update to update one of my attributes.

class Post < ActiveRecord::Base

  before_update :navid_tadding_atgs
  private
    def navid_tadding_atgs
      self.update_attributes(added_by_me: 'yes')
    end

This causes this error:

Completed 500 Internal Server Error in 3539ms (ActiveRecord: 25.6ms)

SystemStackError (stack level too deep):
  app/models/post.rb:167:in `navid_tadding_atgs'
  app/models/post.rb:167:in `navid_tadding_atgs'
  //.....
  app/controllers/posts_controller.rb:70:in `block in update'
  app/controllers/posts_controller.rb:69:in `update'

This is my PostController#Update action:

class PostsController < ApplicationController
  def update
    authorize @post
    respond_to do |format|
      if @post.update(post_params)
        format.html { redirect_to @post, notice: 'Post was successfully updated.' }
        format.json { respond_with_bip(@post) }
      else
        format.html { render :edit }
        format.json { respond_with_bip(@post) }
      end
    end
  end

    def post_params
      params.require(:post).permit(:post_type, :category, :post_identity, :tags, :added_by_me)
    end

PS: format.json { respond_with_bip(@post) } is for best_in_place gem & I have even tested without and got the same error

I already do other after_update & before_update in my other models & after_create in same Post model without any issue.

I don't understand why I would get this error. Any help is appreciated.

I am using Rails 4.2.4 & ruby 2.2.1p85 & I have tried with after_update with same error

It's because you have again call the update method in your private method. That means the application will go in infinite loop and into dead conditions.

You just need to set the attribute into the self no need to call the update method inside the private method.

class Post < ActiveRecord::Base

  before_update :navid_tadding_atgs

  private

  def navid_tadding_atgs
    self.added_by_me = 'yes'
  end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM