我的rails应用程序中的通知模型中有以下代码。
我想稍微重构一下。这肯定是错误的,并且检查对象是否存在然后用它做什么"部分。我想我可以使用try
,但我不知道它是如何工作的。可以告诉我如何做到这一点(使用try
或者是否有更好的方法)?
关于其余代码的其他任何意见?
#check and decrease chat notification that happens between 2 given users (since 1v1 chat notification number max limit is 1)
def self.decreasing_chat_notification_number(current_user, user)
if self.between_chat_recipient(current_user, user).unchecked.any?
notification = self.between_chat_recipient(current_user, user).unchecked.first
checking_and_decreasing_notification(notification)
end
end
#check and decrease all the task notifications that happens between 2 given users
def self.decreasing_task_notification_number(current_user, user)
if self.task.between_other_recipient(current_user, user).unchecked
self.task.between_other_recipient(current_user, user).unchecked.each do |notification|
checking_and_decreasing_notification(notification)
end
end
end
#check and decrease all the post notifications that happened on a given post
def self.decreeasing_post_notification_number(current_user, post)
if self.post.this_post_comments(current_user, post).unchecked
self.post.this_post_comments(current_user, post).unchecked.each do |notification|
checking_and_decreasing_notification(notification)
end
end
end
private
def check_notification #chat notification gets checked
if self.checked_at == nil
update_attributes(checked_at: Time.zone.now)
end
end
def checking_and_decreasing_notification(notification)
notification.check_notification
current_user.decrease_new_other_notifications
current_user.decreased_other_number_pusher
end
的范围:
scope :not_chat, -> { where.not(notifiable_type: "Message") }
scope :chat, -> { where(notifiable_type: "Message") }
scope :task, -> { where(notifiable_type: "Task") }
scope :post, -> { where(notifiable_type: "Post") }
scope :checked, -> { where.not(checked_at: nil) }
scope :unchecked, -> { where(checked_at: nil) }
scope :this_post_comments, -> (recipient_id, post_id) do
where("notifications.recipient_id = ? AND notifications.notifiable_id = ?", recipient_id, post_id)
end
scope :between_chat_recipient, -> (recipient_id, sender_id) do
where("notifications.recipient_id = ? AND notifications.sender_id = ? AND notifications.notifiable_type = ?", recipient_id, sender_id, "Message")
end
scope :between_other_recipient, -> (recipient_id, sender_id) do
where("notifications.recipient_id = ? AND notifications.sender_id = ?", recipient_id, sender_id)
end
更新:
在current_user上调用Everything作为实例方法而不是Notification.class_method。顺便说一句。用户表具有"new_chat_notification",default: 0
和"new_other_notification", default: 0
属性,用于计算当前通知的数量。
user.rb
#check and decrease chat notification that happens between 2 given users (max 1)
def decreasing_chat_notification_number(user)
notification = self.notifications.between_chat_recipient(user).unchecked.first
self.checking_and_decreasing_notification(notification) if notification.present?
end
#check and decrease task notifications that happens between 2 given users
def decreasing_task_notification_number(user)
self.notifications.task.between_other_recipient(user).unchecked.each do |notification|
self.checking_and_decreasing_notification(notification)
end
end
#check and decrease the post notification that belongs to a given post
def decreasing_post_notification_number(post_id)
self.notifications.this_post_comments(post_id).unchecked.each do |notification|
self.checking_and_decreasing_notification(notification)
end
end
def checking_and_decreasing_notification(notification)
notification.check_notification
if notification.notifiable_type == "Message"
self.decrease_new_chat_notifications
self.decreased_chat_number_pusher
else
self.decrease_new_other_notifications
self.decreased_other_number_pusher
end
end
def decrease_new_chat_notifications
decrement!(:new_chat_notification) if self.new_chat_notification > 0
end
def decrease_new_other_notifications
decrement!(:new_other_notification) if self.new_other_notification > 0
end
def decreased_chat_number_pusher
number = self.new_chat_notification
Pusher['private-'+ self.id.to_s].trigger('new_chat_notification', {:number => number})
end
def decreased_other_number_pusher
number = self.new_other_notification
Pusher['private-'+ self.id.to_s].trigger('new_other_notification', {:number => number})
end
notification.rb里
scope :not_chat, -> { where.not(notifiable_type: "Message") }
scope :chat, -> { where(notifiable_type: "Message") }
scope :task, -> { where(notifiable_type: "Task") }
scope :post, -> { where(notifiable_type: "Post") }
scope :checked, -> { where.not(checked_at: nil) }
scope :unchecked, -> { where(checked_at: nil) }
scope :this_post_comments, -> (post_id) do
where("notifications.notifiable_id = ?", post_id)
end
scope :between_chat_recipient, -> (sender_id) do
where("notifications.sender_id = ? AND notifications.notifiable_type = ?", sender_id, "Message")
end
scope :between_other_recipient, -> (sender_id) do
where("notifications.sender_id = ? AND notifications.notifiable_type != ?", sender_id, "Message")
end
def check_notification #chat notification gets checked
update_attribute(:checked_at, Time.zone.now) if self.checked_at.nil?
end
答案 0 :(得分:1)
您可以使用try
尝试向对象发送消息。如果对象响应它,那么它将被执行,否则它将被忽略。
string = "foo"
string.try(:length) # => 3
nil.try(:length) => nil
我建议您改用try!
。如果接收者没有响应消息并且不是nil
但这对你们没什么帮助。
如果您进行迭代,则无需检查是否存在某些内容。你可以只是迭代,如果关联是"空",那么什么都不会发生。
例如,您可以重写decreeasing_post_notification_number
:
def self.decreeasing_post_notification_number(current_user, post)
self.post.this_post_comments(current_user, post).unchecked.each do |notification|
checking_and_decreasing_notification(notification)
end
end
同样适用于decreasing_chat_notification_number
IFF可以为checking_and_decreasing_notification
拨打each
,而不只是first
由于我们在这里看不到完整的代码,我必须做一些假设。代码看起来不是OO(您有self
方法接收所有必需的值作为参数)。我建议您将其重构为:
顺便说一句:很酷,你使用的是Time.zone.now
而不只是Time.now
!
答案 1 :(得分:1)
我会在帮助者内部移动支票:
def checking_and_decreasing_notification(notification)
return if notification.nil? # here we defend from bad input
notification.check_notification
current_user.decrease_new_other_notifications
current_user.decreased_other_number_pusher
end
现在把它称为:
是安全的def self.decreasing_chat_notification_number(current_user, user)
# first below is safe, since `unchecked` returns a relation
# first called on relation will return nil on empty set
checking_and_decreasing_notification \
self.between_chat_recipient(current_user, user).unchecked.first
end
end
Sidenote :if
的后缀形式可能更优雅:
def check_notification #chat notification gets checked
update_attributes(checked_at: Time.zone.now) if self.checked_at.nil?
end