1. 程式人生 > >Active Record Validations and Callbacks

Active Record Validations and Callbacks

有許多種在儲存資料到資料庫之前驗證資料有效性的方法,包括資料庫原生的約束(constraints)、客戶端的驗證、Controller級別的驗證以及Model級別的驗證。

資料庫約束:
資料庫約束和儲存過程使得驗證機制依賴於資料庫本身,會讓測試和維護更加困難。但是如果你的資料庫會被其它的應用程式所使用,這時候使用一些資料 庫級別的約束(constraints)會是個好主意。另外,資料庫級別的驗證可以安全的處理一些很難用其它方式實現的事件(比如大量使用的表的唯一性 (uniqueness in heavily-used tables))。

客戶端驗證:
客戶端的驗證是很有用的,但是隻單獨使用客戶端驗證一般是不可靠的。如果驗證邏輯是用JavaScript來實現,通過關閉使用者瀏覽器的 JavaScript可以很容易的繞過驗證程式。但是,如果和其它技術(指Controlelr、Model或者資料庫級別的驗證技術)結合起來使用,客 戶端驗證會是一種給使用者提供即時反饋的很方便的方式。

Controller級別的驗證:


Controller級別的驗證用起來看似很吸引人,但是經常會變得很難控制、難以測試和維護。只要有可能,保持你的Controllers儘量的“瘦”是個好主意(keep your controllers skinny )。從長遠來看,這會給你的程式帶來很多好處。

Model級別的驗證:
Model級別的驗證是確保只有通過驗證的資料才能被保到資料庫的最好方式。Model級別的驗證是不依賴於資料庫的,並且是不會被終端使用者繞開 的,同時也是方便測試和維護的。Rails使得Model級別的驗證很容易實現,為常見的需求提供了內建的helper,並且還允許你建立你自己的驗證方 法。

驗證什麼時候發生?


Rails中有兩種ActiveRecord物件:一種和資料庫中的每一條記錄相對應,另一種則不是。當你建立一個新的物件的時候,比如呼叫了某 個ActiveRecord類的new方法,創建出來的物件還不存在於資料庫中。一旦你呼叫了這個物件的save方法,它將被儲存到資料庫對應的表中。 ActiveRecord使用new_record?例項方法來判斷一個物件是否已經儲存到資料庫中。

建立和儲存一個新的ActiveRecord物件會向資料庫傳送一條INSERT語句,更新一個ActiveRecord物件會向資料庫傳送一條 UPDATE語句。ActiveRecord的驗證是在傳送這些SQL語句之前進行的,如果驗證不通過,物件將被標記為未通過驗證的(invalid), 並且INSERT、UPDATE命令不會被執行,從而避免了把這些未通過驗證的物件儲存到資料庫中。

有許多改變資料庫中物件的狀態的方法,其中一些方法會觸發驗證,而另一些則不會。這意味著如果不小心的話,把一個未通過驗證的物件儲存到資料庫中是有可能的。

以下這些方法將會觸發驗證:
create
create!
save
save!
update
update_attributes
update_attributes!

其中帶感嘆號的方法(比如save!)在驗證失敗的時候將會丟擲一個異常,不帶感嘆號的則不會:save和update_attributes返回false,create和update只會返回物件本身。

以下方法將會跳過驗證,並把物件儲存到資料庫中,要小心使用:
decrement!
decrement_counter
increment!
increment_counter
toggle!
update_all
update_attribute
update_counters

同時要注意,假如給save方法傳一個false引數也可以跳過驗證,這個技巧也要小心使用。

valid?和invalid?

Rails使用valid?和invalid?方法來判斷一個物件是否通過驗證,這兩個方法都會觸發驗證,如果驗證通過,valid?返回true,invalid?返回false,否則相反。

可以通過ActiveRecord的例項方法errors來得到驗證時發生的任何錯誤資訊的集合(一個hash)。如果驗證執行完畢,這個hash仍然是空的,說明這個物件通過驗證。

errors.invalid?
errors.invalid?用於檢查物件的某個屬性是否合法,這個方法只能在物件的驗證被觸發之後呼叫,因為它只檢查errors這個hash,而不會去觸發驗證。用法:

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=errors.invalid%3F%20%3Aname%20%23true%7Cfalse" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. errors.invalid?  :name #true|false
errors.invalid? :name #true|false



Validation Helpers

validates_acceptance_of
validates_acceptance_of用於驗證表單裡的checkbox是否被勾上。需要使用者同意一些服務條款是 validates_acceptance_of很典型的使用場景。這個“acceptance”不需要被持久化到資料庫中(如果沒有欄位與之對 應,helper會建立一個虛擬屬性(virtual attribute))。

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=class%20Person%20%3C%20ActiveRecord%3A%3ABase%0A%20validates_acceptance_of%20%3Aterms_of_service%20%0Aend%20" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. class  Person < ActiveRecord::Base  
  2.  validates_acceptance_of :terms_of_service
  3. end
class Person < ActiveRecord::Base
 validates_acceptance_of :terms_of_service 
end 


validates_acceptance_of預設的錯誤訊息是"must be accepted",每個Rails內建的驗證helper都可以用:message 選項來指定錯誤訊息:

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=validates_acceptance_of%20%3Aterms_of_service%2C%20%3Amessage%3D%3E'some%20message'" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. validates_acceptance_of  :terms_of_service :message => 'some message'
validates_acceptance_of :terms_of_service, :message=>'some message'


