我对MVC并不陌生,但我是Rails的新手,而且我正努力尝试制作一切" Rails方式"。我想实施网站范围的通知,因此我创建了Notification
模型并创建了User
和Notification
之间的多对多关系。
我面临的问题是在创建通知时,我有几个实体在我的代码中生成通知。当有人回复您关注的论坛帖子时,您会收到通知,收到新的私人消息,有人关注您,收到您的某个条目,等等。我真的不知道如何创建新通知。
在控制器中创建它们感觉很糟糕,它可以很容易地导致胖控制器。我知道Service Objects我喜欢他们,但我不确定在这种情况下是否应该使用它们。例如,我可以使用通知服务来处理所有通知。
我想到的另一件事是制作所有可以生成通知的模型a" to_notification"返回通知所拥有的消息的方法,例如,PrivateMessage
模型将有一个返回to_notification
的方法<a href="some_url">You've got a new private message from #{username}</a>
。
我考虑的第三个解决方案是在notify_user(user, message)
模型中添加Notification
方法。但我想Controller仍然需要管理很多逻辑,比如通知消息本身。
解决这个问题最有效的方法是什么?
编辑:我很清楚Mailboxer但我宁愿自己做。
好的,所以我最终使用了一个服务对象。这是Notification
模型
class Notification < ActiveRecord::Base
validates :message, presence: true
belongs_to :user
end
非常简单,然后我在NotifyUser
中创建了一个名为app/actions/notify_user.rb
的操作,负责发送通知
class NotifyUser
def initialize(user, message)
@user = user
@message = message
end
def notify
Notification.create(user: @user, message: @message)
end
end
最后,要发送通知,我只需通过notify
调用操作NotifyUser.new(user, message).notify
方法即可。
通知消息的逻辑直接在控制器或操作中处理。例如:
def follow(user)
success = current_user.follow user
message = "You've got a new follower, #{view_context.link_to(current_user.username, current_user)}!"
NotifyUser.new(user, message).notify if success
end
我仍然无法想出一种更优雅的方式来创建消息。我想这对我来说足够好了。
答案 0 :(得分:1)
我更喜欢非平凡应用的服务对象。以下是我的个人意见。
假设您有一个典型的用例,其中用户向另一个用户发送消息,例如爱丽丝发送通知&#34;你好&#34;给鲍勃
这是一个在控制器中创建它们的例子,它是&#34; Rails方式&#34;。
Alice访问了一个页面,例如&#34; www.example.com/notifications/" ;,写下她的消息,点击&#34;发送&#34;按钮。
Rails使用NotificationsController创建新的Notification模型实例,即在数据库中记录。
当Bob登录时,应用程序会查询通知以查看是否有适用于Bob的通知。
以下是使用服务对象创建它们的示例:
您有一个文件,例如&#34; ./ app / services / notifier.rb&#34;暴露了一个普通的旧Ruby对象,例如&#34; Notifier&#34;。
Notifier对象有一个&#34; send&#34;方法(或任何你想要的方法)。
该方法负责创建新的通知。
这是一个混合的例子:
E.g。典型的NotificationsController有一些额外的代码:非用户可见的类级方法,例如&#34; def self.send&#34;。
控制器作为典型的REST资源CRUD管理器执行双重任务,并且还作为具有内部API方法的服务对象。
我对这种混合体验的个人经验是有效的,对于快速应用程序来说很容易,因为所有东西都在一个地方,但在真正的应用程序中,混合体往往会变成一个大的使用干净的分离,模拟和存根很难测试的代码球。
要向用户显示通知,并让用户与通知进行交互(例如编辑,删除),我建议使用典型的Rails控制器,因为通知本质上是资源。
我想到的另一件事是制作所有可以生成通知的模型a&#34; to_notification&#34;方法
如果您正在构建一个真正的应用,请不要这样做。我不得不清理这样的许多应用程序。当涉及国际化和本地化时,它也变得毛茸茸。
我考虑在Notification模型中添加notify_user(用户,消息)方法。
这实质上是一个混合类:它作为您的资源和服务对象实现双重任务。
很好,但很难推理,因为它将与模型相关的概念(例如业务逻辑,记录持久性等)与控制器相关的概念混合在一起(例如创建新资源)。
如上所述,它适用于快速应用,但往往会变成一个很难干净地测试的大代码球。