2008年8月29日 星期五

form serialize, selector checkbox

http://docs.jquery.com/Ajax/serialize
http://docs.jquery.com/Selectors/checkbox

File, Pathname, Dir

http://www.ruby-doc.org/core/classes/File.html
http://www.ruby-doc.org/core/classes/Pathname.html
http://www.ruby-doc.org/core/classes/Dir.html#M002347

join, dirname, __FILE__, RAILS_ROOT, directory?

require File.join(File.dirname(__FILE__), 'boot')

RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)


>> File.directory?("#{RAILS_ROOT}/app")
=> true
>> File.exist?("#{RAILS_ROOT}/app")
=> true

>> File.exist?("#{RAILS_ROOT}/app/controllers/application.rb")
=> true
>> File.directory?("#{RAILS_ROOT}/app/controllers/application.rb")
=> false

Dir is file, too


Dir["config.?"] #=> ["config.h"]
Dir.glob("config.?") #=> ["config.h"]
Dir.glob("*.[a-z][a-z]") #=> ["main.rb"]
Dir.glob("*.[^r]*") #=> ["config.h"]
Dir.glob("*.{rb,h}") #=> ["main.rb", "config.h"]
Dir.glob("*") #=> ["config.h", "main.rb"]
Dir.glob("*", File::FNM_DOTMATCH) #=> [".", "..", "config.h", "main.rb"]

2008年8月25日 星期一

squish, strip

>> " 11 22 3344 55 ".squish
=> "11 22 3344 55"
>> " 11 22 3344 55 ".strip
=> "11 22 3344 55"

Daemon, SSL, TLS, and many web knowledge

http://en.wikipedia.org/wiki/Daemon_(computer_software)
http://en.wikipedia.org/wiki/Secure_Sockets_Layer
http://en.wikipedia.org/wiki/Transport_Layer_Security
http://gec.kmu.edu.tw/~tjm/security/sec9/img0.html
http://en.wikipedia.org/wiki/Eavesdropping
http://en.wikipedia.org/wiki/Message_forgery
http://en.wikipedia.org/wiki/Information_security
http://en.wikipedia.org/wiki/Cryptography
http://en.wikipedia.org/wiki/Mutual_authentication
http://en.wikipedia.org/wiki/Smtp
http://140.127.138.46/tsnien/Teach_Manu/F8745/F8745_HTML/chap11/chap11-t.htm

ar_mailer memo

http://blog.segment7.net/articles/2006/08/15/ar_mailer
http://www.javaeye.com/topic/38192
http://www.hostingrails.com/forums/rails_coding_thread/150
http://www.hostingrails.com/forums/wiki_thread/2
http://drawohara.com/post/37908300/rails-using-ssl-tls-with-actionmailer-gmail#disqus_thread
http://xslforum.com/28486-re-using-actionmailer-send-email.html

extend association

http://100essays.blogspot.com/2008/03/final-word-on-rails-association.html

The association version is slightly faster then the class version.

extend 的是那些綁在has_many association下的method

2008年8月22日 星期五

type column table rails

type 這個column, 在Rails, 是在STI default 的一個clumn name
所以如果妳用了type, 他就會嘗試去找SUV
然後就會爆 ActiveRecord::SubclassNotFound

要避免這種情況就是要主動告訴Rncails說這不是STI
在model裡設定

set_inheritance_column "not_sti "

2008年8月21日 星期四

polymphic, comment,db

use polymphic 's benefit
would not need the new table, just change the type could be used for the new model

如果model的相似度高例如 comment , 一個網站裡面很多都可以需要comment

就可以用這個


[forum model]
has_many :comments, :as => :record

[record model]
has_many :comments, :as => :record

[comment model]
belongs_to :record, :polymorphic => true

[comments table]
create_table "comments", :force => true do |t|
t.text "content"
t.integer "record_id", :limit => 11, :null => false
t.string "record_type"
end

update_all

http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M001308

  # Update all billing objects with the 3 different attributes given
Billing.update_all( "category = 'authorized', approved = 1, author = 'David'" )

