2008年11月29日 星期六

MySQL for Hosting Providers - how do they manage ?

MySQL for Hosting Providers - how do they manage ?

Computing 95 percentile in MySQL

Computing 95 percentile in MySQL

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"

超簡單 very simple merb upload file

http://blog.vixiom.com/2007/06/29/merb-on-air-drag-and-drop-multiple-file-upload/
http://iceskysl.1sters.com/?action=show&id=368&page=1
http://www.mikeperham.com/2007/10/02/file-uploads-in-merb-versus-rails/


幹 竟然這樣寫

How to reset a lost mysql root password

http://www.simplehelp.net/2008/11/26/how-to-reset-a-lost-mysql-root-password/

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/


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日 星期二

yaml,load_file

http://ithelp.ithome.com.tw/question/10012281

RESTful CSS

http://www.digital-web.com/articles/RESTful_CSS/


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)

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 苦頭。

2008年11月19日 星期三

session,model,railscast

http://railscasts.com/episodes/119-session-based-model


module,class_eval,extend

http://giantrobots.thoughtbot.com/2008/6/2/slides-from-railsconf
http://www.ruby-doc.org/core/classes/Object.html#M000337

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 裡



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"


原來這種要這樣設

2008年11月18日 星期二

with_scope and with_options

with_scope 和 with_options的用法

session,scope,rjs,option

http://railscasts.com/episodes/103-site-wide-announcements



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 的好物


step 這樣用

http://www.ruby-doc.org/core/classes/Range.html#M000708

respond_to,Graceful Degradation


Graceful Degradation

Caching with Instance Variables

http://railscasts.com/episodes/1-caching-with-instance-variables

Dangers of Model in Session

http://railscasts.com/episodes/13

validate,valid?

http://api.rubyonrails.org/classes/ActiveRecord/Validations.html#M001627

[JavaScript] 複製物件,copy,clone

http://blog.roodo.com/jaceju/archives/7611083.html

2008年11月17日 星期一

adv session,cookie

http://www.quarkruby.com/2007/10/21/sessions-and-cookies-in-ruby-on-rails
http://errtheblog.com/posts/22-sessions-n-such
http://scott.elitists.net/sessions.html
http://railscasts.com/episodes/13

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

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/


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每週五下午五點。故事的主角是馬茲,他原是吉星人,在嬰兒時期即被送往地球,地球人收養了馬茲,為他取了個名字叫佩華,佩華長大後成為地球防衛軍的一員。一日地球遭莫名外星人攻擊,佩華發現入侵人會超能力,也在同時發現自己也有超能力,大戰數回合之後,外星人為佩華所打敗,對方於是呼喚機器人,佩華為機器人所敗,在生死交關之際,突然有個機器人來與佩華合體,是個紅色機器人,或可說是主機,當這主機遭遇困難時,又會有五架機器人飛來,最後又可組成六神合體的雷霆王,雷霆王一出來就不會輸。原來是吉星人要征服地球,於是要佩華的父親製造機械人,也就是雷霆王的主機,只要佩華一死,這主機便會產生可怕的核子反應,並進而消滅地球,可是佩華的父親卻另外造了五架機械人,這五個機械人便可和紅色主機結合成雷霆王。佩華最後終於摧毀了吉星人的野心,其實吉星人也不是真的野心很大,而是在其背後有個可怕的惡魔,這個惡魔名叫族魯,本來佩華是要以自身的滅亡來和族魯同歸於盡,可是還沒用族魯便被幹掉。到這裡是第一段落,佩華有個哥哥名叫馬可,因為不會超能力,所以常被排擠也常被忽視,但他長得非常俊俏,不過這和劇情沒什麼關係,也因為有馬可的幫助,佩華才能在許多的戰役中獲勝,可是馬可在第一段時便死掉了。第二個段落是某日有個外星女子來到了地球,原來他是被追殺的陰極超能力者,在她們的星球每個人都有超能力,但是超能力有分陰陽兩極,陰極超能力者被陽極超能力者追殺,殺到最後還是被佩華搞定,不過這場戰役是兩個組織對打,打到最後又發現是族魯搞的鬼,這是第二段落。第三段是形態人和馬茲對打,這時馬茲被套上了惡魔手環,每當佩華使用一次雷霆王,便會受到惡魔手環的痛苦煎熬,和孫悟空差不多吧!可是每當佩華在痛苦爭扎時都會聽到一句話:”燃燒的火焰,赤熱的星球”原來那星球便是太陽,那麼這句話又是誰說的呢?這句話便是馬可所說的,可是馬可不是死了嗎?好像是用托夢的,佩華到了太陽之後,馬可便為他解開了惡魔手環,最後終於打敗了族魯,可是就在這時,族魯手下的形態人好像是有七人吧!這七人合在一起又組成了族魯,天啊!這一次族魯又再次被打敗,好像族真的被打敗了,因為雷霆王真的沒有再演了。

db,connection,execute,sql

http://wiki.rubyonrails.org/rails/pages/HowtoQueryTheDatabaseDirectly
http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M001794

yaml,load_file

http://corelib.rubyonrails.org/classes/YAML.html

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}}

memcached,cache

http://bbs.railschina.com/viewthread.php?tid=535
http://totou-phpmysql.blogspot.com/2008/07/memcached.html
http://www.danga.com/memcached/
http://nubyonrails.com/articles/memcached-basics-for-rails
http://www.gisblogs.net/post/183.html

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

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

tasks,ruby1.9

ruby script/dbconsole

另外,在Ruby 1.9中去掉了Base64模組(base64.rb),因此在Rails中所有使用這個模組的都得
修改為ActiveSupport::Base64

railsties

Rails.public_path
Rails.logger
Rails.root
Rails.env
Rails.cache
Rails.version

rails2.1 gem

http://lightyror.thegiive.net/2008/06/rails-21-gem.html
http://ryandaigle.com/articles/2008/4/1/what-s-new-in-edge-rails-gem-dependencies

Routes recognition

actionpack-2.1.2/lib/action_controller/routing/recognition_optimisation.rb

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 前

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&amp;var=T">example</a>
11
12 # unescape
13 name_encoded = html.match(/http:([^"]+)/)[0]
14 # name_encoded: http://example.com/?ruby%3F=yes&amp;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

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


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

[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.


>> 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

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

[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

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 %>

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日 星期五

polymorphic,rest

http://api.rubyonrails.com/classes/ActionController/PolymorphicRoutes.html#M000307
http://jamesgolick.com/2007/10/11/rails-polymorphic-url-generation-sucks-here-s-something-better

Iconv.conv big5 轉 utf8 , response

http://twycf.com/wordpress/archives/155
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月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


# In Rails 2.1 you can use :if option
caches_page :index, :if => Proc.new { |c| !c.request.format.json? } <=不是json才會cache

session

http://api.rubyonrails.org/classes/ActionController/SessionManagement/ClassMethods.html

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月2日 星期日