另外,validates_acceptance_of接受一個:accept選項,這個選項所指定的值用於判斷“使用者是否接受了服務條款”,如果沒有指定,預設的值是字串 "1"。

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=validates_acceptance_of%20%3Aterms_of_service%2C%20%3Aaccept%3D%3E'yes'%2C%20%3Amessage%3D%3E'some%20message'" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. validates_acceptance_of  :terms_of_service :accept => 'yes' :message => 'some message'
validates_acceptance_of :terms_of_service, :accept=>'yes', :message=>'some message'



validates_associated
validates_associated用於驗證關聯的物件(呼叫valid?):

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=class%20Book%20%3C%20ActiveRecord%3A%3ABase%0A%20%20has_one%20%3Aauthor%0A%20%20validates_associated%20%3Aauthor%20%0Aend%0A%0Aclass%20Author%20%3C%20ActiveRecord%3A%3ABase%0A%20%20belongs_to%20%3Abook%0A%20%20validates_presence_of%20%3Aname%0Aend%0A%0Abook%20%3D%20Book.new%0Abook.author%20%3D%20Author.new%0Abook.valid%3F%20%23false%0Abook.errors.invalid%3F%20%3Aauthor%20%23true%0Abook.author.name%20%3D%20'somebody'%0Abook.valid%3F%20%23true%0A" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. class  Book < ActiveRecord::Base  
  2.   has_one :author
  3.   validates_associated :author
  4. end
  5. class  Author < ActiveRecord::Base  
  6.   belongs_to :book
  7.   validates_presence_of :name
  8. end
  9. book = Book.new
  10. book.author = Author.new
  11. book.valid? #false
  12. book.errors.invalid? :author #true
  13. book.author.name = 'somebody'
  14. book.valid? #true
class Book < ActiveRecord::Base
  has_one :author
  validates_associated :author 
end

class Author < ActiveRecord::Base
  belongs_to :book
  validates_presence_of :name
end

book = Book.new
book.author = Author.new
book.valid? #false
book.errors.invalid? :author #true
book.author.name = 'somebody'
book.valid? #true


要注意的一點是,別在相關聯的兩個類中同時使用validates_associated,否則在觸發驗證的時候會引起無限迴圈。

validates_confirmation_of
validates_confirmation_of用於檢查兩個欄位的內容是否相同,比如在“使用者註冊”的時候,可以用它檢查“密碼”和“確認密碼”、“郵箱”和“確認郵箱”的內容是否相同。
這個helper會建立一個虛擬屬性,這個虛擬屬性的名字以被要求確認的屬性名開頭,以_confirmation結尾:

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=class%20Person%20%3C%20ActiveRecord%3A%3ABase%0A%20validates_confirmation_of%20%3Aemail%20%0Aend%20" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. class  Person < ActiveRecord::Base  
  2.  validates_confirmation_of :email
  3. end
class Person < ActiveRecord::Base
 validates_confirmation_of :email 
end 


在view模板裡可以這樣用:

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%3C%25%3D%20text_field%20%3Aperson%2C%20%3Aemail%20%25%3E%20%0A%3C%25%3D%20text_field%20%3Aperson%2C%20%3Aemail_confirmation%20%25%3E%20" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. <%= text_field  :person :email  %>   
  2. <%= text_field :person :email_confirmation  %>   
<%= text_field :person, :email %> 
<%= text_field :person, :email_confirmation %> 


檢查只在email_confirmation不為nil的時候執行,所以需要給email_confirmation新增一個validates_presence_of 驗證,像這樣:

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=class%20Person%20%3C%20ActiveRecord%3A%3ABase%0A%20validates_confirmation_of%20%3Aemail%0A%20validates_presence_of%20%3Aemail_confirmation%20%0Aend%20" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. class  Person < ActiveRecord::Base  
  2.  validates_confirmation_of :email
  3.  validates_presence_of :email_confirmation
  4. end
class Person < ActiveRecord::Base
 validates_confirmation_of :email
 validates_presence_of :email_confirmation 
end 


validates_exclusion_of
validates_exclusion_of用於保證物件的屬性值不在指定的集合中,例如在註冊域名的時候,"www"是預留的,不允許使用者註冊,可以這樣:

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=class%20Account%20%3C%20ActiveRecord%3A%3ABase%0A%20validates_exclusion_of%20%3Asubdomain%2C%20%3Ain%20%3D%3E%20%25w(www)%2C%0A%20%3Amessage%20%3D%3E%20%22Subdomain%20%7B%7Bvalue%7D%7D%20is%20reserved.%22%20%0Aend%20" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. class  Account < ActiveRecord::Base  
  2.  validates_exclusion_of :subdomain :in  => %w(www),  
  3.  :message  =>  "Subdomain {{value}} is reserved."
  4. end
class Account < ActiveRecord::Base
 validates_exclusion_of :subdomain, :in => %w(www),
 :message => "Subdomain {{value}} is reserved." 
end 


:in選項接受一個集合,這個集合可以是任何可列舉的物件(enumerable object),集合裡存放的是那些被排除的值。另外,:in有個別名:within。這裡:message的用法展示瞭如何在訊息中包含屬性值({{value}})。

validates_format_of
validates_format_of用於驗證文字的格式,有個:with選項,用來指定要匹配的正則表示式:

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=class%20Product%20%3C%20ActiveRecord%3A%3ABase%0A%20validates_format_of%20%3Alegacy_code%2C%20%3Awith%20%3D%3E%20%2F%5CA%5Ba-zA-Z%5D%2B%5Cz%2F%2C%0A%20%3Amessage%20%3D%3E%20%22Only%20letters%20allowed%22%20%0Aend%20" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. class  Product < ActiveRecord::Base  
  2.  validates_format_of :legacy_code :with  => /\A[a-zA-Z]+\z/,  
  3.  :message  =>  "Only letters allowed"
  4. end
class Product < ActiveRecord::Base
 validates_format_of :legacy_code, :with => /\A[a-zA-Z]+\z/,
 :message => "Only letters allowed" 
end 



validates_inclusion_of
validates_inclusion_of用於確保物件的屬性值在指定的集合中,例如:

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=class%20Coffee%20%3C%20ActiveRecord%3A%3ABase%0A%20validates_inclusion_of%20%3Asize%2C%20%3Ain%20%3D%3E%20%25w(small%20medium%20large)%2C%0A%20%3Amessage%20%3D%3E%20%22%7B%7Bvalue%7D%7D%20is%20not%20a%20valid%20size%22%20%0Aend%20" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. class  Coffee < ActiveRecord::Base  
  2.  validates_inclusion_of :size :in  => %w(small medium large),  
  3.  :message  =>  "{{value}} is not a valid size"
  4. end
class Coffee < ActiveRecord::Base
 validates_inclusion_of :size, :in => %w(small medium large),
 :message => "{{value}} is not a valid size" 
end 


這樣,Coffee的size(……Coffee的size是個什麼概念?)只能為"small"、"medium"或者"large"。同樣,這裡的:in也有一個別名:within。

validates_length_of(別名validates_size_of)
validates_length_of看著簡單,用法卻很多。用於指定某屬性的字串長度,有多種指定方式,比如最大值、最小值、在某個區間內或者直接指定長度:

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=class%20Person%20%3C%20ActiveRecord%3A%3ABase%0A%20validates_length_of%20%3Aname%2C%20%3Aminimum%20%3D%3E%202%0A%20validates_length_of%20%3Abio%2C%20%3Amaximum%20%3D%3E%20500%0A%20validates_length_of%20%3Apassword%2C%20%3Ain%20%3D%3E%206..20%0A%20validates_length_of%20%3Aregistration_number%2C%20%3Ais%20%3D%3E%206%20%0Aend%20" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. class  Person < ActiveRecord::Base  
  2.  validates_length_of :name :minimum  => 2  
  3.  validates_length_of :bio :maximum  => 500  
  4.  validates_length_of :password :in  => 6..20  
  5.  validates_length_of :registration_number :is  => 6   
  6. end
class Person < ActiveRecord::Base
 validates_length_of :name, :minimum => 2
 validates_length_of :bio, :maximum => 500
 validates_length_of :password, :in => 6..20
 validates_length_of :registration_number, :is => 6 
end 


:message選項可以用:wrong_length、:too_long、和:too_short來替代。根據情況選擇,比如:minimun對應:too_short。在message裡可以使用{{count}}作為允許長度的佔位符:

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=class%20Person%20%3C%20ActiveRecord%3A%3ABase%0A%20validates_length_of%20%3Abio%2C%20%3Amaximum%20%3D%3E%201000%2C%0A%20%3Atoo_long%20%3D%3E%20%22%7B%7Bcount%7D%7D%20characters%20is%20the%20maximum%20allowed%22%20%0Aend%20" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. class  Person < ActiveRecord::Base  
  2.  validates_length_of :bio :maximum  => 1000,  
  3.  :too_long  =>  "{{count}} characters is the maximum allowed"
  4. end
class Person < ActiveRecord::Base
 validates_length_of :bio, :maximum => 1000,
 :too_long => "{{count}} characters is the maximum allowed" 
end 


另外,可以使用指定的演算法來分割字串,計算字串的長度(估計是考慮到雙位元組字元,例如中文)。:tokenizer用於指定分割演算法:

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=class%20Essay%20%3C%20ActiveRecord%3A%3ABase%0A%20validates_length_of%20%3Acontent%2C%20%3Aminimum%20%3D%3E%20300%2C%0A%20%3Amaximum%20%3D%3E%20400%2C%0A%20%3Atokenizer%20%3D%3E%20lambda%20%7B%20%7Cstr%7C%20str.scan(%2F%5Cw%2B%2F)%20%7D%2C%0A%20%3Atoo_short%20%3D%3E%20%22must%20have%20at%20least%20%7B%7Bcount%7D%7D%20words%22%2C%0A%20%3Atoo_long%20%3D%3E%20%22must%20have%20at%20most%20%7B%7Bcount%7D%7D%20words%22%20%0Aend%20" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. class  Essay < ActiveRecord::Base  
  2.  validates_length_of :content :minimum  => 300,  
  3.  :maximum  => 400,  
  4.  :tokenizer  => lambda { |str| str.scan(/\w+/) },  
  5.  :too_short  =>  "must have at least {{count}} words" ,  
  6.  :too_long  =>  "must have at most {{count}} words"
  7. end
class Essay < ActiveRecord::Base
 validates_length_of :content, :minimum => 300,
 :maximum => 400,
 :tokenizer => lambda { |str| str.scan(/\w+/) },
 :too_short => "must have at least {{count}} words",
 :too_long => "must have at most {{count}} words" 
end 


validates_numericality_of
validates_numericality_of用於驗證某屬性值是否為數字。它預設允許整數和浮點數,如果你只希望得到一個整數,那麼可以設定:only_integer選項的值為true,這樣Rails將會使用正則表示式

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%2F%5CA%5B%2B-%5D%3F%5Cd%2B%5CZ%2F" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. /\A[+-]?\d+\Z/  
/\A[+-]?\d+\Z/

來匹配屬性值。

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=class%20Player%20%3C%20ActiveRecord%3A%3ABase%0A%20validates_numericality_of%20%3Apoints%0A%20validates_numericality_of%20%3Agames_played%2C%20%3Aonly_integer%20%3D%3E%20true%0Aend%20" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. class  Player < ActiveRecord::Base  
  2.  validates_numericality_of :points
  3.  validates_numericality_of :games_played :only_integer  =>  true
  4. end
class Player < ActiveRecord::Base
 validates_numericality_of :points
 validates_numericality_of :games_played, :only_integer => true
end 


除了:only_integer,validates_numericality_of 還有許多其它選項:

引用 :greater_than – Specifies the value must be greater than the supplied value. The default error message for this option is “must be greater than {{count}}”.
:greater_than_or_equal_to – Specifies the value must be greater than or equal to the supplied value. The default error message for this option is “_must be greater than or equal to {{count}}”.
:equal_to – Specifies the value must be equal to the supplied value. The default error message for this option is “must be equal to {{count}}”.
:less_than – Specifies the value must be less than the supplied value. The default error message for this option is “must be less than {{count}}”.
:less_than_or_equal_to – Specifies the value must be less than or equal the supplied value. The default error message for this option is “must be less or equal to {{count}}”.
:odd – Specifies the value must be an odd number if set to true. The default error message for this option is “must be odd”.
:even – Specifies the value must be an even number if set to true. The default error message for this option is “must be even”.


validates_presence_of
validates_presence_of在前面見過,用於驗證“必填”的屬性,它會呼叫物件屬性的blank?方法來判斷:

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=class%20Person%20%3C%20ActiveRecord%3A%3ABase%0A%20validates_presence_of%20%3Aname%2C%20%3Alogin%2C%20%3Aemail%20%0Aend%20" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. class  Person < ActiveRecord::Base  
  2.  validates_presence_of :name :login :email
  3. end
class Person < ActiveRecord::Base
 validates_presence_of :name, :login, :email 
end 


由於false.blank?的值是true,如果你想驗證某個布林屬性是否被賦值,應當這樣做:

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=validates_inclusion_of%20%3Afield_name%2C%20%3Ain%20%3D%3E%20%5Btrue%2C%20false%5D" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. validates_inclusion_of  :field_name :in  => [ true false ]  
validates_inclusion_of :field_name, :in => [true, false]


validates_uniqueness_of
validates_uniqueness_of用來確保某屬性的唯一性,比如“使用者註冊”時的使用者名稱、email等。一般用法:

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=class%20Account%20%3C%20ActiveRecord%3A%3ABase%0A%20validates_uniqueness_of%20%3Aemail%0Aend%20" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. class  Account < ActiveRecord::Base  
  2.  validates_uniqueness_of :email
  3. end
class Account < ActiveRecord::Base
 validates_uniqueness_of :email
end 


這個驗證在觸發時會執行一條SQL語句(大概像這樣SELECT * FROM accounts WHERE email='[email protected]')。
這個helper有一個:scope選項,用於限制查詢的範圍,比如:

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=class%20Holiday%20%3C%20ActiveRecord%3A%3ABase%0A%20validates_uniqueness_of%20%3Aname%2C%20%3Ascope%20%3D%3E%20%3Ayear%2C%0A%20%3Amessage%20%3D%3E%20%22should%20happen%20once%20per%20year%22%20%0Aend%20" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. class  Holiday < ActiveRecord::Base  
  2.  validates_uniqueness_of :name :scope  =>  :year ,  
  3.  :message  =>  "should happen once per year"
  4. end
class Holiday < ActiveRecord::Base
 validates_uniqueness_of :name, :scope => :year,
 :message => "should happen once per year" 
end 


還有個:case_sensitive用於指定是否忽略大小寫:

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=class%20Person%20%3C%20ActiveRecord%3A%3ABase%0A%20validates_uniqueness_of%20%3Aname%2C%20%3Acase_sensitive%20%3D%3E%20false%20%0Aend%20" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. class  Person < ActiveRecord::Base  
  2.  validates_uniqueness_of :name :case_sensitive  =>  false
  3. end
class Person < ActiveRecord::Base
 validates_uniqueness_of :name, :case_sensitive => false 
end 