# Update records that match our conditions
Billing.update_all( "author = 'David'", "title LIKE '%Rails%'" )

# Update records that match our conditions but limit it to 5 ordered by date
Billing.update_all( "author = 'David'", "title LIKE '%Rails%'",
:order => 'created_at', :limit => 5 )

time range conditions

Record.find(:all, :conditions => {:todo_time => Time.now.ago(10.days)..Time.now})

has_one, has_many ,through

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#M000979


has_one
  • Account#build_beneficiary (similar to Beneficiary.new("account_id" => id))
  • Account#create_beneficiary (similar to b = Beneficiary.new("account_id" => id); b.save; b)
has_many
  • Firm#clients.build (similar to Client.new("firm_id" => id))
  • Firm#clients.create (similar to c = Client.new("firm_id" => id); c.save; c)


Some examples:

[user model]
has_many :record_comments, :through => :records, :source => :comments, :order => "created_at DESC", :limit => 6

has_many :demands, :foreign_key => 'demander_id', :class_name => 'Call'
has_many :accepts, :foreign_key => 'accepter_id', :class_name => 'Call'

[call model]
belongs_to :demander, :foreign_key => 'demander_id', :class_name => 'User'
belongs_to :accepter, :foreign_key => 'accepter_id', :class_name => 'User'

scope_out, extend


[model : x_alerts.rb]
scope_out :active , :conditions => '(x_alerts.status = "new" Or x_alerts.status = "ebe") AND x_alerts.x_daily_alert_id = 0'
scope_out :history, :conditions => 'x_alerts.status = "ale"'

[model : alert_target.rb]
has_many :x_alert_relationships
has_many :x_alerts, :extend => XAlert::AssociationMethods, :through => :x_alert_relationships


Time db

Time#to_s(:db) ignores Time#zone -- example:

>> Time.mktime(2008, 06, 20, 0, 31, 7).to_s(:db)
=> "2008-06-20 00:31:07"
>> Time.utc(2008, 06, 20, 0, 31, 7).to_s(:db)
=> "2008-06-20 00:31:07"

I am cute


ThickBox BlockUI modal

http://jquery.com/demo/thickbox/
http://malsup.com/jquery/block/

HTML REL and REV Attributes

http://vancouver-webpages.com/META/reltags.detail.html

<LINK rel=help href="http://some.org/help.html">

where http://some.org/help.html is a help page for the current document.

<LINK rev=help href="http://some.org/index.html">

where the current document is a help page for http://some.org/index.html

filter, find

http://manalang.com/jquery/docs/index.html#filter-expr
http://www.learningjquery.com/2008/08/quick-tip-dynamically-add-an-icon-for-external-links


$(document).ready(function() {
$('#extlinks a').filter(function() {
return this.hostname && this.hostname !== location.hostname;
}).after(' <img src="/images/external.png" alt="external link">');
});

filter 可以塞function來parse, return true 才會跑後面的after

link_to anchor name

link_to 'name', user_url(:action => 'list', :anchor => 'here')

anchor

validate if, RAILS_DEFAULT_LOGGER

validates_length_of :content, :in => 1..300, :on => :create, :if => lambda{ |forum| forum.user_id != 1 }

RAILS_DEFAULT_LOGGER.debug("servlet call!!!!#{last_bytestream}")

2008年8月19日 星期二

javascript event this

