What have you found for these years?

2008-08-20

formatted named routes

updated:
好險我是用 *with_format 而不是暴力寫死,
應該要 push 不是 unshift... orz
奇怪...



updated:
就這樣結案吧:

formatted_user_album_path(*with_format(user, album))

splat 是必須的,因為 rails 沒設計到這邊。
with_format 是 models.unshift(params[:format])



updated:
嗯,有了,我可以這樣包,而不用動到 rails:

formatted_user_album_path(pfmt(user, album))

現在只要想想看那 pfmt 應該叫什麼比較好。名字絕不能長,因為前面已經夠長了。
但是又不能太短,pfmt 應該看不懂是什麼意思... params[:format] 的意思 XD


*


關於這個東西,文件上一點屁都沒有,google 也完全查不到 =_=b
but source code would tell everything...

根據 actionpack-2.1.0/lib/action_controller/polymorphic_routes.rb
第 157~158 行:

if options[:action].to_s == "formatted" && record_or_hash_or_array.is_a?(Array)
record_or_hash_or_array.pop


表示 formatted_user_album_path 的用法其實應該是丟入 array,
第一個參數帶需要的 format, 第二個參數帶 user, 第三個參數帶 album.
除此之外,後面兩樣東西可以用 id 代替。

rails 程式雖然寫得不夠好,不過要找出這些資訊,也還不算難。
這大概算是一種程式敏感度吧...?

*

well, 該怎麼說呢。rails 真的是個很難一言以蔽之的東西。
就照這個主題來說好了,named routes 到底要怎麼用?
我在文件上(ActionController::Resources)找到這種用法:

article_comment_url(:article_id => @article, :id => @comment)

我覺得這真的是天殺的詭異的介面啊。一個可以丟 model instance 進去,
一個卻要直接指定 argument... 這樣不好嗎:

article_comment_url(:article => @article, :comment => @comment)

測試之後發現好像也可以。不過在文件 ActionController::PolymorphicRoutes 的
地方看到事實上也能這樣寫:

admin_article_comment_url(@article, @comment)

噢,這樣很好,一目了然。只是既然能這樣用,為什麼不一起寫出來?
source code 翻半天,發現他到處都有針對 argument 做型別判定,
為了要做各種不同的 arguments 搭配,讓所有類似的用法都從同一個入口進入。

然後 formatted 的狀況下,則可以用最上面提到的第一個 argument 來表示,
或是直接用 :format => 'html'. 但是非 formatted named routes 又不能這樣用,
否則會變成 ?format=html ...

*

老實講,能提供各種不同的用法是很好,可是文件不寫清楚,變成只能翻 source code,
真的很容易造成混淆...... 所以也只好自己去找到一些 best practice 了。
自己還是要找到一個習慣用法,不然實在太混亂了一點... 很容易寫出 bug.

*

我現在要做的就是看看要怎麼包裝:

formatted_ooo_xxx_path 'html', ooo, xxx

要把第一個參數自動變成 params[:format]

我原本一直以為他會自己判斷,結果會生出看不懂的錯誤訊息:

formatted_user_tags_url failed to generate from {...}, expected:
{:controller=>"tags", :action=>"index"}, diff: {...}

最好是 expected 的參數那麼短,又沒有 format 啦 @@

真是昏倒哪... 好在總算找到原因了。

0 retries:

Post a Comment

All texts are licensed under CC Attribution 3.0