2016-07-23 40 views
1

爲了清晰起見,我第二次重讀railstutorial。我試圖理解由rails提供的RESTful resources,它列出了各種HTTP請求和相應的控制器操作:index,show,new,create,edit,update,destroy。Rails RESTful控制器動作創建用戶

我從來沒有真正理解軌道控制器是如何工作的,我想澄清它。如果我製作了users_controller.rb並且想要創建新用戶,那麼就是。我不在乎重定向,flash消息和其他flair。我只想創建新用戶並將其保存在我的數據庫中。我想做User.create(name: "Iggy1", email: "[email protected]")。假設我進行了遷移,並且在數據庫模式上有name(字符串)和email(字符串)。

user_controller.rb創建用戶所需的最少代碼行是什麼?

我問這個問題的原因直到現在,我仍然不能100%確定哪個代碼行實際執行期望的操作。軌道是否足夠智能以識別這些特定關鍵字index,new,create,destroy, show,editupdate,或者它們是否是任意的?如果rails足夠聰明地檢測這七個關鍵字,那麼只需列出方法(def destroy; #<no code>; end),是否可以自動訪問DELETE用戶方法,或者我不得不說def destroy; User.find(params[:id]).destroy; end使用DELETE用戶方法?在users_controller.rb上,我最終從railstutorial中得到了這個精心製作的代碼。

... 
    def create 
    @user = User.new(user_params) 
    if @user.save 
     @user.send_activation_email 
     flash[:info] = "Please check your email to activate your account." 
     redirect_to root_url 
    else 
     render 'new' 
    end 
    end 
... 

Users_controller上只有def create就足以讓rails創建用戶嗎?

def create 
end 

或者我至少需要有User.new或更多代碼才能創建新用戶?

回答

1

你需要創建一個用戶的第一件事是在你的UsersController一個「新」的動作,如下所示:

class UsersController < ApplicationController 

    def new 
     @user = User.new 
    end 

end 

在聲明上面的方法定義,Rails會期望一個文件名爲'new.html.erb',除非您告訴它呈現另一個模板。

注:我會繼續假設你不想這樣做,但如果你這樣做,你會添加render 'other'到'new'方法的末尾(其中'other'是文件' other.html.erb'):

由於您的目標是創建一個新的User實例,因此此視圖模板將需要一個表單來添加名稱和電子郵件字段。雖然並非所有Rails表單都需要,但創建用戶的一種常見方式是創建一個「新」(即未保存的)用戶實例並將其傳遞給表單,以便表單知道用戶具有哪些屬性。 Rails將此實例變量傳遞給視圖,並且它還知道要呈現哪個視圖文件(因爲您定義的'new'方法應與包含表單的'new.html.erb'視圖模板命名相同)。這也是Rails知道表單的'submit'按鈕應該是'Create user'的。

假設你有上述內容,下一步是添加一個表單數據發送一個地方,一旦你點擊表單的「提交」按鈕。這就是'創造'行動所做的。換句話說,「新」操作負責在瀏覽器中顯示錶單,「創建」操作負責處理該表單提交的數據。你需要在這一點上添加的最低限度的代碼如下:

def create 
    @user = User.create(user_params) 
end 

Rails的方式做到這一點是通過它實現,被稱爲「PARAMS」的特殊方法。在幕後,Rails接受提交表單時發生的HTTP請求,並將某些數據存儲在ActionController :: Parameters對象中。這些數據然後由'user_params'方法進行處理(您需要聲明;請參見下文),並且只返回您在該方法定義中使用白名單的參數(即'name'和'email')。

這意味着您需要實現'user_params'方法定義。這通常是作爲UsersController底部的私有方法完成的,因爲您不希望此方法在控制器之外可用。所以,你會添加以下內容:

private 

def user_params 
    params.require(:user).permit(:name, :email) 
end 

因爲惡意用戶可能會在他們的瀏覽器添加新的表單元素這是從安全角度來看,重要的(例如,一個名爲元素「管理」),並點擊「提交」。如果您的用戶模型確實包含「管理員」屬性,則該惡意用戶剛剛創建了一個管理員用戶(具有相應的管理員權限)。

最後,由於表單發送的請求是POST請求(而非獲取請求),因此Rails希望您在提交表單後提供一個視圖來發送用戶。這個視圖通常是剛剛創建的用戶的'show.html.erb'模板,因爲'create'沒有自己的模板(請記住,我們討論的形式是'編輯'動作,而不是'創建'動作)。 「顯示」視圖通過以下方法呈現:

def show 
end 

此外,你需要告訴Rails到「創造」的動作完成後重定向到「顯示」頁面。添加到您的「create」方法的末尾:

redirect_to @user 

既然你通過了User類的一個實例,Rails的推斷要重定向到「顯示」行動(而不是「指數」或者其他一些行爲)的用戶控制器。根據您傳遞給「redirect_to」方法的內容,您可以將用戶發送到任意數量的目的地。有關更多信息,請參閱these docs

所以總之,除了'edit.html.erb'和'show.html.erb'視圖模板以及'config/routes.rb'文件中的路由聲明(我沒有詳細討論過,因爲這個問題的範圍僅限於UsersController),代碼你的UsersController應該有最起碼的金額如下:

class UsersController < ApplicationController 

    def new 
     @user = User.new 
    end 

    def create 
     @user = User.create(user_params) 
     redirect_to @user 
    end 

    def show 
    end 

    private 

    def user_params 
     params.require(:user).permit(:name, :email) 
    end 
end 
+1

太謝謝你了,@toomanyrichies。這是我需要知道的。其他回答者巧合地提到了路由。有了這2個信息,我已經瞭解到關於資源的大量信息 – Iggy

1

你必須明白的軌道是建立在MVC和REST。 MVC是分配項目責任的架構模式。 M - Model,它與數據庫交互,是實現業務邏輯的理想場所。

N - 查看,這裏的HTML渲染髮生

Ç - 控制器,基本上填補了

M和V.

之間的通信因此,基本上,當最終用戶訪問您的域名的請求到達Web服務器然後,到rails API。 rails API會知道傳輸請求的默認控制器,而默認控制器操作會返回html輸出。在配置

默認路由器/ routes.rb中

root to: 'controller#action' 

同樣導軌理解5 HTML方法其是GET,POST,PUT,DELETE和補丁。因此,一旦你創建了一個控制器並將routes.rb中的引用設置爲resources [controller_name],那麼rails路徑將爲控制器中的8個默認動作中的每一個創建8個URL。舉一個例子,讓我們說你的控制器users_controller.rb然後,將其設置在routes.rb中作爲resources :users這將允許下面的方法,

users  GET /users(.:format)      users#index 
      POST /users(.:format)      users#create 
new_user GET /users/new(.:format)     users#new 
edit_user GET /users/:id/edit(.:format)    users#edit 
user  GET /users/:id(.:format)     users#show 
      PATCH /users/:id(.:format)     users#update 
      PUT /users/:id(.:format)     users#update 
      DELETE /users/:id(.:format)     users#destroy 

所以,當你建立你的觀點和設置的form_for網址爲users_path並將http方法設置爲POST,表單的提交將觸發創建操作。因此,在創建操作中,您應該編寫觸發模型以保存記錄所需的所有代碼。

而且,通過這個文件,以及,

http://guides.rubyonrails.org/routing.html

+0

很好的解釋!謝謝@Pragash。快速提問:路由只負責生成URL,對嗎? 'users#create'響應'users_controller.rb'的'create'方法。我在上面的表格中創建的解釋是在web應用程序中生成/users(.:format)鏈接,並且它執行無論「create」方法如**在users_controller的create方法中定義的那樣。正確? – Iggy

+1

實際上,路線是將URL映射到控制器操作。所以,如果你調用POST方法users_path,它會調用users_controller.rb文件中的create操作。然後,您可以在create方法中編寫代碼來生成新用戶。 – Pragash

相關問題