$('td.goal_del').bind('click', function(){goal_del(null,this );});
function goal_del(del_id,obj) {

cycle 跑馬燈

http://malsup.com/jquery/cycle/

Simple Effects Plugins

http://www.learningjquery.com/2008/02/simple-effects-plugins

2008年8月15日 星期五

Working with Events, part 2

http://www.learningjquery.com/2008/05/working-with-events-part-2
http://www.learningjquery.com/wp-content/themes/jquery/docs.php?fn=clone
http://www.learningjquery.com/2007/09/namespace-your-events
http://docs.jquery.com/Core/jQuery.fn.extend


$('#list3 li.special button').click(function() {
var $parent = $(this).parent();
$parent.clone().insertAfter($parent);
});

$('#list4 li.special button').click(function() {
var $parent = $(this).parent();
$parent.clone(true).append(' I\'m a clone!').insertAfter($parent);
});

clone(true)


Event Namespacing


function addItemNS() {
$('#list7 li.special button')
.unbind('click.addit')
.bind('click.addit', function() {
var $newLi = $('<li class="special">special and new <button>I am new</button></li>');
$(this).parent().after($newLi);
addItemNS();
});
}

$(document).ready(function() {
addItemNS();
// non-rebinding click handler
$('#list7 li.special button').click(function() {
$(this).after(' pressed');
});
});


Unbind by Function Reference

function addItemFinal() {
var $newLi = $('&lt;li class="special"&gt;special and new &lt;button&gt;I am new&lt;/button&gt;&lt;/li&gt;');
$(this).parent().after($newLi);
$('#list8 li.special button')
.unbind('click', addItemFinal)
.bind('click', addItemFinal);
}

$(document).ready(function() {

$('#list8 li.special button').bind('click', addItemFinal);
// non-rebinding click handler
$('#list8 li.special button').click(function() {
$(this).after(' pressed');
});
});

2008年8月14日 星期四

Working with Events, part 1

http://www.learningjquery.com/2008/03/working-with-events-part-1
http://manalang.com/jquery/docs/index.html#insertAfter-expr
http://manalang.com/jquery/docs/index.html#parents
http://www.quirksmode.org/js/events_order.html

Event Delegation. With event delegation, we bind the event handler to a containing element that remains in the DOM and then check for the target of the event.

$(document).ready(function() {
$('#list1 li.special button').click(function() {
var $newLi = $('<li class="special">special and new <button>I am new</button></li>');
$(this).parent().after($newLi);
});
});

$(document).ready(function() {
$('#list2').click(function(event) {
var $newLi = $('<li class="special">special and new <button>I am new</button></li>');
var $tgt = $(event.target);
if ($tgt.is('button'))
$tgt.parent().after($newLi);
}

// next 2 lines show that you've clicked on the ul
var bgc = $(this).css('backgroundColor');
$(this).css({backgroundColor: bgc == '#ffcccc' || bgc == 'rgb(255, 204, 204)' ? '#ccccff' : '#ffcccc'});
});
});

parent(), after(), $(evnet.target), $(this), css()

可以用evnet.target 來取得被trigger的target, $(this)是整個$('#list2')

2008年8月13日 星期三

just sql select, as, relationship

select * from x_alerts as A, alert_targets as B, x_alert_relationships as C where A.status = 'ale' and C.x_alert_id = A.id and C.alert_target_id = B.id and B.user_id = 2590;

這樣加好幾個table 就等於inner join

scope_out :history, :conditions => 'x_alerts.status = "ale"'

XAlert.find_history(:all, :conditions => "id in (select x_alert_id from x_alert_relationships where alert_target_id in (select id from alert_targets where user_id in (#{id})))")

subquery or inner join 誰好 都不一定每種database實作這種東西的方法不同, 自己可以用benchmark測, 不然就是靠知道內部作法的高手 XD


ps:
select id from alert_targets where user_id in (2590);
select id from alert_targets where user_id = 2590;
一樣

2008年8月12日 星期二

Introduction to jQuery UI

http://www.learningjquery.com/2008/07/introduction-to-jquery-ui
http://docs.jquery.com/UI
http://ui.jquery.com/themeroller

jQuery tutorial, find and filter

http://www.learningjquery.com/2006/11/how-to-get-anything-you-want-part-1
http://www.learningjquery.com/2006/12/how-to-get-anything-you-want-part-2

filter will select a certain subset (zero or more) of the already
selected elements.

find will select a set of (zero or more) elements that are descendants
of the already selected elements.

Here is an example:

$('div').filter('.elephants'); // <-- selects the second div, because it has class="elephants"

$('div').find('.elephants'); // <-- selects the first paragraph, because it has class="elephants"

* Note that these two examples are very simple and would probably be
better written as ...

$('div.elephants');

... and ...

$('div .elephants');




$('li + li > a[@href$=pdf]') gets all links ending in
“pdf” that are children of any list item that has another list item as
its previous sibling. It won’t get the first list item’s silly.pdf
because that list item has no other list items before it.

$('span:hidden') gets any span element that is hidden.

$('li:even') gets all odd-numbered list items (because, in javascript, numbering starts with 0, not 1).

$('li:lt(3)') gets the first 3 list items. “lt” stands for “less than,” and it starts counting at 0, not 1.

$('li:not(.goofy)') gets list items 1, 2, and 4, because they’re not “goofy.”
$('p a[@href*=#]') gets any links that are inside a paragraph and have an “href” attribute starting with “#” — containing “#” anywhere. in other words, same-page links. There are problems with trying to identify same-page links this way. I’ll write about this in an upcoming entry. Note the space between the “p” and the “a”; that means that the “a” is a descendant of the “p.”


2008年8月8日 星期五

上傳圖檔 attachment_fu, has_image

http://clarkware.com/cgi/blosxom/2007/02/24
http://almosteffortless.com/2007/03/25/working-with-attachment_fu/
http://randomba.org/2008/07/announcing-has_image-a-lightweight-hackable-image-attachment-plugin-for-rails/

Rails 2.1 new features


http://www.javaeye.com/news/2320
has_one :through
  1. class Magazine <>
  2. has_many :subscriptions
  3. end
  4. class Subscription <>
  5. belongs_to :magazine
  6. belongs_to :user
  7. end
  8. class User <>
  9. has_many :subscriptions
  10. has_one :magazine, :through => : subscriptions, :conditions => ['subscriptions.active = ?', true]
  11. end



http://www.javaeye.com/news/2334
Gem: Dependencies
  1. Rails::Initializer.run do |config|
  2. # Require the latest version of haml
  3. config.gem "haml"
  4. # Require a specific version of chronic
  5. config.gem "chronic", :version => '0.2.3'
  6. # Require a gem from a non-standard repo
  7. config.gem "hpricot", :source => "http://code.whytheluckystiff.net"
  8. # Require a gem that needs to require a file different than the gem's name
  9. # I.e. if you normally load the gem with require 'aws/s3' instead of
  10. # require 'aws-s3' then you would need to specify the :lib option
  11. config.gem "aws-s3", :lib => "aws/s3"
  12. end


http://www.javaeye.com/news/2349
Dirty Objects
  1. article = Article.find(:first)
  2. article.changed? #=> false
  3. # Track changes to individual attributes with
  4. # attr_name_changed? accessor
  5. article.title #=> "Title"
  6. article.title = "New Title"
  7. article.title_changed? #=> true
  8. # Access previous value with attr_name_was accessor
  9. article.title_was #=> "Title"
  10. # See both previous and current value with attr_name_change accessor
  11. article.title_change #=> ["Title", "New Title"]
  12. # Get a list of changed attributes
  13. article.changed #=> ['title']
  14. # Get the hash of changed attributes and their previous and current values
  15. article.changes #=> { 'title' => ["Title", "New Title"] }
http://www.javaeye.com/news/2367
Partial updates
  1. article = Article.find(:first)
  2. article.title #=> "Title"
  3. article.subject #=> "Edge Rails"
  4. # Update one of the attributes
  5. article.title = "New Title"
  6. # And only that updated attribute is persisted to the db
  7. article.save
  8. #=> "UPDATE articles SET title = 'New Title' WHERE id = 1"
ActiveRecord::Base.partial_updates = true

http://www.javaeye.com/news/2377
named_scope

http://www.javaeye.com/news/2392
UTC-based Migration

http://www.javaeye.com/news/2417
http://mad.ly/2008/04/09/rails-21-time-zone-support-an-overview/
http://wiki.rubyonrails.org/rails/pages/HowtoSetDefaultTimeZone
http://blog.labratz.net/articles/2007/4/11/rails-time-zone-guide-for-beginners



為了避免早鳥有一天爆掉

