【问题标题】:Rails best practices - where should this code go?Rails 最佳实践——这段代码应该放在哪里?
【发布时间】:2012-02-29 21:57:14
【问题描述】:

有几个地方我可以做我需要做的事,但我不确定哪里是符合良好做法的最佳地方。

我有一个 Orders 控制器,在创建成功的订单后,我想创建订阅(但前提是订单成功)和推荐(但前提是订单与订单相关联)。

现在显而易见的选择是在 Order 模型上使用 after_create……但是……我怎样才能将会话数据放入其中? (推荐 id、朋友 id 和凭证 id 仅在会话中,因为不需要将它们存储在 Order db 中)。

那么我应该只在 create 操作中创建 Subscription 和 Referral 对象(我现在如何拥有它)还是有更好的方法?

这是我的创建操作: (@order.purchase 仅在支付成功时返回 true)

def create
if @order.save
    if @order.purchase
      Subscription.create(:order_id => @order.id, :product_id => @order.product_id)
      if @order.voucher
        Referral.create(:user_id => session[:friend_id], :order_id => @order.id, 
                        :voucher_amount => @voucher_value)
      end
      render :action => "success"
    else
      render :action => "failure"
    end
  else
    render :action => 'new'
  end
end

任何帮助将不胜感激 - 我真的很想正确地做到这一点,所以我希望没有人介意我问什么可能是一个简单的问题。

【问题讨论】:

    标签: ruby-on-rails-3


    【解决方案1】:

    我最近有一个类似的问题,请看一下,我认为回调中的简单虚拟属性也可以为您解决问题。

    Fetch current user in after_create filter

    【讨论】:

    • 嗨,谢谢 - 虚拟属性似乎是一种有趣的方式。以这种方式使用它们有什么缺点吗?
    • 我真的没有。它看起来很自然,还允许您使用回调。
    • 很抱歉,因为我没有足够的积分或其他东西,我无法“投票”您的答案。无论如何,我结合了您的建议,将所有内容移入模型并使用虚拟属性来获取我的参数。不幸的是,我不能使用回调方法,因为只有在 update_attribute 发生之后才能访问创建新对象的属性,直到创建 Order 之后才会调用它(它是我第一篇文章中 .purchase 方法的一部分) .谢谢两位的回答!
    • 别担心 :) 您可以尝试使用 after_update 回调。每次保存现有记录时都会触发它。
    • 是的,但我只需要在创建成功订单时发生这种情况。我可以通过检查记录是否在我猜的最后两分钟内更新来确定它,但是,我认为我现在的方式还可以。谢谢:)
    【解决方案2】:

    使用回调会让你的生活变得轻松,你需要使用 after_save

    在订单模型的 after_save 回调中做所有的事情。有关回调,请参阅 rails api doc here

    编辑:如果模型不提供会话变量,您可以使用 post_save 方法来处理所有逻辑,该方法也接受所有需要的参数,例如

    喜欢

    class Order < ActiveRecord::Base
      def post_save require_attr
    
       #create subscriptions
    
       # create referral
    
      end
    end 
    

    【讨论】:

    • 请看看我想要实现的目标 - 如何将会话数据(和其他变量)放入我的模型中以用于回调?
    • 好的,没看到。在这种情况下,您可以使用模型方法来处理所有创建/保存后的内容,并且可以将参数传递给它。基本上所有的业务逻辑都应该放到模型中,而不是放在控制器中。
    • 啊,对了,谢谢大声笑,所以我现在不使用回调,只是我模型中的普通方法,对吗? (或者我是否遗漏了一些关于如何将参数输入模型以用于回调的方法?)。感谢您的帮助!
    • 很抱歉,因为我没有足够的积分或其他东西,我无法“投票”您的答案。无论如何,我结合了您的建议,将所有内容移入模型并使用虚拟属性来获取我的参数。不幸的是,我不能使用回调方法,因为只有在 update_attribute 发生之后才能访问创建新对象的属性,直到创建 Order 之后才会调用它(它是我第一篇文章中 .purchase 方法的一部分) .谢谢两位的回答!
    • 将代码移动到模型是一步,使用虚拟属性很好地保存其他对象所需的变量也很好。我看到你想使用订单 ID,你也可以通过在订单产品和推荐之间建立关联来实现这一点,并且可以使用该关联在 after_save 回调中创建所有这些对象。
    猜你喜欢
    • 1970-01-01
    • 2014-02-27
    • 1970-01-01
    • 1970-01-01
    • 2015-03-03
    • 2011-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多