让我们从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_for。 link
def url_for(options = nil)
...
else
...
builder = ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.send(method)
...
builder.handle_model_call(self, options)
...
end
看起来url_for 负责决定如何构建网址。在这种情况下,它被发送到 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。希望对您有所帮助!