2008年8月29日 星期五
File, Pathname, Dir
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月28日 星期四
2008年8月26日 星期二
2008年8月25日 星期一
squish, strip
=> "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/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://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
The association version is slightly faster then the class version.
extend 的是那些綁在has_many association下的method
2008年8月24日 星期日
has_and_belongs_to_many, habtm, self referential relationship
http://blog.hasmanythrough.com/2007/10/30/self-referential-has-many-through
http://hideto.javaeye.com/blog/75887
http://szeryf.wordpress.com/2007/06/27/self-referential-many-to-many-relations-in-ruby-on-rails/
http://practicalruby.blogspot.com/2007/03/symmetric-self-referential-has-one.html
http://www.aldenta.com/2006/11/10/has_many-through-self-referential-example/
http://blog.handlino.com/2007_05_01_archive.html
http://blog.layer2.org/2007/10/10/convert-has_and_belongs_to_many-to-a-has_many-through-association/
http://www.neyric.com/blog/how-to-delete-a-many-to-many-association-with-rails
http://takol.tw/data/96724670ab3aa3fe6.html
[user model]
has_and_belongs_to_many :friends,
:class_name => "User",
:join_table => "friends",
:association_foreign_key => "friend_id",
:foreign_key => "user_id"
[friend table]
create_table :friends, :id => false do |t|
t.column :user_id, :integer, :null => false
t.column :friend_id, :integer, :null => false
end
[console]
user.friends
[sql]
SELECT * FROM `users` INNER JOIN `friends` ON `users`.id = `friends`.friend_id WHERE (`friends`.user_id = 1 )
2008年8月22日 星期五
type column table rails
所以如果妳用了type, 他就會嘗試去找SUV
然後就會爆 ActiveRecord::SubclassNotFound
要避免這種情況就是要主動告訴Rncails說這不是STI
在model裡設定
set_inheritance_column "not_sti "
2008年8月21日 星期四
polymphic, comment,db
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
# 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
has_one, has_many ,through
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)
- 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
HTML REL and REV Attributes
<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://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
validate if, RAILS_DEFAULT_LOGGER
RAILS_DEFAULT_LOGGER.debug("servlet call!!!!#{last_bytestream}")
2008年8月19日 星期二
2008年8月15日 星期五
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 = $('<li class="special">special and new <button>I am new</button></li>');
$(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://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
這樣加好幾個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日 星期二
jQuery tutorial, find and filter
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” attributestarting 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月9日 星期六
IE bugs padding
http://cafefrenzy.com/css-double-padding-ie7-fix/
http://www.positioniseverything.net/explorer/doubled-margin.html
http://www.viget.com/inspire/styling-the-button-element-in-internet-explorer/
http://www.positioniseverything.net/explorer.html
http://jehiah.cz/archive/button-width-in-ie
IE padding bug
2008年8月8日 星期五
Rails 2.1 new features
http://www.javaeye.com/news/2320
has_one :through
- class Magazine <>
- has_many :subscriptions
- end
- class Subscription <>
- belongs_to :magazine
- belongs_to :user
- end
- class User <>
- has_many :subscriptions
- has_one :magazine, :through => : subscriptions, :conditions => ['subscriptions.active = ?', true]
- end
http://www.javaeye.com/news/2334
Gem: Dependencies
- Rails::Initializer.run do |config|
- # Require the latest version of haml
- config.gem "haml"
- # Require a specific version of chronic
- config.gem "chronic", :version => '0.2.3'
- # Require a gem from a non-standard repo
- config.gem "hpricot", :source => "http://code.whytheluckystiff.net"
- # Require a gem that needs to require a file different than the gem's name
- # I.e. if you normally load the gem with require 'aws/s3' instead of
- # require 'aws-s3' then you would need to specify the :lib option
- config.gem "aws-s3", :lib => "aws/s3"
- end
http://www.javaeye.com/news/2349
Dirty Objectshttp://www.javaeye.com/news/2367
- article = Article.find(:first)
- article.changed? #=> false
- # Track changes to individual attributes with
- # attr_name_changed? accessor
- article.title #=> "Title"
- article.title = "New Title"
- article.title_changed? #=> true
- # Access previous value with attr_name_was accessor
- article.title_was #=> "Title"
- # See both previous and current value with attr_name_change accessor
- article.title_change #=> ["Title", "New Title"]
- # Get a list of changed attributes
- article.changed #=> ['title']
- # Get the hash of changed attributes and their previous and current values
- article.changes #=> { 'title' => ["Title", "New Title"] }
Partial updatesActiveRecord::Base.partial_updates = true
- article = Article.find(:first)
- article.title #=> "Title"
- article.subject #=> "Edge Rails"
- # Update one of the attributes
- article.title = "New Title"
- # And only that updated attribute is persisted to the db
- article.save
- #=> "UPDATE articles SET title = 'New Title' WHERE id = 1"
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
為了避免早鳥有一天爆掉
http://iwakela.com/
JavaScript, prototype
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。
sql, subsquery
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/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://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
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://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
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
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
<!-- 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
<!-- 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.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
這種用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日 星期五
javascript reverse string , and add, for number
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('');
}