在初始保存对象之前保存

时间:2014-05-01 14:38:10

标签: ruby-on-rails

创建conversation后,我希望该会话自动跟随creator

class Conversation < ActiveRecord::Base
    belongs_to :user
    has_many :followers
    has_many :users, through: :followers

    alias_method :user, :creator

    before_create { add_follower(self.creator) }

    def add_follower(user)

        unless self.followers.exists?(user_id: user.id)
            self.transaction do
                self.update_attributes(follower_count: follower_count + 1)
                self.followers.create(user_id: user.id)
            end
        end
    end

end

但是,当用户尝试创建对话时,我会收到stack level too deep 。我正在创建一个无限循环,我认为这是因为before_create调用触发了self.update_attributes回调。

那么我应该如何在创建之前有效地更新属性以阻止这种循环发生呢?

1 个答案:

答案 0 :(得分:1)

选项1(首选)

将您的专栏follower_count重命名为followers_count并添加:

class Follower
  belongs_to :user, counter_cache: true
  # you can avoid renaming the column with "counter_cache: :follower_count"
  # rest of your code
end

Rails将为您处理更新followers_count

然后将add_follower方法更改为:

def add_follower(user)
  return if followers.exists?(user_id: user.id)
  followers.build(user_id: user.id)
end

选项2

如果您不想使用counter_cache,请使用update_column(:follower_count, follower_count + 1)update_column不会触发任何验证或回调。

选项3

最后你不需要保存任何东西,只需更新值,它们将在回调结束时保存:

def add_follower(user)
  return if followers.exists?(user_id: user.id)
  followers.build(user_id: user.id)
  self.follower_count = follower_count + 1
end