2016-09-22 78 views
2

CRUD代表創建,讀取,更新,刪除。這是四種方法(如果區分查看一條記錄和查看所有記錄,則爲五條)。在Rails中,處理CRUD的規範方式似乎涉及七種方法。例如,使路由使用resources :orders速記Order對象產生以下七個路線:Rails CRUD路由和控制器方法最佳實踐

  • 指數
  • 創建
  • 顯示
  • 編輯
  • 更新
  • 破壞

這是我的困惑之源。對於new/createedit/update有什麼獨立的行動/路線?單獨查看頁面的操作與創建數據庫中的記錄有什麼好處?我明白它是如何 Rails中進行,例如:

class OrdersController < ApplicationController 
    def new 
    @order = Order.new 
    render 
    end 

    def create 
    @order = Order.new(order_params) 
    if @order.save 
     redirect_to @order, notice: 'Successfully created an order.' 
    else 
     render :new 
    end 
    end 
end 

之前使用Rails的工作,我用Yii的(PHP),它有一個內置的生成這樣的代碼CRUD生成器(翻譯成滑軌) :

class OrdersController < ApplicationController 

    def create 

    if request.method == "POST" 
     @order = Order.new(order_params) 
     if @order.save 
     redirct_to @order, notice: 'Successfully created an order.' 
     end 
    else 
     @order = Order.new 
    end 

    render 

    end 
end 

我更喜歡這種模式的原因是因爲它避免了必須爲不同的控制器操作呈現模板。在第一個代碼示例中,用戶轉到orders/new,併發布到orders/create。如果驗證失敗,用戶仍然卡在orders/create,但查看模板orders/new。這可能會讓用戶感到困惑,而且似乎也打破了單獨查看頁面的操作與在數據庫中創建記錄的整個想法。如果您重定向到orders/new而不是使用render :new,那麼您將丟失所有驗證錯誤消息。

我發現自己潛意識地滑回到我的Rails代碼中的Yii方式。任何人都可以解釋爲什麼標準方式有利嗎?如果我偏離規範的Rails模式,是否會遇到任何問題?

StackOverflow警告我這個問題是主觀的,可能會被關閉,所以讓我澄清一下。我並不是試圖討論Rails vs. Yii,或者確定組織CRUD代碼的最佳理論方法。我想知道,如果我偏離了處理CRUD的規範Rails方式,那麼Rails會有什麼破壞。

+0

我不知道它是否會發布任何錯誤,但Ruby On Rails開發中最常用的短語之一是'Convention over Configuration'...我認爲改變此過程並不是很明智一旦遇到困難,將很難獲得幫助,並且會讓其他人更難以閱讀您的代碼/與您協作。 – luissimo

+0

我認爲規範的Rails方式旨在分離關注點,以幫助剛剛開始編寫Web應用程序的人......更像是Web應用程序的構建方式和工作原理......只是將腳本資源和服務器搭起來,正在運行..並且隨着您的應用程序添加功能..您傾向於編寫自定義路線並偏離軌道中的規範化方式。軌道爲此提供了很大的靈活性,我認爲可以這樣做。但是,我不是這方面的專家,我期待着在這篇文章中提供更有見地的答案。 – sa77

回答

3

簡單的解釋是:

因爲多數民衆贊成神和DHH如何打算的。

Rails CRUD約定非常務實,可以避免許多與瀏覽器緩存和安全相關的缺陷。

讓我們舉一個例子:

# config/routes.rb 
resources :users, only: [:new, :create] 

# app/controllers/users_controller.rb 
class UsersController < ApplicationController 
    def new 
    @user = User.new 
    end 

    def create 
    @user = User.new(user_params) 

    if @user.save 
     sign_in(@user) 
     redirect_to root_path 
    else 
     render :new 
    end 
    end 

    private 
    def user_params 
     params.require(:user).permit(:email, :password, :password_confirmation) 
    end 
end 

在這裏,我們兩個分開的路線GET /users/newPOST /users

第一條路線是冪等的 - 它應該對任何訪客都一樣,並且可以被緩存。第二個不是 - 它應該顯示創建或嘗試創建資源的結果。

當用戶訪問/users/new時,我們將表單發佈到不同的URI。這避免了客戶端的歷史問題。

如果輸入無效,我們也會在相同的請求週期中呈現表單。這樣可以避免在嘗試將表單數據重新傳遞到/users/new時發生的安全問題,並讓我們返回語義正確的響應代碼而不是重定向。

它還確保我們的應用程序在安靜的意義上是無狀態的,因爲如果我們訪問/users/new,上一個操作不會影響我們看到的內容。

在架構級別上,它允許您利用約定而不是配置。你可以這樣做:

def new 
    @user = User.new 
end 

而且它會使views/users/new.html.erb因爲Rails可以推導出新的行動應該呈現新的模板。從設計和測試的角度來看,讓每個控制器動作執行單個任務要好得多,因爲它消除了以相同方法測試兩個獨立代碼路徑的需要。

+0

偏離最大的問題是沒有人會僱用你。 Rails非常受公約的驅動和輿論。而一個積極支持所有使軌道有趣而富有成效的慣例的開發者並不是很有吸引力。 – max

+2

我個人發現,從MVC設計的角度來看,YII方法愚蠢至極。其堆棧作業中的路由組件確定通過匹配請求方法應調用哪個操作。不是應該在你的控制器上重複的東西。 – max