validates_each
這個helper需要靠一個block來驗證屬性,它沒有預定義的函式,但可以使用block建立一個驗證規則,所有傳遞給validates_each的屬性都靠這個規則來驗證。在下面這個例子中,我們希望name和surname不以小寫字母開頭:

Java程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=class%20Person%20%3C%20ActiveRecord%3A%3ABase%0A%20validates_each%20%3Aname%2C%20%3Asurname%20do%20%7Cmodel%2C%20attr%2C%20value%7C%0A%20%20model.errors.add(attr%2C%20'must%20start%20with%20upper%20case')%20if%20value%20%3D~%20%2F%5CA%5Ba-z%5D%2F%0A%20end%20%0Aend%20" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. class  Person < ActiveRecord::Base  
  2.  validates_each :name, :surname do  |model, attr, value|  
  3.   model.errors.add(attr, 'must start with upper case' if  value =~ /\A[a-z]/  
  4.  end   
  5. end   
class Person < ActiveRecord::Base
 validates_each :name, :surname do |model, attr, value|
  model.errors.add(attr, 'must start with upper case') if value =~ /\A[a-z]/
 end 
end 


這裡的block接收3個引數,分別是model物件本身、屬性名和屬性值。

validation helper中常見的選項

:allow_nil 顧名思義。值為true或false。另外,guides上面說:

引用 Using :allow_nil with validates_presence_of allows for nil, but any other blank? value will still be rejected.


但經試驗,發現好像並不是這樣,:allow_nil=>true在validates_presence_of裡好像不起作用。
:allow_blank

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=class%20Topic%20%3C%20ActiveRecord%3A%3ABase%0A%20validates_length_of%20%3Atitle%2C%20%3Ais%20%3D%3E%205%2C%20%3Aallow_blank%20%3D%3E%20true%20%0Aend%20%0ATopic.create(%22title%22%20%3D%3E%20%22%22).valid%3F%20%23%20%3D%3E%20true%20%0ATopic.create(%22title%22%20%3D%3E%20nil).valid%3F%20%23%20%3D%3E%20true%20" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. class  Topic < ActiveRecord::Base  
  2.  validates_length_of :title :is  => 5,  :allow_blank  =>  true
  3. end
  4. Topic.create("title"  =>  "" ).valid?  # => true 
  5. Topic.create("title"  =>  nil ).valid?  # => true 
class Topic < ActiveRecord::Base
 validates_length_of :title, :is => 5, :allow_blank => true 
end 
Topic.create("title" => "").valid? # => true 
Topic.create("title" => nil).valid? # => true 


:message 這裡就不用解釋了。
:on
:on選項允許設定驗證觸發的時機。Rails預設觸發驗證的時機是在儲存物件之前(save、create、update)。如果你想改變這一規則,可以使用:on選項,比如:on=>:save會使驗證只在save方法被呼叫之前 觸發驗證。

Conditional Validation

:if和:unless選項
這兩個選項用於設定驗證觸發的條件,值可以是symbol,可以是string,也可以是一個lambda/proc。
當值為symbol時,Rails會在驗證觸發之前呼叫symbol對應的方法,再根據返回結果決定是否執行驗證;
當值為string時,Rails會在驗證觸發之前用eval來執行這個string,再根據返回結果決定是否執行驗證;
當值為lambda/proc表示式時,Rails會在驗證觸發之前執行這個表示式,再根據返回結果決定是否執行驗證。

自定義驗證
當Rails內建的驗證規則滿足不了你的需求時,可以用validate、validate_on_create或者validate_on_update 自定義驗證規則。它的引數是一個或多個symbol,這些symbol每個都對應一個方法(同名),這些方法將在驗證觸發的時候被呼叫。
另外,甚至可以這樣定義自己的validation helper:

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=ActiveRecord%3A%3ABase.class_eval%20do%20%0A%20def%20self.validates_as_radio(attr_name%2C%20n%2C%20options%3D%7B%7D)%0A%20%20validates_inclusion_of%20attr_name%2C%20%7B%3Ain%20%3D%3E%201..n%7D.merge(options)%20%0A%20end%20%0Aend%20" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. ActiveRecord::Base.class_eval  do
  2.  def self .validates_as_radio(attr_name, n, options={})  
  3.   validates_inclusion_of attr_name, {:in  => 1..n}.merge(options)   
  4.  end
  5. end
ActiveRecord::Base.class_eval do 
 def self.validates_as_radio(attr_name, n, options={})
  validates_inclusion_of attr_name, {:in => 1..n}.merge(options) 
 end 
end 
Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=class%20Movie%20%3C%20ActiveRecord%3A%3ABase%0A%20validates_as_radio%20%3Arating%2C%205%20%0Aend" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. class  Movie < ActiveRecord::Base  
  2.  validates_as_radio :rating , 5   
  3. end
class Movie < ActiveRecord::Base
 validates_as_radio :rating, 5 
end



Working with Validation Errors

errors.add_to_base
errors.add_to_base用於將error新增到物件上而不是物件的某個具體屬性上。使用很簡單,只要給它一個string引數作為錯誤資訊。

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=class%20Person%20%3C%20ActiveRecord%3A%3ABase%0A%20def%20a_method_used_for_validation_purposes%0A%20%20errors.add_to_base(%22This%20person%20is%20invalid%20because%20...%22)%20%0A%20end%20%0Aend%20" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. class  Person < ActiveRecord::Base  
  2.  def  a_method_used_for_validation_purposes  
  3.   errors.add_to_base("This person is invalid because ..." )   
  4.  end
  5. end
class Person < ActiveRecord::Base
 def a_method_used_for_validation_purposes
  errors.add_to_base("This person is invalid because ...") 
 end 
end 


errors.add
errors.add用於將error新增到物件某個特定的屬性上。可以使用full_messages 方法來檢視將會顯示在頁面上的錯誤資訊:

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=class%20Person%20%3C%20ActiveRecord%3A%3ABase%0A%20def%20a_method_used_for_validation_purposes%0A%20%20errors.add(%3Aname%2C%20%22cannot%20contain%20the%20characters%20!%40%23%25*()_-%2B%3D%22)%20%0A%20end%20%0Aend%20%0A%0Aperson%20%3D%20Person.create(%3Aname%20%3D%3E%20%22!%40%23%22)%20%0Aperson.errors.on(%3Aname)%20%20%23%20%3D%3E%20%22cannot%20contain%20the%20characters%20!%40%23%25*()_-%2B%3D%22%20%0Aperson.errors.full_messages%20%23%20%3D%3E%20%5B%22Name%20cannot%20contain%20the%20characters%20!%40%23%25*()_-%2B%3D%22%5D%20" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. class  Person < ActiveRecord::Base  
  2.  def  a_method_used_for_validation_purposes  
  3.   errors.add(:name "cannot contain the characters [email protected]#%*()_-+=" )   
  4.  end
  5. end
  6. person = Person.create(:name  =>  "[email protected]#" )   
  7. person.errors.on(:name )   # => "cannot contain the characters [email protected]#%*()_-+=" 
  8. person.errors.full_messages # => ["Name cannot contain the characters [email protected]#%*()_-+="] 
class Person < ActiveRecord::Base
 def a_method_used_for_validation_purposes
  errors.add(:name, "cannot contain the characters [email protected]#%*()_-+=") 
 end 
end 

person = Person.create(:name => "[email protected]#") 
person.errors.on(:name)  # => "cannot contain the characters [email protected]#%*()_-+=" 
person.errors.full_messages # => ["Name cannot contain the characters [email protected]#%*()_-+="] 


errors.on
errors.on用於檢查某個特定屬性的錯誤資訊。它根據指定的屬性的不同狀態返回不同的物件:如果指定的屬性沒有錯誤,errors.on返 回nil;如果指定的屬性有1個錯誤,errors.on返回這個錯誤的message(字串);如果指定的屬性有多個錯誤,errors.on返回這 些錯誤的message(字串)陣列。

errors.clear
errors.clear用於清除錯誤資訊。

引用 Of course, calling errors.clear upon an invalid object won’t actually make it valid: the errors collection will now be empty, but the next time you call valid? or any method that tries to save this object to the database, the validations will run again. If any of the validations fail, the errors collection will be filled again.


errors.size 不用解釋。

Displaying Validation Errors in the View
當使用form_for來建立表單的時候,可以使用form builder的error_messaages方法來顯示驗證錯誤的結果。

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=class%20Product%20%3C%20ActiveRecord%3A%3ABase%0A%20validates_presence_of%20%3Adescription%2C%20%3Avalue%20%0A%20validates_numericality_of%20%3Avalue%2C%20%3Aallow_nil%20%3D%3E%20true%20%0Aend%20%0A%0A%3C%25%20form_for(%40product)%20do%20%7Cf%7C%20%25%3E%20%0A%20%3C%25%3D%20f.error_messages%20%25%3E%0A%20%20%3Cp%3E%0A%20%20%20%3C%25%3D%20f.label%20%3Adescription%20%25%3E%3Cbr%20%2F%3E%0A%20%20%20%3C%25%3D%20f.text_field%20%3Adescription%20%25%3E%0A%20%20%3C%2Fp%3E%0A%20%20%3Cp%3E%0A%20%20%20%3C%25%3D%20f.label%20%3Avalue%20%25%3E%3Cbr%20%2F%3E%0A%20%20%20%3C%25%3D%20f.text_field%20%3Avalue%20%25%3E%0A%20%20%3C%2Fp%3E%0A%20%20%3Cp%3E%0A%20%20%20%3C%25%3D%20f.submit%20%22Create%22%20%25%3E%0A%20%20%3C%2Fp%3E%20%0A%3C%25%20end%20%25%3E%20" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. class  Product < ActiveRecord::Base  
  2.  validates_presence_of :description :value
  3.  validates_numericality_of :value :allow_nil  =>  true
  4. end
  5. <% form_for(@product do  |f| %>   
  6.  <%= f.error_messages %>  
  7.   <p>  
  8.    <%= f.label :description  %><br />  
  9.    <%= f.text_field :description  %>  
  10.   </p>  
  11.   <p>  
  12.    <%= f.label :value  %><br />  
  13.    <%= f.text_field :value  %>  
  14.   </p>  
  15.   <p>  
  16.    <%= f.submit "Create"  %>  
  17.   </p>   
  18. <% end  %>   
class Product < ActiveRecord::Base
 validates_presence_of :description, :value 
 validates_numericality_of :value, :allow_nil => true 
end 

<% form_for(@product) do |f| %> 
 <%= f.error_messages %>
  <p>
   <%= f.label :description %><br />
   <%= f.text_field :description %>
  </p>
  <p>
   <%= f.label :value %><br />
   <%= f.text_field :value %>
  </p>
  <p>
   <%= f.submit "Create" %>
  </p> 
<% end %> 


也可以使用error_messages_for這個helper來達到同樣的效果:

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%3C%25%3D%20error_messages_for%20%3Aproduct%20%25%3E%20" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. <%= error_messages_for  :product  %>   
<%= error_messages_for :product %> 


這兩個方法都接受3個同樣的選項::header_message, :message和:header_tag。下面是效果對比:

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%3C%25%3D%20error_messages_for%20%3Abook%20%25%3E" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. <%= error_messages_for  :book  %>  
<%= error_messages_for :book %>


Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%3C%25%3D%20error_messages_for%20%3Abook%2C%20%3Aheader_message%3D%3E'header_message'%2C%0A%09%09%3Amessage%3D%3E'message'%2C%20%3Aheader_tag%3D%3E'h1'%25%3E" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. <%= error_messages_for  :book :header_message => 'header_message' ,  
  2.         :message => 'message' :header_tag => 'h1' %>  
<%= error_messages_for :book, :header_message=>'header_message',
		:message=>'message', :header_tag=>'h1'%>


Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%3C%25%3D%20error_messages_for%20%3Abook%2C%20%3Aheader_message%3D%3Enil%2C%0A%09%09%3Amessage%3D%3Enil%2C%20%3Aheader_tag%3D%3Enil%25%3E" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. <%= error_messages_for  :book :header_message => nil ,  
  2.         :message => nil :header_tag => nil %>  
<%= error_messages_for :book, :header_message=>nil,
		:message=>nil, :header_tag=>nil%>
引用 Here is a list with all the available Active Record callbacks, listed in the same order in which they will get called during the respective operations :
10.1 Creating an Object

    * before_validation
    * before_validation_on_create
    * after_validation
    * after_validation_on_create
    * before_save
    * before_create
    * INSERT OPERATION
    * after_create
    * after_save

10.2 Updating an Object

    * before_validation
    * before_validation_on_update
    * after_validation
    * after_validation_on_update
    * before_save
    * before_update
    * UPDATE OPERATION
    * after_update
    * after_save

10.3 Destroying an Object

    * before_destroy
    * DELETE OPERATION
    * after_destroy

after_save runs both on create and update, but always after the more specific callbacks after_create and after_update, no matter the order in which the macro calls were executed.


另外,after_initialize 將在Active Record物件例項化之後被呼叫。包括呼叫類方法new或者從資料庫中載入物件。
after_find 將在Active Record從資料庫載入物件之後呼叫,如果同時定義了after_initialize,after_find將先被呼叫。
注意,after_initialize和after_find這兩個callbacks和其它的有點不同。首先,這兩個callbacks沒有 對應的before_* callbacks。同時,由於效能上的原因,使用它們的唯一方式是將它們定義為一個普通的方法,否則這兩個callbacks將被忽略。(This behaviour is due to performance reasons, since after_initialize and after_find will both be called for each record found in the database, significantly slowing down the queries. 說實話,其實看不太明白。。):

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=class%20User%20%3C%20ActiveRecord%3A%3ABase%0A%20def%20after_initialize%0A%20%20puts%20%22You%20have%20initialized%20an%20object!%22%20%0A%20end%20%0A%20def%20after_find%0A%20%20puts%20%22You%20have%20found%20an%20object!%22%20%0A%20end%20%0Aend%20" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. class  User < ActiveRecord::Base  
  2.  def  after_initialize  
  3.   puts "You have initialized an object!"
  4.  end
  5.  def  after_find  
  6.   puts "You have found an object!"
  7.  end
  8. end
class User < ActiveRecord::Base
 def after_initialize
  puts "You have initialized an object!" 
 end 
 def after_find
  puts "You have found an object!" 
 end 
end 


Running Callbacks

下面的方法將會觸發callbacks:
    *  create
    * create!
    * decrement!
    * destroy
    * destroy_all
    * increment!
    * save
    * save!
    * save(false)
    * toggle!
    * update
    * update_attribute
    * update_attributes
    * update_attributes!
    * valid?
after_find callbacks會被以下方法觸發:
    * all
    * first
    * find
    * find_all_by_attribute
    * find_by_attribute
    * find_by_attribute!
    * last
以下方法會跳過callbacks:
    *  decrement
    * decrement_counter
    * delete
    * delete_all
    * find_by_sql
    * increment
    * increment_counter
    * toggle
    * update_all
    * update_counters

Conditional Callbacks
同Conditional Validation ,只是Conditional Callbacks支援:if和:unless混用。

Ruby程式碼 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yuan.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=class%20Comment%20%3C%20ActiveRecord%3A%3ABase%0A%20after_create%20%3Asend_email_to_author%2C%20%3Aif%20%3D%3E%20%3Aauthor_wants_emails%3F%2C%20%0A%20%3Aunless%20%3D%3E%20Proc.new%20%7B%20%7Ccomment%7C%20comment.post.ignore_comments%3F%20%7D%20%0Aend%20%0A" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
  1. class  Comment < ActiveRecord::Base  
  2.  after_create :send_email_to_author

相關推薦

Active Record Validations and Callbacks

有許多種在儲存資料到資料庫之前驗證資料有效性的方法,包括資料庫原生的約束(constraints)、客戶端的驗證、Controller級別的驗證以及Model級別的驗證。 資料庫約束: 資料庫約束和儲存過程使得驗證機制依賴於資料庫本身,會讓測試和維護更加困難。但是如果你的資

Yii2之Active Record

att ima pda 所有 參數 sin sta fin ive Yii AR很好很強大,但剛開始不知道怎麽使用 如果英文不錯,可以直接看原文地址http://www.yiiframework.com/doc/guide/1.1/en/database.ar 對於一

Rails中重寫Active Record字段屬性

col attr record span 需要 AC code end div  系統重構或升級時偶爾會碰到需要重寫某個字段的情況,例如: 1. 讀取user的name字段時,實際返回name_new字段 class User < ActiveRecord::Ba

Active Record in Rails 4

Active Record is the object-relational mapping (ORM) layer supplied with Rails. It is the part of Rails that implements your application’s model. Thi

Active Record 設計模式原理及簡單實現

概述 本文簡要介紹Active Record 設計模式。Active Record 是一種資料訪問設計模式,它可以幫助你實現資料物件Object到關係資料庫的對映。 應用Active Record 時,每一個類的例項物件唯一對應一個數據庫表的一行(一對一

Execute Monkey and Record Log and Screen

Here is an example to do monkey test and record log and device screen. SET REPEAT_TIMES=10 SET ADB_PREFIX=adb SET APP_NAME=MMS

Active Record 基礎

Active Record 是 MVC 中的 M(模型),負責處理資料和業務邏輯。Active Record 負責建立和使用需要持久存入資料庫中的資料。Active Record 實現了 Active Record 模式,是一種物件關係對映系統。 Active Record

PEAA筆記六:Active Record

What is it Active Record包裝了資料表或檢視中的一行資料,封裝了它的資料庫訪問行為,並加入了該資料的業務邏輯。也可以這樣看,Active Record是加入了資料庫訪問行為的Domain Object ^_^ How it works Active Re

YII2-資料查詢Active Record方法

查詢資料 AR 提供了兩種方法來構建 DB 查詢並向 AR 例項裡填充資料: •[[yii\db\ActiveRecord::find()]] •[[yii\db\ActiveRecord::findBySql()]] 以上兩個方法都會返回 [[yii\db\Active

samba服務錯誤:Starting SMB/CIFS File and Active Directory Server. [FAIL]

出現錯誤:Starting SMB/CIFS File and Active Directory Server. [FAIL] 現象:samba服務兩次啟動,其中有一次沒有起來顯示fail 方案一: sudo rm /etc/init/samba-ad-dc.conf

Android App To Record And Share Your Important Thoughts

Today, am happy to introduce to you my newest android application : Quotes! In a nutshell, this android app helps you record your deepest, perhaps mos

30,000 Images/Second: Xilinx and AMD Claim AI Inferencing Record

On the heels of its dual announcement at the Open Compute Project Summit in Amsterdam this week (see related story), Xilinx yesterday disclosed that AMD an

數字影象處理筆記——Snakes演算法、活動輪廓以及水平集(Snakes, active contours, and level sets)

Snakes演算法 上一講我們講的影象分割演算法主要是基於畫素的,這一講主要是基於曲線的。我們希望能得到一個能夠包圍住影象輪廓的平滑的曲線,snakes演算法就是一個很有用的演算法。首先我們將曲線的座標x、y同一用引數s表示,s範圍從0-1代表從起點繞曲線一週再回到原點 我們假定初始化

Record and Upload Videos with React Native

Record and Upload Videos with React NativeIn one of my last blog posts, Samuel Omole asked me if I could do an article about uploading content with React N

wyh2000 and pupil

cor other miss 貪心 -i mission spa size foo wyh2000 and pupil Accepts: 93 Submissions: 925 Time Limit: 3000/1500 MS (Java/Other

[Binary Hacking] ABI and EABI

about specific pap spec ica app .debian rpc cati Following are some general papers about ABI and EABI. Entrance https://en.wikiped

《Thinking in Java》 And 《Effective Java》啃起來

大學 前言 技術 數據結構和算法 解決 一句話 定義 應該 太多的 前言   今天從京東入手了兩本書,《Thinking in Java》(第四版) 和 《Effective Java》(第二版)。都可以稱得上是硬書,需要慢慢啃的,預定計劃是在今年前把這兩本書啃完。哈哈,可

The connection to adb is down, and a severe error has occured

真的 findstr ole pla a10 tool fcm ott art 相信不少人在android中都遇到了你下面不好解決的問題: 首先描寫敘述癥狀,例如以下圖 解決方法: 方法1:先在cmd中adb kill-server,然後adb -startser

A - Mike and palindrome

nbsp == 字符串長度 cda problem eal iostream quotes aaa A - Mike and palindrome Mike has a string s consisting of only lowercase English le

code force 798cMike and gcd problem

sub while 並且 cati put ins i++ des 替代 Mike has a sequence A?=?[a1,?a2,?...,?an] of length n. He considers the sequence B?=?[b1,?b2,?...,?b