ken*_*nyc 149 ruby-on-rails ruby-on-rails-4
随着Observers正式从Rails 4.0中删除,我很好奇其他开发人员在他们的位置使用了什么.(除了使用提取的宝石.)虽然Observers肯定被滥用并且有时很容易变得笨拙,但是在缓存清除之外有许多用例,它们是有益的.
例如,需要跟踪模型更改的应用程序.观察者可以轻松地观察模型A的变化,并在数据库中记录模型B的变化.如果你想观察几个模型的变化,那么一个观察者就可以处理它.
在Rails 4中,我很好奇其他开发人员使用什么策略代替Observers来重新创建该功能.
就个人而言,我倾向于某种"胖控制器"实现,在每个模型控制器的创建/更新/删除方法中跟踪这些更改.虽然它稍微膨胀了每个控制器的行为,但它确实有助于可读性和理解,因为所有代码都在一个地方.缺点是现在的代码非常相似,分散在几个控制器中.将该代码提取到帮助器方法是一种选择,但您仍然可以调用遍布各处的方法.不是世界末日,也不是"精瘦控制者"的精神.
ActiveRecord回调是另一种可能的选择,虽然我个人并不喜欢,因为在我看来它往往会将两个不同的模型紧密地结合在一起.
所以在Rails 4中,no-Observers世界,如果你必须在创建/更新/销毁另一条记录之后创建一条新记录,你会使用什么样的设计模式?胖控制器,ActiveRecord回调,还是完全不同的东西?
谢谢.
Unc*_*dam 79
看看忧虑
在models目录中创建一个名为concern的文件夹.在那里添加一个模块:
module MyConcernModule
extend ActiveSupport::Concern
included do
after_save :do_something
end
def do_something
...
end
end
Run Code Online (Sandbox Code Playgroud)
接下来,在您希望运行after_save的模型中包含:
class MyModel < ActiveRecord::Base
include MyConcernModule
end
Run Code Online (Sandbox Code Playgroud)
根据你正在做的事情,这可能会让你在没有观察者的情况下接近.
Kri*_*ris 33
他们现在在插件中.
我还可以推荐一种替代方案,它可以为您提供以下控制器:
class PostsController < ApplicationController
def create
@post = Post.new(params[:post])
@post.subscribe(PusherListener.new)
@post.subscribe(ActivityListener.new)
@post.subscribe(StatisticsListener.new)
@post.on(:create_post_successful) { |post| redirect_to post }
@post.on(:create_post_failed) { |post| render :action => :new }
@post.create
end
end
Run Code Online (Sandbox Code Playgroud)
Mik*_*keJ 21
我的建议是阅读James Golick的博客文章http://jamesgolick.com/2010/3/14/crazy-heretical-and-awesome-the-way-i-write-rails-apps.html(试着忽略如何标题听起来不谦虚).
回到那一天,这一切都是"胖模特,瘦瘦的控制者".然后脂肪模型成为一个巨大的头痛,特别是在测试期间.最近推出的是瘦模型 - 这个想法是每个类应该处理一个责任而模型的工作就是将数据保存到数据库中.那么我所有复杂的业务逻辑最终会在哪里结束?在业务逻辑类中 - 表示事务的类.
当逻辑开始变得复杂时,这种方法可能变成泥潭(giggity).这个概念虽然合理 - 而不是使用难以测试和调试的回调或观察器隐式触发事物,而是在模型顶层逻辑层的类中显式触发事物.
agm*_*min 13
使用活动记录回调只会翻转耦合的依赖关系.例如,如果你有modelA
和CacheObserver
观察modelA
rails 3样式,你可以删除CacheObserver
没有问题.现在,反过来说A
必须手动调用CacheObserver
后保存,这将是rails 4.你只是移动你的依赖,所以你可以安全删除A
但不是CacheObserver
.
现在,从我的象牙塔,我更喜欢观察者依赖于它所观察的模型.我是否足够关心我的控制器?对我来说,答案是否定的.
大概你已经考虑了为什么你想要/需要观察者,因此创建一个依赖于它的观察者的模型并不是一个可怕的悲剧.
对于依赖于控制器动作的任何类型的观察者,我也有(合理的基础,我认为)厌恶.突然之间,您必须将观察者注入任何可能更新您想要观察的模型的控制器动作(或其他模型).如果您可以保证您的应用程序只会通过创建/更新控制器操作修改实例,那么您将获得更多权力,但这不是我对轨道应用程序的假设(考虑嵌套表单,模型业务逻辑更新关联等)
ops*_*psb 13
Wisper是一个很好的解决方案.我个人对回调的偏好是他们被模型解雇但事件只是在请求进来时才被听取,即我不想在我在测试中设置模型等时触发回调但是我确实想要它们在涉及控制器时触发.使用Wisper非常容易设置,因为您可以告诉它只能监听块内的事件.
class ApplicationController < ActionController::Base
around_filter :register_event_listeners
def register_event_listeners(&around_listener_block)
Wisper.with_listeners(UserListener.new) do
around_listener_block.call
end
end
end
class User
include Wisper::Publisher
after_create{ |user| publish(:user_registered, user) }
end
class UserListener
def user_registered(user)
Analytics.track("user:registered", user.analytics)
end
end
Run Code Online (Sandbox Code Playgroud)
在某些情况下,我只使用Active Support Instrumentation
ActiveSupport::Notifications.instrument "my.custom.event", this: :data do
# do your stuff here
end
ActiveSupport::Notifications.subscribe "my.custom.event" do |*args|
data = args.extract_options! # {:this=>:data}
end
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
32120 次 |
最近记录: |