What have you found for these years?

2008-07-27

has_many and find (3)



contagion 提到...

嗯..這個..
問題應該是

user.habit_contents.class
不應該傳回 Array
而是 AssociationProxy 才對
2008年7月25日 下午 10:57


godfat 真常 提到...

也是一個方法,不過我還是覺得改名字會比較好一點
例如 query 之類的
如果說為了跟 Model.find 有同樣的名字
那乾脆用 Model.query
總之不要衝突...
2008年7月25日 下午 11:18



因為發神經,所以試了一下 data mapper[0]

他確實是回傳 association proxy, 而且有三種:
DataMapper::Associations::OneToMany::Proxy
DataMapper::Associations::ManyToOne::Proxy
DataMapper::Associations::ManyToMany::Proxy

合理的作法。另一方面,他也完全沒有污染 find.
active record 的 find :first 對應為 first
find :all 對應為 all.
find id 對應為 get id.

ActiveRecord:
Model.find :all
Model.find :first
Model.find 1

DataMapper:
Model.all
Model.first
Model.get 1

association 呢?

ActiveRecord:
user.habit_contents.find :all, :conditions => ['name = ?', 'test']

DataMapper:
user.habit_contnets.all :name.eql => 'test'

雖然我也不喜歡 data mapper 的 Symbol#eql, #gt, etc.
但是就有如 Why DataMapper?[1] 一文所說,
active record 裡面還是有不少 sql 相關知識:

例如什麼 DESC, AESC, conditions => "name = 'test'",
order => 'rand()' 這些差不多都是 sql 直接搬過來。
要是沒有好好注意的話,甚至會寫出有 sql injection 風險的程式。
畢竟 active record 就某方面而言也可以說是 sql generator?

那讓我覺得很討厭。理由當然很簡單,因為我不懂 sql, 也不想碰。
這倒不是在批評 active record, 只是 kind of taste 罷了。
像我就覺得 ramaze[2] 推薦的 sequel[3] 更爛,因為他更貼近 sql......

當然這很明顯是不考慮效率了。

另一方面,rails 2.1 好像才引入什麼 dirty object,
看起來意思就是單純指僅儲存改變的數值進 database.
呃,這不是基本功嗎?我一直以為 rails 有做.......
還有 lazy fetching 之類的,active record 好像沒做完整?

總之就是希望哪天 data mapper 可以取代 active record 就是了...

[0] http://datamapper.org
[1] http://datamapper.org/why.html
[2] http://ramaze.net
[3] http://ramaze.net/features:orms
[4] http://en.wikipedia.org/wiki/Liskov_substitution_principle

p.s. 其實會想罵 rails, 最主要可能是因為很多人都把 rails 當神話了吧...
此外還有 java, oo 等等。總覺得都被別人拿去炒作,然後誤解的人就一堆。
這點實在是讓人覺得很討厭。

*

對了,再提到這種名稱污染,RMagick 裡面也有。
他的 ImageList 把 map 吃掉了。不過有參數不同,
一跑就有 argument error, 不像 RecordNotFound 這點比較討厭。
而且 find 沒有 alias, 但 map 可改用 collect...

再加上我去翻他 source code, 我還是可以用 __map__...
但沒有 __find__ (或許有其他名字,我沒去翻 source code)

所以雖然他把 map 吃掉我有點不爽,但還好解決。
active record 吃掉 find, 就真的只能 to_a.find 了。
這在 ruby 1.8 也會有點恐怖,因為 Object#to_a 是存在的。
如果 to_a 沒有按照 Enumerable 的 semantics 的話,
那就又出事了...

誰知道呢,畢竟 Array 都不是 Array 了。

*

喔,還有一件事,不過這跟 ruby 本身比較有關。
就是 map 到底應該是 map 到 array 呢,還是 map 回自己?
之前 ruby-core 上有相關的討論,說 Set#map 究竟該回傳什麼?
而且我也常常會需要 hash map 回 hash.

我想可能兩種都需要,所以可以考慮用不同的名字,不用去爭到底要保留哪個。

而 hash map 回 hash, 我最後都寫成 inject(fold) 的模式...
會變得稍微囉唆些,有點可惜。

*

啊,最後一件事,一直忘記說。
DataMapper 我用 DataMapper.setup :default, 'sqlite3://memory',
在 irb 裡一直出事 @@
DataMapper.auto_migrate! 建好 table 後,過沒多久就不見了!
我猜可能是被 gc 掉了吧... 改用檔案執行就不會有這個問題了。
(該不會是 irb 有奇怪的動作?之前也碰過 irb 出事過)

這... 老實講有點討厭。畢竟測試時用 irb 還是方便得多。
希望 1.0 可以改進這部份。或是說看有沒有什麼簡易的 workaround,
或是 irb 時還是建個檔案吧。

0 retries:

Post a Comment

All texts are licensed under CC Attribution 3.0