繁体   English   中英

Rails:清理难看的控制器

[英]Rails: Cleaning up ugly controllers

我全力支持更瘦的控制器,更胖的模型思维方式。

我想知道如何去做:

  1. 如何确定应移至模型的事物(假设您像我一样,并且变得懒惰,并且需要重构控制器,因为您只是在其中推入了代码)

  2. 您如何在控制器中编写和组织新元素的创建。 请参见以下示例。

我有一个相对混乱的控制器,用于多词“表决”。 我已经很好地清理了它,但是我想知道是否可以更好地改进此操作:

def up
 vote = Vote.new
 vote.vote = true
 vote.voter = current_user    
 vote.voteable = Recipe.find params[:id]
 vote.save
end

对我来说,这有点丑陋,我可能应该只使用create而不是new,但是我想知道我是否正在通过使用非标准操作(关于REST)来推动这条致命的道路。

我正在努力将其切换为new 但是我绝对想了解社区的观点。

关键是测试驱动开发。 一旦养成习惯,就会在95%的时间为您回答在哪里放置代码的问题。 这就是为什么。

单元测试(Rails中的模型测试)是测试代码最容易的地方。 模型方法应该经过单元测试的“黑匣子”样式-意味着您不在乎方法内部是什么,只不过输入X提供了输出Y。这也将导致您在模型中编写大量较小的方法,而不是非常大的方法。 测试越容易,就越好-而且不仅仅是为了测试。 更简单的方法更易于被其他代码覆盖,这是Ruby的一大优势。

另一方面,控制器(功能)测试将使您更关心动作内部发生的事情,因为这些方法并不是多余的,而且不会浪费输入/输出场景。 发生数据库调用,设置会话变量,等等。Shoulda是一个很棒的测试套件,可以自动为您执行很多操作。

最后,我的建议是查看一些您喜欢的插件,以了解它们的运行情况。 而且,如果您对测试有更多的兴趣,我会在《 Shoulda》上发表有关静态控制器测试的文章这可能会让您入门。

在RESTful控制器中,尤其是通过大量操作,有时我会创建一个before_filter来加载对象:

before_filter :load_recipe, :only => %w(show edit update destroy up down)

private
def load_recipe
  @recipe = Recipe.find(params[:id])
end

在您的情况下,我可能会考虑将投票移至用户模型,因此您将遇到以下情况:

def up
  current_user.vote(@recipe)
end

然后在您的模型中:

class User < ActiveRecord::Base
  has_many :votes

  def vote(object)
    votes.create(:vote => true, :voteable => object)
  end
end

这样做的好处是,您可以轻松地单独测试投票的行为,并且如果您想在其他地方启用投票功能,则可以重新使用它(如其他操作的隐式结果,通过API投票,大量投票一样) -投票等)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM