簡體   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