2

我的应用程序中有两个模型:一个childthathas_many :toys和一个toythat belongs_to :child。我进行了为此工作所需的数据库迁移(添加child_idtoys表中)。

起初,孩子独立存在,玩具独立存在(没有关联)。在幼儿园的每一天开始时,没有孩子拥有任何玩具。要玩玩具,孩子必须先认领它,然后成为它的主人。所以,现在我需要以某种方式实现一个child.claim(toy)方法,在这里我卡住了。具体来说:

  1. 这应该进入child控制器或模型吗?或者也许它应该以某种方式在两者之间分开?
  2. 如果它应该进入控制器,它应该对应于 CRUD 操作之一还是它自己的东西def claim(toy)

编辑1:孩子是用户并通过浏览器登录。(今天的孩子可以做一些了不起的事情)

4

3 回答 3

2

我会建立一个单独的类来处理关于孩子和玩具的所有逻辑。称之为上下文,称之为关注,但要去做。

class ToyChild # or ToyInteraction or ChildContext::Toys...

  attr_reader :toy, :child

  def initialize(toy, chid)
    @toy   = toy
    @child = child
  end

  def associate
    toy.child = child
    # could be more difficult: you should check if the child has not enough toys, if the toy is not already assigned to another child etc...
    #I'd avoid saving here since you may want to perform other operations
  end

  def foo
    #code here
  end

end

在控制器中:

assoc = ToyChild.new(toy, child).associate
assoc.save

这种编码风格:

  • 更容易测试

  • 职责分工明确

  • 保持干燥(控制器中没有特定代码)

于 2012-12-26T14:36:28.263 回答
2

实际上,如果孩子是用户,则不需要声明方法。您可以claim_toy在控制器中有一个方法。在每个玩具的玩具索引视图中,您可以提供如下链接。

<%= link_to "claim", claim_toy_path(:toy_id => toy.id) %>

你的控制器方法看起来像这样。

def claim_toy
  toy = Toy.find(params[:toy_id])
  current_child.toys << toy
end

很简单。顺便说一句,这不是一个安宁的解决方案。

于 2012-12-26T14:38:43.310 回答
2

孩子是玩具的外键

当然还有其他方法可以做到这一点,但根据您最初的问题,最简单的解决方案是使您的行为与儿童与玩具表中的玩具相关联的事实一致。

最简单的解决方案

撇开关于在完美的 OOP/MVC 设计中应该做什么的争论不谈,做出改变的明智的地方是在控制器中,因为当孩子要求玩具时,要求由 #update(甚至可能是 #索赔)对玩具控制器的操作。

孩子是用户并通过浏览器登录。

在您的情况下,会话已经知道孩子是谁,因此将外键添加到 Toy 模型是微不足道的。控制器是接收关联模型参数的实体,因此它是告诉玩具模型为给定玩具更新哪些属性的正确位置。

当然还有更复杂的解决方案,但根据您原始帖子中提供的信息,它们的价值值得怀疑。与往常一样,您的里程可能会有所不同。

于 2012-12-26T14:46:08.243 回答