所以還是要有官網blog, 本來其實另外一邊有弄了, 可是有人懶得兩邊跑, 這邊比較常動所以乾脆就這邊也當作官網好了, 不過我猜這篇很快就會被memo文 淹沒 ㄎㄎ, 順手補個連結
http://iwakela.com/

JavaScript, prototype

http://blog.ericsk.org/archives/1089


var foo = {};
var bar = function() {}; // 也可以 function Bar() {};

if (foo instanceof Object) {
alert('Yes, foo is an Object instance');
}

if (bar instanceof Function) {
alert('Yes, bar is a Function instance');
}

var foo = {
x: 100,
y: 200,
f: function() {
....
}
};
如此一來你可以 foo.x, foo.y 或是 foo.f() 來操作

即使先用 new 生出 Function 的實體,之後再對該 Function 做 prototype 的新定義,被生出來的實體一樣會採用新的 prototype 定義。也就是對每一個實體而言,它綁住的是一個 prototype 而不是一個 class。

subsqery

http://www.1keydata.com/sql/sql-subquery.html
http://dev.mysql.com/doc/refman/5.0/en/subqueries.html

sql, subsquery

http://www.1keydata.com/sql/sql-subquery.html
http://dev.mysql.com/doc/refman/5.0/en/subqueries.html
http://railsforum.com/viewtopic.php?pid=68484

include 有時候太大包了, 這時我們可以用的就是subquery

[ActiveRecord]
User.find(:all, :conditions => "id in (select user_id from statuses where fight = true)")
[Sql]
SELECT * FROM `users` WHERE (id in (select user_id from statuses where fight = true))

[ActiveRecord]
User.update_all("group_nickname = 'iamlakela'","users.id in (select user_id from statuses where fight = true)")
[Sql]
UPDATE `users` SET group_nickname = 'iamlakela' WHERE (users.id in (select user_id from statuses where fight = true))

