Rails回调以更新另一个模型属性

时间:2018-03-21 14:09:57

标签: ruby-on-rails

我在here之前问了同样的问题,但可能不太清楚。

我有一个模型用户,列vote_weightcurrent_vote_weight

每个用户可以临时将投票权重分配给另一个用户。为实现此目的,我创建了一个模型VoteWeightAssignment,其中包含sender_idreceiver_idtemp_vote_weight列。 temp_vote_weight是每次从用户发送到另一个用户的投票权重。

VoteWeightAssignment模型

belongs_to :sender, foreign_key: 'sender_id', class_name: 'User'
belongs_to :receiver, foreign_key: 'receiver_id', class_name: 'User'

然后在我的users / show上,我显示已登录的用户发送和接收的投票权重(current_user)。要在我的用户控制器显示操作上执行此操作,我有:

@vote_weight_assignments_sent = VoteWeightAssignment.where(sender_id: current_user.id)
@vote_weight_assignments_received = VoteWeightAssignment.where(receiver_id: current_user.id)

@total_vote_weight_received = @vote_weight_assignments_received.to_a.sum(&:temp_vote_weight)
@total_vote_weight_sent = @vote_weight_assignments_sent.to_a.sum(&:temp_vote_weight)
@total_vote_weight = current_user.vote_weight + @total_vote_weight_received - @total_vote_weight_sent

这很好用。

现在我想要实现的是每次创建或销毁投票权重分配时(我不允许对其进行编辑),对于表用户,应使用vote_weight +值为发件人和收件人更新列current_vote_weight收到的投票权数之和 - 发送的投票权重之和。

示例:

用户1有10个投票权重

用户2有5个vote_weight

用户3有8个vote_weight

所以我的表用户列id,vote_weight,current_vote_weight列应为:

1,10,10

2,5,5-

3,8,8

然后:

用户1向用户2发送3投票权重

用户3向用户2发送4个投票权重

此表格后,包含sender_id,receiver_id,temp_vote_weight列的vote_weight_assignments将为:

1,2,3

3,2,4

而用户表应该是:

1,10,7(因为他发送了3张投票权)

2,5,12(因为他收到了7张投票权)

3,8,4(因为他发出4票重量)

我知道我必须创建一个模型方法和一个回调。该方法应该在用户模型上,并通过VoteWeightAssignment模型上的回调调用它。但我不确定如何实施它。

有人能指出我正确的方向吗?

更新

我添加了gem counter colture并添加到用户表2列:received_vote_weight和sent_vote_weight,这些列正在使用为每个用户发送和接收的总投票权重进行更新。

然后我在user.rb上创建了

  after_commit :set_sender_current_vote_weight
  after_commit :set_receiver_current_vote_weight

  counter_culture :receiver, column_name: 'received_vote_weight', delta_column: 'temp_vote_weight'
  counter_culture :sender, column_name: 'sent_vote_weight', delta_column: 'temp_vote_weight'


  def receiver_current_vote_weight
    (receiver.vote_weight + receiver.received_vote_weight - receiver.sent_vote_weight)

  end

  def set_receiver_current_vote_weight
    receiver.update_attributes(current_vote_weight: receiver_current_vote_weight)
  end


  def sender_current_vote_weight
    (sender.vote_weight + sender.received_vote_weight - sender.sent_vote_weight)
  end

  def set_sender_current_vote_weight
    sender.update_attributes(current_vote_weight: sender_current_vote_weight)
  end

我遇到的最后一个问题是现在它更新了current_vote_weight列,但它不包括计算中的最后一条记录。

1 个答案:

答案 0 :(得分:0)

我这样解决了。

添加了gem counter-colture,生成了一个迁移,用于在users table创建了columnsreceived_vote_weight和sent_vote_weight。

已添加至vote_weight_assignment.rb

counter_culture :receiver, column_name: 'received_vote_weight', delta_column: 'temp_vote_weight'
counter_culture :sender, column_name: 'sent_vote_weight', delta_column: 'temp_vote_weight'

添加到user.rb

after_find :set_current_vote_weight

def current_vote_weight
  self.vote_weight - self.sent_vote_weight + self.received_vote_weight
end

def set_current_vote_weight
  self.update_attributes(current_vote_weight: current_vote_weight)
end

现在它按预期工作,但回调after_find过于频繁地更新用户表。但我尝试了VoteWeightAssignment模型的所有回调,他们是肯定更新,但他们没有计算最后一个条目。也许我会发布另一个问题来解决这个问题。