2015-08-29 38 views
1

背景:新手rails開發人員在此學習Michael Hartl的Ruby on Rails教程(https://www.railstutorial.org/),其中您使用User模型和Post模型開發基本的類似twitter的應用程序。用戶路由產生的從我的理解是將以下到routes.rb中文件的常用方法:古怪的Ruby on Rails語法

resources :users 

問:我不明白爲什麼當你使用:

redirect_to @user

軌發送一個請求UsersController#節目,但它通過調用user_url(@user)這樣做:

get "https://stackoverflow.com/users/id" => "users#show" 

哪裏奇(「用戶」)user_url來自上面的代碼?我認爲用戶網址應該是users_url或users_path(正如我在某些地方看到的)。試圖找出這個單數編碼到rails中的位置。

謝謝!

回答

1

讓我們跟隨一些代碼下來的兔子洞,開始redirect_to @user

redirect_to執行與location集重定向到url_for(@user)link

def redirect_to(options = {}, response_status = {}) #:doc: 
    ... 
    self.location  = _compute_redirect_to_location(request, options) 
    ... 
end 

def _compute_redirect_to_location(request, options) #:nodoc: 
    ... 
    else 
    url_for(options) 
... 
end 

到目前爲止,這麼好。 redirect_to在如何確定路徑方面沒有發言權。接下來,我們來看看url_forlink

def url_for(options = nil) 
    ... 
    else 
    ... 
    builder = ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.send(method) 
    ... 
     builder.handle_model_call(self, options) 
    ... 
end 

貌似url_for負責決定URL應該如何建立的。在這種情況下,它被髮送到HelperMethodBuilder。 link

def handle_model_call(target, model) 
     method, args = handle_model model 
     target.send(method, *args) 
    end 

    def handle_model(record) 
     ... 
     named_route = if model.persisted? 
         ... 
         get_method_for_string model.model_name.singular_route_key 
        ... 
     [named_route, args] 
    end 

    def get_method_for_string(str) 
    "#{prefix}#{str}_#{suffix}" 
    end 

我們走了。 handle_model獲取(持續)記錄的model_name,它返回ActiveModel::Name對象,並從中獲取singular_route_key

pry(main)> User.first.model_name.singular_route_key 
=> "user" 

get_method_for_string使用singular_route_key完成輔助方法調用。我將離開邏輯推導"prefix"/"suffix"作爲學術練習,但它應該返回"user_path"

所以,要回答這個問題,單數形式被編碼到ActiveModel :: Name和HelperMethodBuilder中。希望有所幫助!

+0

和vualá!謝謝,非常感謝。 – craig

1

歡迎來到鐵軌。

如果您查看所有路線,您可能會注意到爲什麼會立即發生。但由於設計增加了許多額外的路線,可能會造成混淆。

鐵路的路線使用複數和單數模型的概念。

因此,讓我們說你有一個用戶,路徑是單數 - user_path(@user) - 和這個網址將是/users/1

如果您想查看所有用戶的集合,路徑是複數 - users_path - 對於這個URL將是/users

這同樣適用於該用戶相關的所有路由。當你在談論隻影響單個對象的動作時,路徑是單數的,而影響多個對象的動作是複數。長時間閱讀,而是因爲它決定如何行動都解決了,一個很好的資源是:http://guides.rubyonrails.org/routing.html

+0

所以我明白'users_path'和URL'/ users'的路徑來自哪裏,因爲當我運行'rake routes'時,我看到'resources:users'生成的幾條路由,比如'用戶GET/users(。 :format)users#index'。我看到這個路由的URI是如何「用戶」的,這對我來說都是有意義的。 但我沒有看到代碼中單數用戶的來源。 – craig

+1

它只是一個語義幫助器來返回正確的URL。因爲你只是在尋找一個單一的對象,這個幫手是單一的。所有的路徑助手都是這樣,除非你深入rails核心,否則這不是你會「看到」的代碼。 – trh

+0

好吧,它在軌道內核中,我不會在任何路徑中明確地看到它,這就是我想知道的。謝謝。 – craig