使用新控制器干燥rails应用程序

时间:2013-10-25 13:35:46

标签: ruby-on-rails ruby-on-rails-3 rails-routing

我正在通过为一个基本上是SO副本的大学项目做一个app来学习Rails。请考虑以下路线:

resources :questions do
  resources :answers
  post :vote_up, :vote_down, :on => :member
end

resources :answers do
  post :vote_up, :vote_down, :on => :member
end

虽然这很好,但我确信这不是最好的方法。我在两个控制器上的vote_upvote_down操作之间获得了大量重复代码。我的规格也有很多重复。

我想知道如何以尽可能干的方式解决这个问题。我想需要一个VotesController,但我玩弄路由并没有得到实际的解决方案。我得到的只是一些重要的URL而不是我真正希望的。

你能指出我正确的方向吗?

1 个答案:

答案 0 :(得分:0)

听起来你正在描述一个vote_controller,它可以在任何一个方向上进行投票,而不是向上和向下分割成他们自己的控制器。

关于将上下投票拆分为自己的控制器的问题是它们有多么不同。如果你有一个vote_upvote_down控制器,他们都必须找到被投票的实体的投票,添加一个新的投票,然后存储数据。无论你是投票还是投票,几乎所有的事情都是一样的。事实上,我管理投票的方式是让vote类型有点像这样:

   class Vote
        attr_reader :direction, :user, :timestamp
   end

通过这种方式,单一投票类型可以记录投票是投票还是投票,以及记录谁进行投票(因此,如果有人在拖车,你可以随时撤消所有工作)以及投票的时间,这总是有用的。

然后当您致电vote_controller.up_vote时,您创建了一个带有正方向的新Vote对象,对于vote_controller.down_vote,您创建一个带有负方向的对象。其他一切都很常见,所以你在投票控制器中所拥有的只是含糊不清:

def vote(direction)
    myVote = vote.new(direction, Request.userId, Time.now )
    voteOnObject.votes.add(myVote)
end

def up_vote
    vote( 1 )
end

def down_vote
    vote( -1 )
end

您会注意到这与工作代码完全不同。这部分是因为我不想为你做功课,部分是因为我最近没有做太多的Ruby,所以我有点吱吱作响。重要的是这里的原则。

如果你想正确干,你也可以设计一个相同的投票控制可以附加到问题,答案,评论等的方式(所以他们有一个父对象一个给定的类型/实现一个给定的mixin,他们调整的票数而不是影响模型级别的投票对象)而不必做任何改动。