2012-11-16 76 views
0

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

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

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

  1. 步骤1中添加的用户应该以某种方式被激活。也就是说,在激活之前他们将无法登录。
  2. 应在步骤2中购买订单。
  3. 在步骤2中购买的“材料”是某种虚拟产品。也就是说,产品在用户登录时显示为“邀请”。这些细节并不太重要,有点难以解释。关键是,确认后,应在数据库中创建与用户关联的邀请。

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

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

+0

我有一个答案正在进行,但意识到它太模糊不实用。我的一般回应是你应该保留你的模型中的状态信息,并且在那里确定逻辑的状态(无论是状态机还是简单的流程)。这听起来很像我的一个“邀请”过程 - 你“邀请”一个潜在的新用户,并给他们虚拟的东西。但是他们只有在注册并确认之后才能得到这些东西。这种流程在Devise gem中出色地完成了(我认为有一个“invitable”模块)。检查出来的灵感。 –

+0

感谢您的回复。你对邀请系统绝对正确。实际上我使用Railscast#196作为灵感来源,因为我有自己的认证系统,不能/不会使用Devise(不是我认为Devise不错)。我的主要问题仍然是如何处理“控制多个模型”。我需要这样一些内容:在步骤3中按下OK后:下订单,激活用户,发送邀请等等。因此,可能的一些操作(跨越用户,邀请和订单模型)在单个交易中汇总。但是,谢谢。 – Kasper

回答

1

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

因此,在Order模型中放置一个订单,在User模型中激活用户,在Invitation模型中发送邀请等等。让模特了解彼此没有错。当一个事件跨越多个模型时,我将一个方法放在与用户引起的事件最密切相关的方法中,可能是Order中的“购买”方法,这就是您要从Order控制器调用的方法。

因此,如果有在其他车型状态的依赖,建立小法在他们测试(如果需要),如用户activated?,和别人做的工作,如activate(即更新用户状态),然后在邀请中“邀请”,以保存与用户关联的新邀请,等等。如果他们失败了,请确保他们提出异常。

一旦你有很多很好的粒度方法,你可以将它们捆绑在一起,甚至将它们包装在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 

通过在交易中完成所有操作,您的数据无论是全部正确还是不正确。

有点像这样吗?

+0

我想我明白你的意思。所以,有这样的模型“交流”,我想我可以让它工作。我对Rails相当陌生,而且我认为,了解它最难的部分是理解什么是“好”导轨,什么是“坏”导轨。顺便说一下,R​​ails中是否存在某种Oberver模式?谢谢。 – Kasper

+0

嗯,猜我可以只是谷歌的Rails观察员模式:) – Kasper

+0

要看“良好的Rails”看看宝石和Rails本身的源代码。大多数情况下,如果它看起来不错 - 不,认真。简短的小方法,干净的一致性等等。是的,Rails有观察者,但我不明白他们被广泛使用 - 他们擅长解耦电子邮件发送等。二者之间的排序可能在过滤器之前/之后/周围 - 并不完全相同,但似乎是避免过多的if/else逻辑混淆其他简单方法的更常见的方法。 –