我的应用中有通知系统。当用户转到其他用户的页面(用户/节目页面)时,通知计数减少,因为他/她可以看到公共聊天窗口。因此,例如,如果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
答案 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
确切的查询可能会因您的关联而有所不同,但同样,我们的想法是在与通知相同的数据库调用中加载收件人,从而消除潜在的竞争条件。