2008年11月29日 星期六
2008年11月27日 星期四
A quick way to get memcached status
http://www.mysqlperformanceblog.com/2008/11/26/a-quick-way-to-get-memcached-status/
echo stats | nc 127.0.0.1 11211
watch "echo stats | nc 127.0.0.1 11211"
echo stats | nc 127.0.0.1 11211
watch "echo stats | nc 127.0.0.1 11211"
2008年11月26日 星期三
upload file in rails
http://www.tutorialspoint.com/ruby-on-rails/rails-file-uploading.htm
http://manuals.rubyonrails.com/read/chapter/79
http://manuals.rubyonrails.com/read/chapter/78
http://manuals.rubyonrails.com/read/chapter/77
http://www.practicalecommerce.com/blogs/post/432-Multiple-Attachments-in-Rails
http://izumi.plan99.net/blog/index.php/2007/04/07/ruby-on-railss-handling-of-uploaded-files/
http://manuals.rubyonrails.com/read/chapter/79
http://manuals.rubyonrails.com/read/chapter/78
http://manuals.rubyonrails.com/read/chapter/77
http://www.practicalecommerce.com/blogs/post/432-Multiple-Attachments-in-Rails
http://izumi.plan99.net/blog/index.php/2007/04/07/ruby-on-railss-handling-of-uploaded-files/
About the uploaded file object
While the uploaded file is a special beast,it is not difficult to use. The object
rails receives are processed by a CGI object. The object that CGI returns to Rails
isn’t actually a file object, but it’s close enough for our purposes.
Details from the CGI class documentation
... the value is not a string, but an IO object, either an IOString for small files,
or a Tempfile for larger ones.
This object also has the additional singleton methods:
local_path(): the path of the uploaded file on the local filesystem
original_filename(): the name of the file on the client computer
content_type(): the content type of the file
2008年11月25日 星期二
2008年11月24日 星期一
request
http://api.rubyonrails.org/classes/ActionController/AbstractRequest.html#M000461
domain(tld_length = 1)
content_type()
headers()
host()
host_with_port()
path_parameters()
path()
parameters()
port()
post?()
put?()
remote_ip()
request_uri()
subdomains(tld_length = 1)
domain(tld_length = 1)
content_type()
headers()
host()
host_with_port()
path_parameters()
path()
parameters()
port()
post?()
put?()
remote_ip()
request_uri()
subdomains(tld_length = 1)
2008年11月20日 星期四
asset_host
http://chadfowler.com/2007/2/18/edge-rails-goody-distributed-asset-hosts
http://ihower.idv.tw/blog/archives/1707
Rails 還有個功能是可以設定 asset_host,方便你把靜態檔案(即 /public 目錄)用更快速便宜的 web server 提供 (別讓 mongrel 直接提供這些靜態檔案啊),像 Registrano 就乾脆把所有靜態檔案放在另一台網路稍快的 server 上:
# /config/environments/production.rb
config.action_controller.asset_host = 'http://asset.example.org"
Rails2 更支援可以同時分散到四台 asset0~asset3,只要加%d (當然你的 DNS 也要設好,最簡單的作法可以指到同一台 server)
# /config/environments/production.rb
config.action_controller.asset_host = 'http://asset%d.example.org"
好處是可以讓 browser 同時平行下載 (單一 domain 的下載最多同時兩個 persistent connections, see HTTP連線管理一文),因此如果你的網站靜態檔案(如圖檔)很多的話,應該會有不錯的效果。不過在 Registrano 實測效果並沒有很好,這是因為 DNS Lookup 也要花時間(即上述第9點)
P.S. 使用 asset host 的一個副作用是 cross domain 問題,因此吃了不少 Javascript library 苦頭。
http://ihower.idv.tw/blog/archives/1707
Rails 還有個功能是可以設定 asset_host,方便你把靜態檔案(即 /public 目錄)用更快速便宜的 web server 提供 (別讓 mongrel 直接提供這些靜態檔案啊),像 Registrano 就乾脆把所有靜態檔案放在另一台網路稍快的 server 上:
# /config/environments/production.rb
config.action_controller.asset_host = 'http://asset.example.org"
Rails2 更支援可以同時分散到四台 asset0~asset3,只要加%d (當然你的 DNS 也要設好,最簡單的作法可以指到同一台 server)
# /config/environments/production.rb
config.action_controller.asset_host = 'http://asset%d.example.org"
好處是可以讓 browser 同時平行下載 (單一 domain 的下載最多同時兩個 persistent connections, see HTTP連線管理一文),因此如果你的網站靜態檔案(如圖檔)很多的話,應該會有不錯的效果。不過在 Registrano 實測效果並沒有很好,這是因為 DNS Lookup 也要花時間(即上述第9點)
P.S. 使用 asset host 的一個副作用是 cross domain 問題,因此吃了不少 Javascript library 苦頭。
標籤:
asset_host
2008年11月19日 星期三
module,extend,composed_of,advanced-activerecord
http://giantrobots.thoughtbot.com/2008/6/2/slides-from-railsconf
http://api.rubyonrails.org/classes/ActiveRecord/Aggregations/ClassMethods.html#M001663
http://www.ruby-doc.org/core/classes/Object.html#M000337
有類似的class method, validates, 就把他弄進module 裡
http://api.rubyonrails.org/classes/ActiveRecord/Aggregations/ClassMethods.html#M001663
http://www.ruby-doc.org/core/classes/Object.html#M000337
有類似的class method, validates, 就把他弄進module 裡
標籤:
composed_of,
extend,
module
validate,class,define_method,exists?,[],array
http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#M001640
http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M001701
Possible gotcha: You can‘t pass in a condition as a string e.g. "name = ‘Jamie’", this would be sanitized and then queried against the primary key column as "id = ‘name = \’Jamie"
原來這種要這樣設
http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M001701
Possible gotcha: You can‘t pass in a condition as a string e.g. "name = ‘Jamie’", this would be sanitized and then queried against the primary key column as "id = ‘name = \’Jamie"
原來這種要這樣設
2008年11月18日 星期二
validate,before,create,define_method,callback
http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html#M001618
http://www.ruby-doc.org/core/classes/Module.html#M001682
* (-) save
* (-) valid
* (1) before_validation
* (2) before_validation_on_create
* (-) validate
* (-) validate_on_create
* (3) after_validation
* (4) after_validation_on_create
* (5) before_save
* (6) before_create
* (-) create
* (7) after_create
* (8) after_save
define_method: 動態產生method 的好物
http://www.ruby-doc.org/core/classes/Module.html#M001682
* (-) save
* (-) valid
* (1) before_validation
* (2) before_validation_on_create
* (-) validate
* (-) validate_on_create
* (3) after_validation
* (4) after_validation_on_create
* (5) before_save
* (6) before_create
* (-) create
* (7) after_create
* (8) after_save
define_method: 動態產生method 的好物
2008年11月17日 星期一
cookie_store,session
http://railscasts.com/episodes/84-cookie-based-session-store
http://izumi.plan99.net/blog/index.php/2007/11/25/rails-20-cookie-session-store-and-security/
http://blog.caboo.se/articles/2007/2/21/new-controversial-default-rails-session-storage-cookies
http://stackoverflow.com/questions/192153/what-is-the-best-way-to-read-the-rails-session-secret
http://hi.baidu.com/holin/blog/item/36b9b21127f85e7ccb80c45e.html
http://api.rubyonrails.org/classes/ActionController/SessionManagement/ClassMethods.html#M000299
actionpack-2.1.2/lib/action_controller/session/cookie_store.rb
BAh7ByIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo%0ASGF
zaHsABjoKQHVzZWR7ADoNbG9naW5faWQw--b410e484d58fa0b31c5e778115c66ea29a220af8
-- 前面是data的部份, 後面是digest的部份, data可以讓user 去decode 沒關係, 但是digest的部份有加上secret 去做encode, 所以可以用來辨識這是不是我們網站自己產生合法的cookie
http://izumi.plan99.net/blog/index.php/2007/11/25/rails-20-cookie-session-store-and-security/
http://blog.caboo.se/articles/2007/2/21/new-controversial-default-rails-session-storage-cookies
http://stackoverflow.com/questions/192153/what-is-the-best-way-to-read-the-rails-session-secret
http://hi.baidu.com/holin/blog/item/36b9b21127f85e7ccb80c45e.html
http://api.rubyonrails.org/classes/ActionController/SessionManagement/ClassMethods.html#M000299
actionpack-2.1.2/lib/action_controller/session/cookie_store.rb
BAh7ByIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo%0ASGF
zaHsABjoKQHVzZWR7ADoNbG9naW5faWQw--b410e484d58fa0b31c5e778115c66ea29a220af8
-- 前面是data的部份, 後面是digest的部份, data可以讓user 去decode 沒關係, 但是digest的部份有加上secret 去做encode, 所以可以用來辨識這是不是我們網站自己產生合法的cookie
2008年11月15日 星期六
adv cache,memcahe
http://nubyonrails.com/articles/about-this-blog-memcached
http://blog.leetsoft.com/2007/5/22/the-secret-to-memcached
http://blog.craigambrose.com/past/2007/11/13/caching_makes_your_brain_explode/
http://ryandaigle.com/articles/2007/12/19/what-s-new-in-edge-rails-pluggable-controller-caching
http://wiki.rubyonrails.org/rails/pages/MemCached
http://ihower.idv.tw/blog/archives/1768
http://www.ibm.com/developerworks/cn/web/wa-rails1/
http://blog.leetsoft.com/2007/5/22/the-secret-to-memcached
http://blog.craigambrose.com/past/2007/11/13/caching_makes_your_brain_explode/
http://ryandaigle.com/articles/2007/12/19/what-s-new-in-edge-rails-pluggable-controller-caching
http://wiki.rubyonrails.org/rails/pages/MemCached
http://ihower.idv.tw/blog/archives/1768
http://www.ibm.com/developerworks/cn/web/wa-rails1/
Don’t Expire, Just Render it Obsolete
So, here’s my first bit of advice. If you’re building a real site, go straight to memcache. If you’re not building a site for big traffic, don’t cache, just optimise any really stupid queries that are giving you trouble. If you’re using memcache, be sure to run monit too.2008年11月14日 星期五
雷霆王
http://www.ananedu.com/1230/b151.htm
六神合一的雷霆王 嗚~嗚~嗚
六神合一的雷霆王 嗚~嗚~嗚
保衛地球的安全我當先
對抗入侵的異形人不後人
六神合一的雷霆王 嗚~嗚~嗚
六神合一的雷霆王 嗚~嗚~嗚
保衛地球的安全我當先
對抗入侵的異形人不後人
六神合一的雷霆王 嗚~嗚~嗚
六神合一的雷霆王 嗚~嗚~嗚
啦...雷霆王~雷霆王
雷霆王是中視卡通,播出時間為780331~790629每週五下午五點。故事的主角是馬茲,他原是吉星人,在嬰兒時期即被送往地球,地球人收養了馬茲,為他取了個名字叫佩華,佩華長大後成為地球防衛軍的一員。一日地球遭莫名外星人攻擊,佩華發現入侵人會超能力,也在同時發現自己也有超能力,大戰數回合之後,外星人為佩華所打敗,對方於是呼喚機器人,佩華為機器人所敗,在生死交關之際,突然有個機器人來與佩華合體,是個紅色機器人,或可說是主機,當這主機遭遇困難時,又會有五架機器人飛來,最後又可組成六神合體的雷霆王,雷霆王一出來就不會輸。原來是吉星人要征服地球,於是要佩華的父親製造機械人,也就是雷霆王的主機,只要佩華一死,這主機便會產生可怕的核子反應,並進而消滅地球,可是佩華的父親卻另外造了五架機械人,這五個機械人便可和紅色主機結合成雷霆王。佩華最後終於摧毀了吉星人的野心,其實吉星人也不是真的野心很大,而是在其背後有個可怕的惡魔,這個惡魔名叫族魯,本來佩華是要以自身的滅亡來和族魯同歸於盡,可是還沒用族魯便被幹掉。到這裡是第一段落,佩華有個哥哥名叫馬可,因為不會超能力,所以常被排擠也常被忽視,但他長得非常俊俏,不過這和劇情沒什麼關係,也因為有馬可的幫助,佩華才能在許多的戰役中獲勝,可是馬可在第一段時便死掉了。第二個段落是某日有個外星女子來到了地球,原來他是被追殺的陰極超能力者,在她們的星球每個人都有超能力,但是超能力有分陰陽兩極,陰極超能力者被陽極超能力者追殺,殺到最後還是被佩華搞定,不過這場戰役是兩個組織對打,打到最後又發現是族魯搞的鬼,這是第二段落。第三段是形態人和馬茲對打,這時馬茲被套上了惡魔手環,每當佩華使用一次雷霆王,便會受到惡魔手環的痛苦煎熬,和孫悟空差不多吧!可是每當佩華在痛苦爭扎時都會聽到一句話:”燃燒的火焰,赤熱的星球”原來那星球便是太陽,那麼這句話又是誰說的呢?這句話便是馬可所說的,可是馬可不是死了嗎?好像是用托夢的,佩華到了太陽之後,馬可便為他解開了惡魔手環,最後終於打敗了族魯,可是就在這時,族魯手下的形態人好像是有七人吧!這七人合在一起又組成了族魯,天啊!這一次族魯又再次被打敗,好像族真的被打敗了,因為雷霆王真的沒有再演了。
yaml,load_file
http://corelib.rubyonrails.org/classes/YAML.html
yml file
>>YAML.load_file("file_name")
>>{"defaults"=>{"sessions"=>false, "ttl"=>1800, "readonly"=>false, "fragments"=>true, "c_threshold"=>10000, "benchmarking"=>true, "namespace"=>"youholder", "debug"=>false, "servers"=>"localhost:11212", "urlencode"=>false, "compression"=>true}}
yml file
defaults:
ttl: 1800
readonly: false
urlencode: false
c_threshold: 10000
compression: true
debug: false
namespace: lalala
sessions: false
fragments: true
servers: localhost:11212
benchmarking: true
>>YAML.load_file("file_name")
>>{"defaults"=>{"sessions"=>false, "ttl"=>1800, "readonly"=>false, "fragments"=>true, "c_threshold"=>10000, "benchmarking"=>true, "namespace"=>"youholder", "debug"=>false, "servers"=>"localhost:11212", "urlencode"=>false, "compression"=>true}}
cache in rails 2.1
http://railscasts.com/episodes/115-caching-in-rails-2-1
http://thewebfellas.com/blog/2008/6/9/rails-2-1-now-with-better-integrated-caching
cache的用法
有幾種cache 機制
自己生個cache object
幫助你生cache_key
memcachestore 是production 常選用的方式, default 存入是存成marshal
http://thewebfellas.com/blog/2008/6/9/rails-2-1-now-with-better-integrated-caching
cache的用法
有幾種cache 機制
自己生個cache object
幫助你生cache_key
memcachestore 是production 常選用的方式, default 存入是存成marshal
Marshal
http://www.ruby-doc.org/core/classes/Marshal.html
Ruby can take an object and convert it into a stream of bytes that can be stored
outside the application. This process is called marshaling. This saved object
can later be read by another instance of the application (or by a totally separate
application), and a copy of the originally saved object can be reconstituted
2008年11月13日 星期四
使用METHOD_MISSING時請小心
rex.respond_to? :bark #=> false <= 我們用respond_to? 檢查時會以為沒有這東西
rex.bark #=> woofwoof!
所以要加上 repsond_to?(method) method
標籤:
method_missing
tasks,ruby1.9
ruby script/dbconsole
另外,在Ruby 1.9中去掉了Base64模組(base64.rb),因此在Rails中所有使用這個模組的都得
修改為ActiveSupport::Base64
另外,在Ruby 1.9中去掉了Base64模組(base64.rb),因此在Rails中所有使用這個模組的都得
修改為ActiveSupport::Base64
blog 貼code
http://morten.lyhr.dk/2007/12/how-to-get-syntax-highlighting-in.html
http://yehhou.blogspot.com/2007/06/blogger-dpsyntaxhighlighter.html
下面這些貼在 head tag 裡
<link type="text/css" rel="stylesheet" href="http://lake.ilakela.googlepages.com/SyntaxHighlighter.css"></link>
下面的放在 body tag 前
http://yehhou.blogspot.com/2007/06/blogger-dpsyntaxhighlighter.html
下面這些貼在 head tag 裡
<link type="text/css" rel="stylesheet" href="http://lake.ilakela.googlepages.com/SyntaxHighlighter.css"></link>
下面的放在 body tag 前
Destroy Without JavaScript
http://railscasts.com/episodes/77-destroy-without-javascript
<!-- projects/index.rhtml -->
<ul>
<% for project in @projects %>
<li>
<%=h project.name %>
<%= link_to_destroy "Destroy", project_path(project), confirm_destroy_project_path(project) %>
</li>
<% end %>
</ul>
<!-- projects/confirm_destroy.rhtml -->
<% form_for :project, :url => project_path(@project), :html => { :method => :delete } do |f| %>
<h2>Are you sure you want to destroy this project?</h2>
<p>
<%= submit_tag "Destroy" %>
or <%= link_to "cancel", projects_path %>
</p>
<% end %>
# routes.rb
map.resources :projects, :member => { :confirm_destroy => :get }
# projects_controller.rb
def confirm_destroy
@project = Project.find(params[:id])
end
# projects_helper.rb
def link_to_destroy(name, url, fallback_url)
link_to_function name, "confirm_destroy(this, '#{url}')", :href => fallback_url
end
/* application.js */
function confirm_destroy(element, action) {
if (confirm("Are you sure?")) {
var f = document.createElement('form');
f.style.display = 'none';
element.parentNode.appendChild(f);
f.method = 'POST';
f.action = action;
var m = document.createElement('input');
m.setAttribute('type', 'hidden');
m.setAttribute('name', '_method');
m.setAttribute('value', 'delete');
f.appendChild(m);
f.submit();
}
return false;
}
2008年11月12日 星期三
regexp,uri,cgi,encode,decode
http://snippets.dzone.com/posts/show/5180
http://ruby-doc.org/stdlib/libdoc/uri/rdoc/classes/URI/Escape.html#M009386
http://ruby-doc.org/stdlib/libdoc/cgi/rdoc/classes/CGI.html#M000091
[^abc]
Any single character but a, b, or c
1
2 require 'cgi'
3
4 # escape
5 name = "ruby?"
6 value = "yes"
7 url = "http://example.com/?" + CGI.escape(name) + '=' + CGI.escape(value) + "&var=T"
8 # url: http://example.com/?ruby%3F=yes&var=T
9 html = %(<a href="#{CGI.escapeHTML(url)}">example</a>)
10 # html: <a href="http://example.com/?ruby%3F=yes&var=T">example</a>
11
12 # unescape
13 name_encoded = html.match(/http:([^"]+)/)[0]
14 # name_encoded: http://example.com/?ruby%3F=yes&var=T
15 href = CGI.unescapeHTML(name_encoded)
16 # href: http://example.com/?ruby%3F=yes&var=T
17 query = href.match(/\?(.*)$/)[1]
18 # query: ruby%3F=yes&var=T
19 pairs = query.split('&')
20 # pairs: ["ruby%3F=yes", "var=T"]
21 name, value = pairs[0].split('=').map{|v| CGI.unescape(v)}
22 # name, value: ["ruby?", "yes"]
command,route,respond
1)rake routes 可以秀出所有的route 跟其對應的function
2)就算沒有特別寫respond_to ,rails 也會根據format 去找其相退應的file
2)就算沒有特別寫respond_to ,rails 也會根據format 去找其相退應的file
標籤:
respond_to,
routes
atom_feed,rss
http://railscasts.com/episodes/87-generating-rss-feeds
http://svn.rubyonrails.org/rails/plugins/atom_feed_helper/README
http://api.rubyonrails.com/classes/ActionView/Helpers/AtomFeedHelper.html#M001208
http://hideto.javaeye.com/blog/84463
http://snippets.dzone.com/tags/ruby/blinksale
http://railspikes.com/2008/10/1/publishing-non-activerecord-objects-in-an-atom-feed-with-rails
http://svn.rubyonrails.org/rails/plugins/atom_feed_helper/README
http://api.rubyonrails.com/classes/ActionView/Helpers/AtomFeedHelper.html#M001208
http://hideto.javaeye.com/blog/84463
http://snippets.dzone.com/tags/ruby/blinksale
http://railspikes.com/2008/10/1/publishing-non-activerecord-objects-in-an-atom-feed-with-rails
atom_feed do |feed|
feed.title("All User Books!")
feed.updated((@users.first.created_at))
for user in @users
feed.entry(user) do |entry|
entry.title(user.name)
entry.content(user.name, :type => 'html')
entry.books do |books| <= 幹 這個地方不用再傳東西, entry.book(fuck)
for b in user.books
books.title(b.name)
end
end
end
end
end
<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
<id>tag:localhost,2005:/people</id>
<link type="text/html" rel="alternate" href="http://localhost:25001"/>
<link type="application/atom+xml" rel="self" href="http://localhost:25001/people.atom"/>
<title>My great blog!</title>
<updated>2008-11-04T00:31:17Z</updated>
<entry>
<id>tag:localhost,2005:User/1</id>
<published>2008-11-04T00:31:17Z</published>
<updated>2008-11-04T00:31:17Z</updated>
<link type="text/html" rel="alternate" href="http://localhost:25001/people/1"/>
<title>ilake</title>
<content type="html">ilake</content>
<books>
<title>book123</title>
<title>bbbb</title>
</books>
</entry>
<entry>
<id>tag:localhost,2005:User/2</id>
<published>2008-11-09T16:39:09Z</published>
<updated>2008-11-09T16:39:09Z</updated>
<link type="text/html" rel="alternate" href="http://localhost:25001/people/2"/>
<title>lake2</title>
<content type="html">lake2</content>
<books>
<title>[lake2]lake 2 book</title>
</books>
</entry>
</feed>
2008年11月11日 星期二
strain, 寫成這樣好醜 XD
if params[:type]
SmsRecord.sys
else
SmsRecord.purchase
end.find(:all, :conditions => cond).each do |row|
csv << [row.id, row.sms_purchase_record_id, row.user_id, row.send_to_sms_at.strftime('%Y/%m/%d %H:%M'), row.sms_rsp_code]
end
Complex Forms
http://railscasts.com/episodes/73
http://railscasts.com/episodes/74
http://railscasts.com/episodes/75
http://api.rubyonrails.org/classes/ActionView/Helpers/PrototypeHelper/JavaScriptGenerator/GeneratorMethods.html#M001254
http://api.rubyonrails.org/classes/ActionView/Helpers/JavaScriptHelper.html#M001341
http://railscasts.com/episodes/74
http://railscasts.com/episodes/75
http://api.rubyonrails.org/classes/ActionView/Helpers/PrototypeHelper/JavaScriptGenerator/GeneratorMethods.html#M001254
http://api.rubyonrails.org/classes/ActionView/Helpers/JavaScriptHelper.html#M001341
[View edit.rhtml]
<div id='books'>
<%= render :partial => 'book', :collection => @user.books %>
</div>
<%= add_book_link 'add book'%>
[user helper]
module UsersHelper
def add_book_link(name)
link_to_function name do |page|
page.insert_html :bottom, :books, :partial => 'book', :object => Book.new
end
end
end
[View book partial]
<% fields_for "user[books][]", book do |b| %>
<%= b.text_field :name %>
<%= link_to_function 'remove', "this.up('.book').remove()"%>
<% end %>
下面是強化版
[view, edit.rhtml]
<div class='book'>
<% fields_for "user[books][]", book, :index => nil do |b| %>
<%= b.text_field :name %>
<% if book.new_record?%>
<%= link_to_function 'remove', "this.up('.book').remove()" %><br /> <= 單純移掉 html, 反正是new出來的還沒存
<% else %>
<%= link_to_function 'remove', 'mark_for_destory(this)' %>
<%= b.hidden_field :id %> <= 原有的 object 把 id藏起來
<%= b.hidden_field :should_destroy, :class => 'should_destroy' %> <= 用來記真的要砍的記號
<% end %>
<% end %>
</div>
[js application.js]
function mark_for_destory(element) {
$(element).next('.should_destroy').value = 1; <= 做了記號後
$(element).up('.book').hide(); <= 藏起來
}
[Controller, user_controller.rb]
@user.update_attributes(params[:user])
[Model book.rb]
attr_accessor :should_destroy
def should_destroy?
should_destroy.to_i == 1
end
[Model user.rb]
after_update :save_books
def books=(books_attrs)
books_attrs.each do |attrs|
if attrs[:id].blank? <= 如果id是空的就是需要new的
books.build(attrs)
else
book = books.detect{|b| b.id == attrs[:id].to_i}
book.attributes = attrs <= 這時上面那些有被destroy 的 should_destroy 也會被給值
end
end
end
def save_books <= parent object update_attribute would not update the children attribute, so we need to save by ourself
books.each do |book|
if book.should_destroy?
book.destroy
else
book.save # if Calling save(false) saves the model without running validations.
end
end
end
2008年11月10日 星期一
clone
http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M001761
Returns a clone of the record that hasn‘t been assigned an id yet and is treated as a new record. Note that this is a "shallow" clone: it copies the object‘s attributes only, not its associations. The extent of a "deep" clone is application-specific and is therefore left to the application to implement according to its need.
Returns a clone of the record that hasn‘t been assigned an id yet and is treated as a new record. Note that this is a "shallow" clone: it copies the object‘s attributes only, not its associations. The extent of a "deep" clone is application-specific and is therefore left to the application to implement according to its need.
>> u = User.first
=> #<User id: 1, name: "ilake", created_at: "2008-11-04 00:31:17", updated_at: "2008-11-04 00:31:17">
>> uc = u.clone
=> #<User id: nil, name: "ilake", created_at: "2008-11-04 00:31:17", updated_at: "2008-11-04 00:31:17">
>> uc.books
=> []
>> uc.name
=> "ilake"
>> uc.new_record?
=> true
with_options
http://railscasts.com/episodes/42-with-options
map.with_options :controller => 'membercenter' do |t|
t.partner_login 'membercenter/plogin', :action => 'partner_login'
t.partner_signup 'membercenter/psignup', :action => 'partner_signup'
t.partner_logout 'membercenter/plogout', :action => 'partner_logout'
t.default 'membercenter/:action'
end
def index
FaqCommon.with_options :order => "created_at DESC", :limit => 9 do |faqcommon|
@member_faqs = faqcommon.find(:all, :conditions => ["title_type = ?", 0] )
@use_faqs = faqcommon.find(:all, :conditions => ["title_type = ?", 1] )
end
end
標籤:
with_options
Handle Multiple Models in One Form Handle Multiple Models in One Form
http://www.pragprog.com/titles/fr_arr/advanced-rails-recipes
http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#M001198
Recipe 13
http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#M001198
Recipe 13
[View, edit.rhtml]
<% form_for(@user) do |f| %>
<%= f.text_field :name %>
<% for book in @user.books %>
<% fields_for "user[books][]", book do |b| %> <= 用fields_for的方法注意
<%= b.text_field :name %>
<% end %>
<% end %>
<%= f.submit "Update" %>
<% end %>
[user controller, update action]
def update
@user = User.find(params[:id])
if @user.update_attributes(params[:user])
flash[:notice] = 'User and books was successfully updated.'
redirect_to(@user)
end
params[:user] 是長像這樣的東西 {"name" => "ilake",
"books" => {"1"=>{"name"=>"book1"}, "2"=>{"name"=>"book2"}}}
update_attributes 就是去做 @user.name = 'ilake'
@user.books = {"1"=>{"name"=>"book1"}, "2"=>{"name"=>"book2"}} 的動作
end
[user model]
class User < ActiveRecord::Base
has_many :books, :dependent => :destroy
has_one :couple
validates_presence_of :name
after_update :save_books
def books=(books_attrs) <= 因為controller 的@user.update_attributes 被叫到
books.reject(&:new_record?).each do |book| <= 檢查這是不是新的record, 這邊是update 新的不要
attributes = books_attrs[book.id.to_s]
if attributes
book.attributes = attributes
else
books.delete(book)
end
end
end
def save_books
books.each do |book|
book.save(false) # Calling save(false) saves the model without running validations.
end
end
end
標籤:
fields_for,
rails,
recipe
text_field,form
http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#M001197
<% form_tag :action => 'edit_all' do %>
<% for @user in @users %> <= 一定要用@user, for iterator 才能這樣用
<%= text_field('user[]', 'name') %> <= []會自己讓他塞id, 變成 <input type="text" value="ilake" size="30" name="user[1][name]" id="user_1_name"/>
<% fields_for @user.couple do |couple| %>
<%= couple.text_field :name %>
<% end %>
<% end %>
<%= submit_tag 'EDIT_ALL'%>
<% end %>
標籤:
form,
text_field
2008年11月9日 星期日
rails,json
[view]
<script type="text/javascript">
(function($){
$(document).ready(function(){
var user_id = {};
user_id['user_id'] = '<%= @user.id %>';
$.ajax({
url: '/people/<%= @user.id %>/books',
type: 'GET',
data: user_id,
dataType: 'json', <= 要指定型態
success:function(data){ <= 出來是個json object array
$.each(data, function(){
$('#script').append('<li>'+this.book.name+'</li>');
});
}
});
});
})(jQuery);
</script>
<ul id='script'></ul>
[controller ]
def index
@books = @user.books.find(:all)
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @books.to_xml }
format.js { render :json => @books.to_json }
format.yaml { render :text => @books.to_yaml }
end
end
2008年11月7日 星期五
Iconv.conv big5 轉 utf8 , response
http://twycf.com/wordpress/archives/155
http://tzangms.com/blog/programming/1314
http://tzangms.com/blog/programming/1314
def reply_list
html = GOOKUS_CACHE.get("nownews_reply_list_#{@nng.id}") <= get from memcache
unless html
@gookus = @nng.children.find(:all, :include => :user, :limit => limit, :order => 'created_at DESC')
html = render_to_string(:template => 'gookus/nownews', :layout => false)
GOOKUS_CACHE.set("nownews_reply_list_#{@nng.id}", html, 1.day) <= set into memcache
end
unless params[:encoding] == 'utf8'
html = Iconv.conv('big5','utf8',html) <= 把html 內容 的編碼 utf8轉成 big5
response.charset='big5' <= charset 也要改
end
response.content_type= "text/javascript"<= 是要丟一個js回去 render js
render :text => "document.write('#{escape_javascript(html)}' <= escape 過 內容
end
2008年11月6日 星期四
ActiveResource
http://www.ryandaigle.com/articles/2006/06/30/whats-new-in-edge-rails-activeresource-is-here#REST
http://www.therailsway.com/2007/9/3/using-activeresource-to-consume-web-services
http://ihower.idv.tw/blog/archives/1565
http://wiki.rubyonrails.org/rails/pages/ActiveResource
http://www.therailsway.com/2007/9/3/using-activeresource-to-consume-web-services
http://ihower.idv.tw/blog/archives/1565
http://wiki.rubyonrails.org/rails/pages/ActiveResource
class Auction < ActiveResource::Base
self.site = ‘http://localhost:3000’
end
標籤:
ActiveResource
verify
http://api.rubyonrails.org/classes/ActionController/Verification/ClassMethods.html#M000336
verify :method => :post,
:only => [ :goto ],
:redirect_to => { :action => :index }
2008年11月5日 星期三
cache,page
http://www.javaworld.com.tw/jute/post/view?bid=59&id=191117&sty=3&age=0&tpg=1&ppg=1
http://api.rubyonrails.org/classes/ActionController/Caching/Pages.html#M000282
http://api.rubyonrails.org/classes/ActionController/Caching/Pages.html#M000282
# In Rails 2.1 you can use :if option
caches_page :index, :if => Proc.new { |c| !c.request.format.json? } <=不是json才會cache
routes,conditions,requirement
map.with_options :conditions => { :subdomain => MIRRORS_REGEX} do |goyou_map|
goyou_map.target 'target/:type/:type_id/:sort',
:controller => 'target', :action => 'index',
:defaults => { :sort => 'target_id'
},
:requirements => { :type => /(category)|(concept)/,
:sort => /(target_id)|(change_rate)|(volume)/
}
end
conditions <= 必須符合這個條件才會apply, 不符合就繼續往下找
requirement <= 會符合這個 rule, 但是 paramter 需符合 requirement
rest, options
map.resources :users, as => 'people' do |user|
user.resources :books, :collection => {:list => :get},
:member => {:add_title => :put},
:singular => 'lala'
end
<% for book in @books %>
<tr>
<td><%= book.name %></td>
<td><%= link_to 'Show', user_lala_path(@user, book) %></td>
<td><%= link_to 'Edit', edit_user_lala_path(@user, book) %></td>
<td><%= link_to 'add_title', add_title_user_lala_path(@user, book), :method => :put %></td>
<td><%= link_to 'Destroy', user_lala_path(@user, book), :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New book', new_user_lala_path(@user) %>
<%= link_to 'GoTo user index', users_url %>
<%= link_to 'All books', list_user_books_url(@user) %> <= plural 的還是一樣 沒變成lalas
http://localhost:25001/people/1/books <= 生出的 uri
2008年11月3日 星期一
REST & RESTful & resources
http://ihower.idv.tw/blog/archives/1542
http://ihower.idv.tw/blog/archives/1545
http://ihower.idv.tw/blog/archives/1543
http://ihower.idv.tw/blog/archives/1561
http://api.rubyonrails.org/classes/ActionController/Resources.html#M000337
http://ihower.idv.tw/blog/archives/1541
http://www.prescod.net/rest/mistakes/
http://www.xml.com/pub/a/2004/03/17/udell.html
http://en.wikipedia.org/wiki/REST
http://ihower.idv.tw/blog/archives/1634
http://ihower.idv.tw/blog/archives/1545
http://ihower.idv.tw/blog/archives/1543
http://ihower.idv.tw/blog/archives/1561
http://api.rubyonrails.org/classes/ActionController/Resources.html#M000337
http://ihower.idv.tw/blog/archives/1541
http://www.prescod.net/rest/mistakes/
http://www.xml.com/pub/a/2004/03/17/udell.html
http://en.wikipedia.org/wiki/REST
http://ihower.idv.tw/blog/archives/1634
2008年11月2日 星期日
訂閱:
文章 (Atom)