2015-06-22 3 views
1

У меня есть модель с именем Tweet. Колонки модели Tweet:Уровень стека слишком глубокий, потому что рекурсия

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

Каждый твит может иметь один или несколько ретвитов. Отношение происходит с помощью original_tweet_id. Все твиты имеют original_tweet_id ноль, в то время как ретвиты содержат идентификатор Tweet.
Когда твит удаляется, необходимо также удалить ретвиты. Я пытаюсь сделать это в следующей функции:

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 
+1

Зачем использовать переменный экземпляр? Это будет шланги, потому что каждый вызов метода будет переписывать '@ retweets'. Это не может быть основной причиной, но это кажется мне подозрительным. –

+0

Я изменил @retweets на ретвиты, и я все еще получаю уровень стека слишком глубоким: P –

+0

Я решил проблему, которую написал @ tweet.id вместо tweet.id в том месте, где мой бог глупо меня. Это был хороший вопрос, так что вы очень сильно Дэйв Ньютон и Авдект :) Я узнал что-то от вас обоих –

ответ

2

Если выразить свое отношение правильно, 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 
+0

Большое спасибо :). Но этот код был написан в начале Rails, и мне пришлось бы многое изменить для этого. Однако так и должно быть! Это лучшее решение без вопросов. –

1

Даже если коллекция пуста, она возвращает истину в любом случае. Вместо if @retweetsif @retrweets.any?

Почему? Поскольку запрос where возвращает объект ActiveRecord::Relation, и вы проверяете, присутствует ли объект, а не какие-либо записи.

+0

Правда, но он также не будет перебирать пустую коллекцию. –

+0

Хороший улов. Но я все еще получаю это ... –

+0

Есть ли у вас обратные вызовы в вашей модели? И каковы ваши отношения с моделью твиттов? – Avdept

Смежные вопросы