【问题标题】:Stack level too deep because recursion堆栈级别太深,因为递归
【发布时间】:2015-09-08 00:56:16
【问题描述】:

我有一个名为 Tweet 的模型。 Tweet 模型的列是:

-id  
-content  
-user_id  
-picture  
-group  
-original_tweet_id    

每条推文都可以有一个或多个转发。这种关系在original_tweet_id 的帮助下发生。所有推文都有 original_tweet_id nil ,而转推包含推文的 id。
当一条推文被删除时,转发的推文也必须被删除。我尝试在以下函数中执行此操作:

   def destroy_retweets(tweet)
    retweets = Tweet.where(original_tweet_id: @tweet.id)
    if retweets.any?
      retweets.each do |retweet|
        destroy_retweets(retweet)
        retweet.destroy
      end
    end
  end

如果我不添加"destroy_retweets(retweet)" 行,那么一切正常,它会删除推文的转推。问题是当我转推转推时,这就是为什么我必须添加该行(所以我删除所有转推的转推等等)。由于这对我如何使其工作或替代方法没有任何想法(除了不允许用户转发转发)。

建议这是 tweet.rb 模型:

class Tweet < ActiveRecord::Base
  belongs_to :user
  has_many :hashrelations, dependent: :destroy
  has_many :hashtags, through: :hashrelations
  default_scope -> { order(created_at: :desc) }
  mount_uploader :picture, PictureUploader
  validates :user_id, presence: true
  validates :content, presence: true, length: { maximum: 140 }
  validate  :picture_size


  private

    # Validates the size of an uploaded picture.
    def picture_size
      if picture.size > 5.megabytes
        errors.add(:picture, "o poza nu poate sa aiba o marime mai mare de 5MB")
      end
    end

end

这是最先调用destroy_retweets的方法:

  def destroy
    destroy_retweets(@tweet)
    @tweet.destroy
    redirect_to request.referrer || root_url
  end

【问题讨论】:

  • 为什么要使用实例变量?由于每个方法调用都将覆盖@retweets,因此这将让事情变得更糟。这可能不是根本原因,但我觉得它很可疑。
  • 我将@retweets 更改为转推,但堆栈级别仍然太深:P
  • 我解决了我在 where 子句中写 @tweet.id 而不是 tweet.id 的问题,我的上帝真傻。无论如何,这是一个很好的问题,你非常喜欢 Dave Newton 和 Avdept :) 我从你们俩那里学到了一些东西
  • @DaveNewton 介意发布答案以便我检查吗? :) 这个问题已经解决了,其他问题可能需要更多人关注。
  • 您可以回答自己的问题并接受它;我的评论并没有真正帮助:)

标签: ruby-on-rails ruby ruby-on-rails-4 twitter


【解决方案1】:

如果你正确地表达了关系,ActiveRecord 会为你做的

class Tweet
  belongs_to :original_tweet, class_name: Tweet
  has_many :retweets, class_name: Tweet, dependent: :destroy, inverse_of :original_tweet

end

Tweet.last.destroy  # will now destroy dependents

【讨论】:

  • 非常感谢 :) 。但是这段代码是在我的 Rails 开始时编写的,我必须进行很多更改才能做到这一点。然而,这就是它应该做的!这是毫无疑问的最佳解决方案。
【解决方案2】:

即使collection emtpy,它仍然返回true。 代替 if @retweets,使用if @retrweets.any?

为什么? 因为where 查询返回ActiveRecord::Relation 对象,并且您检查对象是否存在,而不是是否存在任何记录。

【讨论】:

  • 是的,但它也不会遍历空集合。
  • 你的模型中有回调吗?你的推文模型关系是什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-04
  • 2013-10-05
  • 2011-11-17
  • 2012-07-24
  • 2016-08-02
  • 1970-01-01
相关资源
最近更新 更多