rails控制器动作+渲染bug

时间:2016-07-13 19:13:57

标签: ruby-on-rails model-view-controller model controller

我的应用中有通知系统。当用户转到其他用户的页面(用户/节目页面)时,通知计数减少,因为他/她可以看到公共聊天窗口。因此,例如,如果sby发短信给你,那么你有1个通知。当您进入发件人的展示页面时,您的通知会减少到0。

一切正常,但我想重构代码,因为它变得杂乱无章。

您可以在下面看到旧代码和新代码。旧代码工作正常,但新代码存在一个奇怪的问题。当我到达用户页面并打印出控制器显示操作或模板中的current_user.new_chat_notification属性时(我在标题中显示它以便它在每个页面上都可用)它显示1.在与此同时,如果我在控制台中打印出它显示的数字0.因此由于某种原因,数字在数据库中减少,但控制器操作和视图并未及时了解它。如果我转到另一页,则数字会降至零。因此,下一个控制器操作已经知道该数字已经减少并显示为0.我真的不明白旧代码和新代码之间的区别是什么导致这样的事情。

schema.rb

create_table "users", force: :cascade do |t|
  t.integer  "new_chat_notification",  default: 0
end

用户控制器

def show
  @user = User.find(params[:id])
  #FOLLOWING 3 LINES ARE PART OF THE UPDATE
  @conversation = Conversation.create_or_find_conversation(current_user.id, @user.id)
  @tasks = Task.uncompleted.between(current_user.id, @user.id).order("created_at DESC").includes(:assigner, :executor).paginate(page: params[:page], per_page: 14)
  @messages = @conversation.messages.includes(:user).order(created_at: :desc).limit(50).reverse
  current_user.decreasing_chat_notification_number(@user)
  respond_to do |format|
    format.html
    format.js { render template: "tasks/between.js.erb" }
  end
end

user.rb

#FOLLOWING 2 LINES ARE PART OF THE UPDATE
has_many :notifications, foreign_key: "recipient_id", dependent: :destroy
validates :new_chat_notification, numericality: { only_integer: true, greater_than_or_equal_to: 0 }

def decreasing_chat_notification_number(sender)
  notification = notifications.between_chat_recipient(sender).unchecked.first
  checking_and_decreasing_notification(notification) if notification.present?
end

def checking_and_decreasing_notification(notification)
  notification.check_notification
  if notification.notifiable_type == "Message"
    # decrease_new_chat_notifications --> OLD CODE THAT WORKING PROPERLY
    NotificationSender.new(notification).decrease_new_chat_notifications # --> NEW CODE NOT WORKING PROPERLY
    ....
  else
    ....
  end
end

def decrease_new_chat_notifications
  decrement!(:new_chat_notification) if new_chat_notification > 0
end

notification_sender.rb(新代码)

class NotificationSender
  attr_reader :notification, :recipient

  def initialize(notification)
    @notification = notification
    @recipient = notification.recipient
  end

  def decrease_new_chat_notifications
    recipient.decrement!(:new_chat_notification) if recipient.new_chat_notification > 0
  end
end

1 个答案:

答案 0 :(得分:1)

差异可能在于这一行:

@recipient = notification.recipient

可以从数据库加载收件人,重置状态。从您的代码中可以看出,在调用User之前decreasing_chat_notification_number模型中是否存在任何状态更改。

<强>更新

如果这实际上是问题的原因(目前只是一个不受支持的建议),您可以加载引用的收件人以及通知。这样,当您初始化NotificationSender时,它的状态不会意外地从数据库中更新。

代替notification = notifications.between_chat_recipient(sender).unchecked.first,试试这个:

notification = notifications.
    between_chat_recipient(sender).
    unchecked.
    includes(:recipient).
    first

确切的查询可能会因您的关联而有所不同,但同样,我们的想法是在与通知相同的数据库调用中加载收件人,从而消除潜在的竞争条件。