[ActiveRecord]
User.find(:all, :include => :status, :conditions => {'statuses.fight' => true})
[Sql]
SELECT `users`.`id` AS t0_r0, `users`.`name` AS t0_r1, `users`.`password_salt` AS t0_r2, `users`.`password_hash` AS t0_r3, `users`.`email` AS t0_r4, `users`.`created_at` AS t0_r5, `users`.`cookie_hash` AS t0_r6, `users`.`target_time_now` AS t0_r7, `users`.`reset_password_code` AS t0_r8, `users`.`reset_password_code_until` AS t0_r9, `users`.`yahoo_userhash` AS t0_r10, `users`.`group_id` AS t0_r11, `users`.`group_nickname` AS t0_r12, `users`.`time_zone` AS t0_r13, `statuses`.`id` AS t1_r0, `statuses`.`user_id` AS t1_r1, `statuses`.`fight` AS t1_r2, `statuses`.`state` AS t1_r3, `statuses`.`average` AS t1_r4, `statuses`.`success_rate` AS t1_r5, `statuses`.`continuous_num` AS t1_r6, `statuses`.`num` AS t1_r7, `statuses`.`last_record_created_at` AS t1_r8, `statuses`.`group_join_date` AS t1_r9, `statuses`.`attendance` AS t1_r10, `statuses`.`diff` AS t1_r11 FROM `users` LEFT OUTER JOIN `statuses` ON statuses.user_id = users.id WHERE (`statuses`.`fight` = 1)
[


從sample 就可以看出來差距多大了

ps:update 本來就是update 所有符合條件的object

crontab enviroment problem

/usr/bin/env: ruby: No such file or directory
/usr/local/bin/ruby: No such file or directory -- .script/runner (LoadError)

http://www.hostingrails.com/forums/deployment_troubleshooting_thread/966

http://www.hostingrails.com/forums/deployment_troubleshooting_thread/49

0 11 * * * cd /home/yourname/your_rails_app/ ; /usr/local/bin/ruby script/runner -e production "ModelName.method_name"


ps:script/runner 裡可以改default 的environment

2008年8月7日 星期四

ruby xml html parser and Here Document

http://ihower.idv.tw/blog/archives/1666
http://en.wikipedia.org/wiki/Heredoc#Ruby
http://code.whytheluckystiff.net/hpricot/wiki/HpricotBasics
http://fcamel.twbbs.org/archives/2007/07/13/410/
http://www.rubyinside.com/ruby-xml-crisis-over-libxml-0-8-0-released-955.html
http://libxml.rubyforge.org/

[Here document]

print <<-EOB
abc
cde
#{1+1}
EOB



require 'rubygems'

require 'hpricot'
require 'open-uri'

url = "http://www.iwakela.com"

doc = Hpricot(open(url))
doc.search('table tr').each do |item|
(item/'a').each do |nav|
p nav.attributes['href']
p nav.inner_html
end
end


妳想parse的是xml 時妳有更好的選擇libxml

require 'pp'
require 'benchmark'
require 'rubygems'
require 'xml/libxml'
require 'hpricot'
require 'rexml/document'

include Benchmark

signal_keys = [:signal_type, :create_datetime, :realized_or_unrealized,
:close_datetime, :open_price, :close_price, :performance,
:annualized_performance]

$rsp1 = {}
$rsp2 = {}

bm(12) do |test|

str = File.read('test.xml')

test.report('libxml') do
#xml_doc = XML::Document.file('test.xml')
xml_doc = XML::Parser.string(str).parse
root = xml_doc.root
root.find('target').each do |t|
$rsp2[t.find_first('target_id').content] = rsp_target = {}
rsp_target[:target_performance_average] = t.find_first('performance_average').content
rsp_target[:target_annualized_performance_average] = t.find_first('annualized_performance_average').content

t.find('signal').each do |signal|
rsp_target[signal.find_first('signal_id').content.to_sym] = signal_keys.inject({}) do |h,k|
h[k] = signal.find_first(k.to_s).content ; h
end
end
end

end

test.report('hpricot') do
xml_doc = Hpricot(File.open('test.xml'))
(xml_doc/:target).each do |t|
$rsp1[t.at(:target_id).innerHTML] = rsp_target = {}
rsp_target[:target_performance_average] = t.at("performance_average").innerHTML
rsp_target[:target_annualized_performance_average] = t.at("annualized_performance_average").innerHTML
(t/:signal).each do |signal|
rsp_target[signal.at(:signal_id).innerHTML.to_sym] = signal_keys.inject({}) do |h,k|
h[k]=signal.at(k).innerHTML ; h
end
end
end
end

end


binding ruby

http://www.ruby-doc.org/core/classes/Kernel.html#M001057
http://www.ruby-doc.org/core/classes/Binding.html
http://onestepback.org/index.cgi/Tech/Ruby/RubyBindings.rdoc/style/print


def getBinding(str)
return binding
end
str = "hello"
eval "str + ' Fred'" #=> "hello Fred"
eval "str + ' Fred'", getBinding("bye") #=> "bye Fred"

class Demo
def initialize(n)
@secret = n
end
def getBinding
return binding()
end
end

k1 = Demo.new(99)
b1 = k1.getBinding
k2 = Demo.new(-3)
b2 = k2.getBinding

p eval("@secret", b1) #=> 99
p eval("@secret", b2) #=> -3
p eval("@secret") #=> nil

def getBinding(param)
return binding()
end
b = getBinding("hello")
p eval("param", b) #=> "hello"


2008年8月6日 星期三

DRY in views, view的外圍是重覆的, 只有內部content 不同, 把內部content 當作block

DRY in view
http://www.igvita.com/2007/03/15/block-helpers-and-dry-views-in-rails/
Block to partial
http://errtheblog.com/posts/11-block-to-partial
binding
http://onestepback.org/index.cgi/Tech/Ruby/RubyBindings.rdoc/style/print
concat
http://api.rubyonrails.org/classes/ActionView/Helpers/TextHelper.html#M001727
capture
http://api.rubyonrails.org/classes/ActionView/Helpers/CaptureHelper.html#M001750




[view]
<% round 'title' do %>
I be rounded
<% end %>

[helper]
def round(name, &block)
option = {}
option.merge!(:name => name, :body => capture(&block))
concat(render(:partial => 'round_out', :locals => option), block.binding)
end

[partial]
<div>
<b>aaaa</b>
<div>
<%= name %>
</div>
<div>
<%= body %>
</div>
<b>bbbb</b>
</div>

2008年8月5日 星期二

redo, retry

http://my4java.itpub.net/post/9983/65275
http://www.souzz.net/big5.php?/html/345/23493.html

retry

例:

retry

語法:

retry

在迭代、塊或for語句中使用retry,意味著重啟迭代器。同時迭代器的參數也將被重新計算。

for i in 1..5
retry if some_condition # 從 i == 1 開始重新執行
end

2008年8月4日 星期一

ActiveRecord::Base

http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M001343


  Company.find(:first, :conditions => [
"id = :id AND name = :name AND division = :division AND created_at > :accounting_date",
{ :id => 3, :name => "37signals", :division => "First", :accounting_date => '2005-01-01' }
])

  Student.find(:all, :conditions => { :first_name => "Harvey", :status => 1 })
Student.find(:all, :conditions => params[:student]);
Student.find(:all, :conditions => { :grade => 9..12 })
Student.find(:all, :conditions => { :grade => [9,11,12] })


class Song < ActiveRecord::Base
# Uses an integer of seconds to hold the length of the song
def length=(minutes)
write_attribute(:length, minutes.to_i * 60)
end

def length
read_attribute(:length) / 60
end
end


# Now 'Bob' exist and is an 'admin'
User.find_or_create_by_name('Bob', :age => 40) { |u| u.admin = true }


class User < ActiveRecord::Base
serialize :preferences
end
user = User.create(:preferences => { "background" => "black", "display" => large })
User.find(user.id).preferences # => { "background" => "black", "display" => large }


class User < ActiveRecord::Base
serialize :preferences, Hash
end
user = User.create(:preferences => %w( one two three ))
User.find(user.id).preferences # raises SerializationTypeMismatch


User.create([{ :first_name => 'Jamie' }, { :first_name => 'Jeremy' }]) do |u|
u.is_admin = false
end


# Delete multiple objects
todos = [1,2,3]
Todo.delete(todos)

Person.find(1, 2, 6) # returns an array for objects with IDs in (1, 2, 6)
Person.find([7, 17]) # returns an array for objects with IDs in (7, 17)

Person.exists?(:name => "David")
Person.exists?(['name LIKE ?', "%#{query}%"])


Person.find(:all, :conditions => [ "category IN (?)", categories], :limit => 50)
Person.find(:all, :conditions => { :friends => ["Bob", "Steve", "Fred"] }
Person.find(:all, :offset => 10, :limit => 10)
Person.find(:all, :include => [ :account, :friends ])
Person.find(:all, :group => "category")

Person.transaction do
person = Person.find(1, :lock => true)
person.visits += 1
person.save!
end

Post.update_counters 5, :comment_count => -1, :action_count => 1

{ :name => "foo'bar", :group_id => 4 }
# => "name='foo''bar' and group_id= 4"
{ :status => nil, :group_id => [1,2,3] }
# => "status IS NULL and group_id IN (1,2,3)"
{ :age => 13..18 }
# => "age BETWEEN 13 AND 18"
{ 'other_records.id' => 7 }
# => "`other_records`.`id` = 7"

with_scope

http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M001343
Scope parameters to method calls within the block. Takes a hash of method_name => parameters hash. method_name may be :find or :create. :find parameters may include the :conditions, :joins, :include, :offset, :limit, and :readonly options. :create parameters are an attributes hash.

In nested scopings, all previous parameters are overwritten by the innermost rule, with the exception of :conditions, :include, and :joins options in :find, which are merged.

:joins options are uniqued so multiple scopes can join in the same table without table aliasing problems. If you need to join multiple tables, but still want one of the tables to be uniqued, use the array of strings format for your joins.

Advanced Search Form

http://railscasts.com/episodes/111-advanced-search-form



<!-- views/searches/new.html.erb -->
<% form_for @search do |f| %>
<p>
<%= f.label :keywords %><br />
<%= f.text_field :keywords %>
</p>
<p>
<%= f.label :category_id %><br />
<%= f.collection_select :category_id, Category.all, :id, :name, :include_blank => true %>
</p>
<p>
Price Range<br />
<%= f.text_field :minimum_price, :size => 7 %> -
<%= f.text_field :maximum_price, :size => 7 %>
</p>
<p><%= f.submit "Submit" %></p>
<% end %>


# models/search.rb
def products
@products ||= find_products
end

private

def find_products
Product.find(:all, :conditions => conditions)
end

def keyword_conditions
["products.name LIKE ?", "%#{keywords}%"] unless keywords.blank?
end

def minimum_price_conditions
["products.price >= ?", minimum_price] unless minimum_price.blank?
end

def maximum_price_conditions
["products.price <= ?", maximum_price] unless maximum_price.blank?
end

def category_conditions
["products.category_id = ?", category_id] unless category_id.blank?
end

def conditions
[conditions_clauses.join(' AND '), *conditions_options]
end

def conditions_clauses
conditions_parts.map { |condition| condition.first }
end

def conditions_options
conditions_parts.map { |condition| condition[1..-1] }.flatten
end

def conditions_parts
private_methods(false).grep(/_conditions$/).map { |m| send(m) }.compact
end




Simple Search Form

http://railscasts.com/episodes/37


<!-- projects/index.rhtml -->

<% form_tag projects_path, :method => 'get' do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>


# projects_controller.rb
def index
@projects = Project.search(params[:search])
end

# models/project.rb
def self.search(search)
if search
find(:all, :conditions => ['name LIKE ?', "%#{search}%"])
else
find(:all)
end
end

javascript get local time & rails

http://www.eie052.com/bcshow.php/t/java/p/0/d/30.html
http://www.builder.com.cn/2006/0123/227078.shtml
http://articles.techrepublic.com.com/5100-10878_11-6016329.html

[View]
$('.localtime').click(function(){
var t = new Date();
now = t.getTime();
window.location = '/alert/gettime?time='+now
});

getTime拿到的是1970年1月1日後到此當時時間之間的毫秒數。
但是記得要加上time zone offset
[Controller]
Time.at(params[:time].to_f/1000).to_s(:db)

為了不一直發出request

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

這種用setTimeout的技巧 還蠻常用到的

var sending = null;

var _formSubmit = function () {
alert('Form submited!');
};

var _doAjaxPost = function () {
if (sending !== null) {
clearTimeout(sending);
sending = null;
}
sending = setTimeout(_formSubmit, 1000);
};

var plusQuantity = function () {
// ... 執行增加數量的動作 ...
_doAjaxPost();
return false;
};

var minusQuantity = function () {
// ... 執行減少數量的動作 ...
_doAjaxPost();
return false;
};

$(function () {
// 增加數量
$('a.plus').click(plusQuantity);

// 減少數量
$('a.minus').click(minusQuantity);
});

2008年8月1日 星期五

find, like, sql


User.find(:all, :conditions => ["name LIKE ?", "%#{params[:search]}%"])

javascript reverse string , and add, for number

Q: add the ',' symbol in the number, like 1,234,567
reference:
http://www.javascripter.net/faq/converti.htm
http://www.ruby-forum.com/topic/79885
maxsize(x), maxlength(o)

http://www.bytemycode.com/snippets/snippet/400/
http://www.irt.org/script/1325.htm

>>> '123456'.split(/.../)
["", "", ""]
>>> '123456'.split(/(...)/)
["", "123", "", "456", ""]

ie split有問題, 所以只好自己做, 在下面


function fn_price(val) {
var val = val+'';

var a = val.split('').reverse();

var str = [];
for(var i = 0 ; i< a.length; i++){
if(i % 3 == 0 && i != 0) { str.push(',');}
str.push( a[i]);
}
return str.reverse().join('');
}