1

Rails 处理“多个控制器动作”的方式是什么?在我的应用程序中,我有一个特殊的“购物车”流程,它影响了几个模型。基本上,当他/她登录时,该流程可供特殊类型的用户使用,如下所示:

  1. 添加用户。
    • 在这里可以“添加用户”。如果您了解 Basecamp,这一步有点像在项目中添加人员。所以在这一步我正在考虑用户资源。
  2. 在这里,可以为之前添加的每个用户“购买”东西。
    • 这有点像一个基本的购物车。因此,就资源而言,我正在考虑“商店”或“购物车”。
  3. 这是一个确认步骤。我再次认为这是购物车的一部分。

确认后,应该会发生几件事。

  1. 在步骤 1 中添加的用户应该以某种方式被激活。也就是说,他们将无法在激活之前登录。
  2. 应该从第 2 步中的购买中下订单。
  3. 您在第 2 步中购买的“东西”是某种虚拟产品。即产品在用户登录时以“邀请”的形式出现。这个细节并不太重要,而且有点难以解释。关键是,确认后,应在数据库中创建与用户相关联的邀请。

同样,系统的细节有点难以解释,但我的主要问题是如何在 Rails 中最好地实现这类东西。In 涉及多个步骤,并在所有步骤中影响多个模型。

我一直在考虑用某种状态机来做这件事。然后状态机将负责在步骤或状态之间进行转换,并执行所需的操作。所以我想我会有一个 StateMachineController 或其他东西,没有模型,可以实现主要逻辑。这是可以使用的吗?似乎 Rails 确实偏向于 RESTfull 资源,但我似乎想不出类似上述的 RESTfull 方法。谢谢。

4

1 回答 1

1

将控制器操作视为用户引发的事件。之后发生的是通常应该与一个或多个模型相关联的逻辑。

所以下订单是 Order 模型中的东西,激活用户是 User 模型中的东西,发送邀请是 Invitation 模型中的东西等等。让模型彼此了解并没有错。当一个事件跨越多个模型时,我将一个方法放在与用户引发的事件最密切相关的一个中,可能是 Order 中的“purchase”之类的方法,这就是您将从 Order 控制器调用的方法。

因此,如果在其他模型中存在对状态的依赖关系,请在其中创建一些方法来测试(如果需要),例如activated?在 User 中,以及其他人来完成工作,例如activate(更新用户状态),然后在 Invitation 中“邀请”保存与用户关联的新邀请,依此类推。如果它们失败,请确保它们引发异常。

一旦你有了一堆很好的细粒度方法,你就可以将它们捆绑在一起,甚至将它们包装在你Order#purchase方法中的一个事务中。就像是

def purchase(user, stuff, invitee)
  Order.transaction do
    begin
      invitee.activate
      invitation = Invitation.create! {:invitee => invitee, :stuff => stuff, :invited_by => user }
      # You can't roll back an email, so do this after the others have worked without exception
      invitation.send
    rescue
      ActiveRecord::Rollback
    end
  end
end

通过在事务中完成所有操作,您的数据要么全部正确,要么不正确。

有这样的吗?

于 2012-11-16T22:51:43.653 回答