作者归档:船长

重庆涞滩古镇和二佛寺

一个多月前去的涞滩古镇, 到今天才传上了照片.

重庆涞滩古镇和二佛寺
涞滩古镇的城门 继续阅读

发表在 人在旅途, 浮光掠影 | 留下评论

如何复兴越剧?

前天晚上和网友聊天时得知今天下午一个剧院里有越友演出,今天开了闹钟.起床时11点. 起床后连连打哈欠.

做饭, 吃饱后转着广场几个公车站找能到那个剧院的公车. 终于找到了, 可惜下错了站, 之后又上错上了另一辆公车, 最后才换了一个能到的. 到时已经2点多, 幸运的是原定1:30的演出刚好拖到此时要开幕.

场不算大, 但坐得算很满. 有一好心的大伯看我找座, 忙把我让到他身边的一个空位.

剧场上拉是一横幅, 从这字幅看这是为纪念越剧百年, 贵阳, 重庆, 成都三地的越友共同自费组织的一场表演.
如何复兴越剧?
开幕了, 上来两位很标准的主持念"经典"的台词

表演进行了大概三小时. 都是越剧选段, 选的最多的是梁祝. 表演者大多挂着XX剧团的名字, 最多的是一重庆的剧团. 表演者的水平就我个人听来都不怎么样. 给我印象最深的倒是其中唯一一对没有挂名的外地"越友"的演唱. 唱者声音洪亮, 字正腔圆, 韵味十足.他们演唱结束后掌声雷动, 赞声连连. 但最受观众欢迎的好像不是这一对, 而是一位来自本地的早期专业越剧演员. 听说以前她在重庆是红到发紫. 她上去清唱了一段. 除了不断的拉长音虚词, 我没听明白一个字. 但她下台后台下几乎沸腾了. 不少观众叫着"再来一个, 再来一个." 结果我担心的事件没有发生 –她说自己没有准备, 没有再来一个. 她让我明白了一个道理: 做网站不要看网站站长的背景功底, 而要看他做出来的网站; 或很多人技术不错, 但就不用来做正事, 都用到歪道上, 做出来的网站不一定有用. 正如越剧不是把词拉得越长越好听, 但功力好的演员却常常要为了表现自己功力而扫观众的兴.
如何复兴越剧?
这些演员将反复上台演出

如何复兴越剧?
这两位应该就是我说的唱得很不错的越友

如何复兴越剧?
再来一张, 可惜还是没照清楚

如何复兴越剧?
这个是从 碧玉簪 里选的." 婆婆"表情还是比较非富的.

如何复兴越剧?
可怜的祥林嫂

正如刚才说的,观众来了不少. 但基本上全是中老年, 其中又以女性居多. 或我, 一个二十多岁的男青年坐在剧场很显眼, 两个拿DV记录的都跟到我这边留个录像.
如何复兴越剧?
基本上全是中老年观众

这事让我很担心.
为什么看越剧的都是中老年呢? 这对越剧有什么影响呢?
究其原因有两种可能:
第一种可能是越剧本来就是为老年人开发的艺术. 从100年前, 到100年后的现在, 越剧就一直只是中老年人喜爱的. 人非要过40岁才有可能恋上越剧.
如果真是这样,应该也算是一件好事啊. 中国的老龄化问题听说很严重啊, 以后的老人会越来越多. 这样的话越剧的潜在观众也会更多.
第二可能是越剧本来是全民文化, 但后来受到电影,电视, 现代流行音乐, 电子游戏等其它娱乐项目的竞争,在现代社会中对新生代几乎没有了任何吸引力. 新青年都对越剧不感兴趣, 没有或很少新越剧迷加入, 从而越剧只被为固执的老资格戏迷所喜爱, 而这些人逝老, 形成只有中老越剧迷这种青黄不接的情景.
如果是这个情形的话越剧是把房子盖在沙堆上, 很危险啊.

无论上面是那个情况, 如果越剧能让青年喜欢, 都是好事. 为什么越剧不能吸引青年呢?
我上面提到过电影, 电视, 音乐, 游戏等的竞争, 如果这些东西都当作敌人, 而且他们的攻击力很强, 越剧现居弱势, 长此下去, 必将不敌啊.
所在我感觉越剧要兴, 必仗一字 — 变!
越剧很美, 但美中有不足, 有不让人喜欢的原因.

就比如拉长音, 虽然运用得当, 很是可以强烈地加强人物情感. 但也是越剧在当今的一大把柄. 随着商品经济的发展, 人们进了快节奏的生活方式, 但戏剧太"慢"了. 一部戏近3个小时, 可实际上没说上几句话.假如唱一句要半分钟,年青观众没这个耐性子. 年青人说:"我一分钟几百万上下, 还听你这样磨嘴皮?"
(娘子——————————啊…(开唱), 没等开唱, 那"子—"就能吓跑一半的青年人, 你说这个"子—"除了吓人, 还有什么功能作用的???)
(五女拜寿 做得很好.)

剧本少,剧本改来改去, 没什么新鲜情节. 剧情俗, 本来故事就不多, 而且还都很不合时代, 故事大多是给非常传统的人写的.
越剧没有电影那样的惊心场面, 没有游戏里面的激情互动. 但这两个不算缺点. 本来越剧就是通过朴素的背景服装唱词唱法来叙述看来平淡, 听完却感天动地之情的艺术. 有特色才有存在的价值.

我一直希望越剧能重兴, 但我说的重兴是怎样一个度呢?
从舞台表演到屏幕表演的改革(媒体传播向网络化发展, 舞台表演本身就限制越剧的传播)
屏幕后不再重唱梁祝(因为有录相了), 每年像贺岁片一样, 一年一部新片. 新故事, 新创意, (新演员).

人百年或已德高望重,  越剧百年或已将长存之道蕴含在自身的历史之中.

看完演出, 走出大门, 我径直又上了一辆公车. 到了终点站才发现又坐错了. 这才等来一辆能到沙坪坝的公车. 这车也不对–它竟开了一个多小时才到沙坪坝. 我把渴的眼睛发绿.

发表在 越剧柔情 | 留下评论

成功的条件

今天在想成功的条件, 现在总结有这几条:
成功在这里指完成一件事.
1.坚定决心
一要很想完成这事,欲望很强; 二要对这事坚贞不逾, 事不成不罢休, 包括在遇到多大的困难和挫折时都不改志向.
2.人际关系
好人际关系可以得到很多的帮助, 使事件的发展势势如破竹.
3.人力物力
做事的基础. 包括自己的技能(人力之一).
4.计谋策略
做事的方法
5.天时地利

发表在 成败几何 | 留下评论

舍 得

有时候舍就是得,得就是舍. 要取舍清楚.

发表在 成败几何 | 留下评论

如何长生不老

如何才能长生不老是我一直在研究的课题之一.
虽然我还未能找到长生的方法.但我找到了一个很重要的线索.
要做到长生不老,起码要做到的一个就是:
不狂喜,不痛悲

情感是使人衰老,特别是悲愁. 我亲眼看到过N个中年人因为一件愁心的事半年之后成为老年人. 由中年过度到老年更决定的因素不是年月,而是情感.

古书更有一夜白发的事件无数, 我相信这是真实的.

要做到长寿,很重要的就是做到不狂喜,不痛悲.对得失都看得很淡泊.

要如何能做到这点呢?

本身的思想眼光应该是广博的. 心怀宇宙. 对于百,一为少,对于万,百为小,对于亿,万亦不足道. 对于年,日为短,于宇宙的长存,人之一生演的不过是百年的喜悲; 人活于浩瀚之天地,人的手脚舞动不过在尺寸之内. 之于无际的宇宙,人只是不起眼的一个小点, 算得了什么? 这样的一生得到什么,又失去什么, 一定要让人狂喜,一定要让人痛悲???

 每在不顺心时我都会仰望天空, 看着广阔的天空或浩瀚的星空,我的不顺心有如宇宙间的一颗尘埃,微–不足道!

发表在 我思我在 | 2 条评论

Ruby on Rails页面缓存

三种方式 Page Caching, Action Caching和 Fragment Caching

缓存默认只在production 环境下启动

Page Caching
caches_page :public_content
以URL为准
expire_page :action =>"public_content"

Action Caching
caches_action :premium_content
以URL为准
 expire_action :action => "premium_content", :id => article
 Page Caching 和 Action Caching的实例:
class ContentController < ApplicationController
 before_filter :verify_premium_user, :except => :public_content
 caches_page :public_content
 caches_action :premium_content
 cache_sweeper :article_sweeper,
        :only => [ :create_article,
        :update_article,
        :delete_article ]
 def public_content
  @articles = Article.list_public
 end
 def premium_content
  @articles = Article.list_premium
 end
 private
 def verify_premium_user
  return
   user = session[:user_id]
   user = User.find(user)
  if user
   unless user && user.active?
   redirect_to :controller =>  "login", :action => "signup_new"
  end
 end
end

删除过期缓存内容:
app/models中加article_sweeper.rb
class ArticleSweeper < ActionController::Caching::Sweeper
 observe Article
 def after_create(article)
  expire_public_page
 end
 def after_update(article)
  expire_article_page(article.id)
 end
 def after_destroy(article)
  expire_public_page
  expire_article_page(article.id)
 end
 private
 def expire_public_page
  expire_page(:controller => "content", :action => ‘public_content’)
 end
 def expire_article_page(article_id)
  expire_action(:controller =>  "content",
        :action => "premium_content",
        :id => article_id)
 end
end
app/public/content/show/1默认caches_page文件路径
app/public/content/show/1.html

Fragment Caching
controller:
class Blog1Controller < ApplicationController
 def list
  @dynamic_content = Time.now.to_s
  unless read_fragment(:action => ‘list’)
   logger.info("Creating fragment")
   @articles = Article.find_recent
  end
 end
end
#read_fragment()查看一个action的fragment缓存是否存在
view:
<%= @dynamic_content %> <!– 动态内容 –>
<% cache do %> <!– 缓存开始–>
 <ul>
 <% for article in @articles -%>
  <li><p><%= h(article.body) %></p></li>
 <% end -%>
 </ul>
<% end %> <!– 结束缓存 –>
<%= @dynamic_content %> <!– 其它动态内容 –>

使用多个缓存段:
<% cache(:action => ‘list’, :part => ‘articles’) do %>
 <ul>
 <% for article in @articles -%>
  <li><p><%= h(article.body) %></p></li>
 <% end -%>
 </ul>
<% end %>
<% cache(:action => ‘list’, :part => ‘counts’) do %>
 <p>There are a total of <%= @article_count %> articles.</p>
<% end %>
#使用:part参数区分同一action下的不同缓存段

缓存过期
controller:
class Blog2Controller < ApplicationController
 def list
  @dynamic_content = Time.now.to_s
  @articles = Article.find_recent
  @article_count = @articles.size
 end
 def edit
  # 编辑文章时不更新统计缓存
  expire_fragment(:action => ‘list’, :part => ‘articles’)
  redirect_to(:action => ‘list’)
 end
 def delete
  #删除文章时同时删除两个缓存
  expire_fragment(:action => ‘list’, :part => ‘articles’)
  expire_fragment(:action => ‘list’, :part => ‘counts’)
  redirect_to(:action => ‘list’)
 end
end

expire_fragment()可接正则表达式
expire_fragment(%r{/blog2/list. })

Fragment Caching存储选项设置:
ActionController::Base.fragment_cache_store = <下面的选项之一>
ActionController::Caching::Fragments::FileStore.new(path)
ActionController::Caching::Fragments::DRbStore.new(url)
ActionController::Caching::Fragments::MemCachedStore.new(host)

发表在 Ruby on Rails | 留下评论

Ruby on Rails Action Controller学习笔记

自动增加预载model方法:
class StoreController < ApplicationController
 model :cart, :line_item
 observer :stock_control_observer
 # …

如果没有找到相应的action, method_missing()将被调用
如果没有任何action, Rails会直接找template显示.

Ruby on Rails链接
Routing Requests
配置文件:config/routes.rb
ActionController::Routing::Routes.draw do |map|
 map.connect ‘:controller/service.wsdl’, :action => ‘wsdl’
 map.connect ‘:controller/:action/:id’
end

map.connect可用参数:
:defaults => { :name => "value", …}
 设默认值,默认为:defaults => { :action => "index", :id => nil }
:requirements => { :name =>/regexp/, …}
:name => value
:name => /regexp/

实例:
ActionController::Routing::Routes.draw do |map|
 #从上到下优先级降低.
 #’http://my.app/blog/&#39; 直接显示 index
 map.connect "blog/",
   :controller => "blog",
   :action =>"index"
 #按日期访问博客文章列表
 map.connect "blog/:year/:month/:day",
      :controller =>"blog",
      :action =>"show_date",
      :requirements => { :year => /(19|20)\d\d/,
               :month => /[01]?\d/,
               :day => /[0-3]?\d/},
      :day =>nil,
      :month =>nil
 # 按文章ID显示文章内容
 map.connect "blog/show/:id",
      :controller => "blog",
      :action =>"show",
      :id => /\d+/
 # 管理页面,常规
 map.connect "blog/:controller/:action/:id"
 # 其它
 map.connect "*anything",
      :controller =>"blog",
      :action =>"unknown_request"
 #=> URL>junk
 #=>@params = {:anything=>["junk"], :controller=>"blog", :action=>"unknown_request"}
end

链接生成url_for
@link = url_for :controller => "store", :action => "display", :id => 123
生成:http://pragprog.com/store/display/123
url_for(:controller => "store", :action => "list",
 :id => 123, :extra => "wibble")
生成:http://rubygarden.org/store/list/123?extra=wibble
url_for(:overwrite_params => {:year => "2002"})
生成:http://pragprog.com/blog/2002/4/15
#url_for会使用默认环境中的参数自动补充出完整的地址
#但一般补最后面的
#使用:overwrite_params使之补前面的.
url_for(:year=>year, :month=>sprintf("%02d", month), :day=>sprintf("%02d", day))
用来填充位数???
url_for(:controller => "/store", :action => "purchase", :id => 123)
#=> http://my.app/store/purchase/123
url_for(:controller => "/archive/book", :action => "record", :id => 123)
#=> http://my.app/archive/book/record/123

redirect_to(:action =>’delete’, :id => user.id)
# 和上面的一样:
redirect_to(:action => ‘delete’, :id => user)

default_url_options()
:anchor string #+string
:host string  (helper.pragprog.com:8080)
:only_path boolean
:protocol string ("https://";)
:trailing_slash boolean (+"/"?)

有名字的 Routes
map.date "blog/:year/:month/:day",
    :controller =>"blog",
    :action =>"show_date",
    :requirements => { :year => /(19|20)\d\d/,
            :month => /[01]?\d/,
            :day => /[0-3]?\d/},
    :day =>nil,
    :month =>nil
可调用
date_url(:year => 2003, :month => 2)
#=> http://pragprog.com/blog/2003/2

方法
把action藏起来,让它使用URL访问不了.
hide_action :check_credit
def check_credit(order)
# …
end

Controller Environment
request
  domain()
  remote_ip()
  env() 如:request.env['HTTP_ACCEPT_LANGUAGE']
  method (:delete, :get, :head,:post, or :put.)
   delete?, get?, head?, post?, and put?
class BlogController < ApplicationController
 def add_user
  if request.get?
   @user = User.new
  else
   @user = User.new(params[:user])
   @user.created_from_ip = request.env["REMOTE_HOST"]
   if @user.save
    redirect_to_index("User #{@user.name} created")
   end
  end
 end
end

params
cookies
response
session
headers

runder()
更改默认template目录
ActionController::Base.template_root=dir_path
render(:text=>string)
class HappyController < ApplicationController
 def index
  render(:text =>"Hello there!")
 end
end

render(:inline=>string, [ :type =>"rhtml"|"rxml"] )
class SomeController < ApplicationController
 if RAILS_ENV == "development"
  def method_missing(name, *args)
   render(:inline => %{  
    <h2>Unknown action:#{name}</h2>
    Here are the request parameters:<br/>
    <%= debug(params) %> })
  end
 end
end

render(:action =>action_name)
def display_cart
 if @cart.empty?
  render(:action => :index)
 else
  # …
 end
end

render(:file =>path, [ :use_full_path =>true|false] )

render(:template =>name)
class BlogController < ApplicationController
 def index
  render(:template =>"blog/short_list")
 end
end

render(:partial =>name, …)
render(:nothing => true)
render_to_string() 不发送,直接转为string

发送
send_data
def sales_graph
png_data = Sales.plot_for(Date.today.month)
 send_data(png_data, :type => "image/png", :disposition => "inline")
end

send_file
def send_secret_file
 send_file("/files/secret_list")
 headers["Content-Description"] = "Top secret"
end

有些地方使用redirect_to代替render
redirect_to(:action => ‘display’)

redirect_to(options…)
redirect_to(path)
redirect_to(url)

Cookies and Sessions
Cookies只能存String
class CookiesController < ApplicationController
 def action_one
  cookies[:the_time] = Time.now.to_s
  redirect_to :action =>"action_two"
 end
 def action_two
  cookie_value = cookies[:the_time]
  render(:text => "The cookie says it is #{cookie_value}")
 end
end

cookies[:marsupial] = { :value => "wombat",
          :expires => 30.days.from_now,
          :path =>"/store" }
可用选项 :domain, :expires,:path, :secure, and :value

Sessions
保存model时要先预载:
class BlogController < ApplicationController
 model :user_preferences

设置session:
ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS[:session_key] = ‘my_app’
可用选项:
:database_manager
:session_domain
:session_id
:session_key
:session_path
:session_secure
Session保存选择:
:database_manager => CGI::Session::PStore
  flat file (单服务器推荐)
:database_manager => CGI::Session::ActiveRecordStore
:database_manager => CGI::Session::DRbStore
:database_manager => CGI::Session::MemCacheStore

Flash用于在两个action传输暂时信息
flash.now用法实例:
class BlogController
 def display
  unless flash[:note]
   flash.now[:note] = "Welcome to my blog"
  end
  @article = Article.find(params[:id])
 end
end

flash.keep用法实例:
class SillyController
 def one
  flash[:note] = "Hello"
  redirect_to :action => "two"
 end
 def two
  flash.keep(:note)
  redirect_to :action => "three"
 end
 def three
  # flash[:note] => "Hello"
 render
 end
end

Filters
class BlogController < ApplicationController
 before_filter :authorize, :only => [ :delete, :edit_comment ]
 after_filter :log_access, :except => :rss
 # …
before_filter可用来替换全局页面中的字符,如{$title}
也可用来给页面 Zlib压缩
Around Filters可用来计算action用时

Verification
class BlogController < ApplicationController
 verify :only => :post_comment,
 :session => :user_id,
 :add_flash => { :note =>"You must log in to comment"},
 :redirect_to => :index
 # …
使用范围:
:only =>:name or [ :name, ... ]
:except =>:name or [ :name, ... ]
通过条件:
:flash =>:key or [ :key,... ]
:method =>:symbol or [ :symbol, ... ](:get, :post, :head, or :delete)
:params =>:key or [ :key,... ]
:session =>:key or [ :key,... ]
反应:
:add_flash =>hash
:redirect_to =>params

 GET Requests
 GET用来获取信息
 POST用来传输更改数据库的信息
 <%= link_to ‘删除评论’, { :action => ‘com_destroy’, :id => comment },
     :confirm =>"你确定要删除这则评论吗?",
     :post => true %>
使用forms和buttons

发表在 Ruby on Rails | 留下评论

更多Ruby on Rails的Active Record

Callbacks
class User < ActiveRecord::Base
 before_destroy :dont_destroy_dave
 def dont_destroy_dave
  raise "Can’t destroy dave" if name == ‘dave’
 end
end

class Order < ActiveRecord::Base
 # ..
 def before_save
  self.payment_due ||= Time.now + 30.days
 end
end

class Order < ActiveRecord::Base
 before_validation :normalize_credit_card_number
 after_create do |order|
  logger.info "Order #{order.id} created"
 end
 protected
 def normalize_credit_card_number
  self.cc_number.gsub!(/-\w/, ”)
 end
end

Callback Objects 全局可以访问
class CreditCardCallbacks
 # Normalize the credit card number
 def before_validation(model)
  model.cc_number.gsub!(/-\w/,”)
 end
end

class Order < ActiveRecord::Base
 before_validation CreditCardCallbacks.new
 # …
end
 Subscription < ActiveRecord::Base
class
 before_validation CreditCardCallbacks.new
 # …
end
可用于数据加密

格式化数据类型:
class LineItem < ActiveRecord::Base
 def total_price
  Float(read_attribute("total_price"))
 end
end

数量单位转换:
class ProductData < ActiveRecord::Base
 CUBITS_TO_INCHES = 18
 def length
  read_attribute("length") * CUBITS_TO_INCHES
 end
 
 def length=(inches)
  write_attribute("length", Float(inches) / CUBITS_TO_INCHES)
 end
end

find_by_sql没有读取PK时不能保存的实例:
result = LineItem.find_by_sql("select quantity from line_items")
result.each do |li|
 li.quantity += 2
 li.save
end

有特殊功能的段名
created_at, created_on, updated_at, updated_on
 ror自动更新的时间段
 修改ActiveRecord::Base.default_timezone = :utc参数更改变时区
lock_version
type
 (employee, manager, person..)
id
XXX_id (FK)
xxx_count
position (acts_as_list)
partent_id (acts_as_tree)

发表在 Ruby on Rails | 留下评论

Ruby on Rails 的检验方法(Validation Helpers)大全

可以自定义validate(), 这个方法在每次保存数据时都会被调用.
如:
def validate
 if name.blank? && email.blank?
  errors.add_to_base("You must specify a name or an email address")
 end
end
同时也可以自定义 validate_on_create(), validate_on_update()方法.
 valid?()方法可以随时调用,用来测试数据是否能通过校验
返回的错误信息可用 error_messages_for(model)方法显示.
如:<%= error_messages_for ‘article’ %>

校验大全:
validates_acceptance_of
 指定checkbox应该选中. (如:(*)我同意条款)
 用法:validates_acceptance_of attr… [ options... ]
 参数:message text  默认:“must be accepted.”
   :on :save, :create, or :update
 实例:
 class Order < ActiveRecord::Base
  validates_acceptance_of :terms,
              :message => "Please accept the terms to proceed"
 end

validates_associated
 查验指定的object.
 用法:validates_associated name… [ options... ]
 参数:message text 默认: is “is invalid.”
   :on :save, :create, or :update
 实例:
 class Order < ActiveRecord::Base
  has_many :line_items
  belongs_to :user
  validates_associated :line_items,
            :message => "are messed up"
  validates_associated :user
 end

validates_confirmation_of
 数据重校
 用法:validates_confirmation_of attr… [ options... ]
 参数:message text 默认 “doesn’t match confirmation.”
   :on :save, :create, or :update
 实例:
 对密码表:
 <%= password_field "user", "password" %><br />
 <%= password_field "user", "password_confirmation" %><br />
 #第二表名为xxxx_confirmation
 class User < ActiveRecord::Base
  validates_confirmation_of :password
 end

validates_each
 使用block检验一个或一个以上参数.
 用法:validates_each attr… [ options... ] { |model, attr, value| … }
 参数:allow_nil boolean 设为true时跳过nil对象.
   :on :save, :create, or :update
 实例:
 class User < ActiveRecord::Base
  validates_each :name, :email do |model, attr, value|
   if value =~ /groucho|harpo|chico/i
    model.errors.add(attr,"You can’t be serious, #{value}")
   end
  end
 end

validates_exclusion_of
 确定被检对象不包括指定数据
 用法:validates_exclusion_of attr…, :in => enum [ options... ]
 #enum指一切可用include?()判断的范围.
 参数:allow_nil 设为true将直接跳过nil对象.
   :in (or :within) enumerable
   :message text 默认为: “is not included in the list.”
   :on :save, :create, or :update
 实例:
 class User < ActiveRecord::Base
  validates_exclusion_of :genre,
            :in => %w{ polka twostep foxtrot },
            :message =>"no wild music allowed"
  validates_exclusion_of :age,
             :in => 13..19,
             :message =>"cannot be a teenager"
 end

validates_inclusion_of
 确认对象包括在指定范围
 用法:validates_inclusion_of attr…, :in => enum [ options... ]
 参数:allow_nil 设为true直接跳过nil对象
   :in (or :within) enumerable An enumerable object.
   :message text 默认:“is not included in the list.”
   :on :save, :create, or :update
 实例:
 class User < ActiveRecord::Base
  validates_inclusion_of :gender,
            :in => %w{ male female },
            :message =>"should be ‘male’ or ‘female’"
  validates_inclusion_of :age,
            :in => 0..130,
            :message =>"should be between 0 and 130"
 end

validates_format_of
 用正则检验对象
 用法:validates_format_of attr…, :with => regexp [ options... ]
 参数:message text 默认为: “is invalid.”
   :on :save, :create, or :update
   :with 正则表达式
 实例:
 class User < ActiveRecord::Base
  validates_format_of :length, :with => /^\d+(in|cm)/
 end

validates_length_of
 检查对象长度
 用法:validates_length_of attr…, [ options... ]
 参数:in (or :within) range
   :is integer
   :minimum integer
   :maximum integer
   :message text 默认文字会根据参数变动,可使用%d 取代确定的最大,最小或指定数据.
   :on :save, :create, or :update
   :too_long text 当使用了 :maximum后的 :message
   :too_short text ( :minimum )
   :wrong_length ( :is)
 实例:
 class User < ActiveRecord::Base
  validates_length_of :name, :maximum => 50
  validates_length_of :password, :in => 6..20
  validates_length_of :address, :minimum => 10,
                :message =>"seems too short"
 end

validates_numericality_of
 检验对象是否为数值
 用法:validates_numericality_of attr… [ options... ]
 参数:message text 默认 “is not a number.”
   :on :save, :create, or :update
   :only_integer
 实例:
 class User < ActiveRecord::Base
  validates_numericality_of :height_in_meters
  validates_numericality_of :age, :only_integer => true
 end

validates_presence_of
 检验对象是否为空
 用法:validates_presence_of attr… [ options... ]
 参数:message text 默认:“can’t be empty.”
   :on :save, :create, or :update
 实例:
 class User < ActiveRecord::Base
  validates_presence_of :name, :address
 end

validates_uniqueness_of
 检验对象是否不重复
 用法:validates_uniqueness_of attr… [ options... ]
 参数:message text 默认: “has already been taken.”
   :on :save, :create, or :update
   :scope attr 指定范围
 实例:
 class User < ActiveRecord::Base
  validates_uniqueness_of :name
 end

 class User < ActiveRecord::Base
  validates_uniqueness_of :name, :scope =>"group_id"
 end
 #指定在同一group_id的条件下不重复.

常用正则:

E-Mail地址格式:
validates_format_of     :email,
                        :with       => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i,
                        :message    => ‘email must be valid’

网址格式:
validates_uri_existence_of :url, :with =>
        /(^$)|(^(http|https)://[a-z0-9] ([-.]{1}[a-z0-9] )*.[a-z]{2,5}(([0-9]{1,5})?/.*)?$)/ix

 

发表在 Ruby on Rails | 留下评论

Ruby on Rails 的Active Record之Acts As List和Acts As Tree

Acts As List实例:
在子表中加parent_idposition

定义:
class Parent < ActiveRecord::Base
 has_many :children, :order => :position
end
class

Child < ActiveRecord::Base
 belongs_to :parent
 acts_as_list :scope => :parent_id
#:scope 指定在parent_id相同范围内.
end

向表中添加数据:
parent = Parent.new
%w{ One Two Three Four}.each do |name|
 parent.children.create(:name => name)
end
parent.save

定义显示方法:
def display_children(parent)
 puts parent.children.map {|child| child.name }.join(", ")
end

调用实例:
display_children(parent) #=> One, Two, Three, Four

puts parent.children[0].first? #=> true
#使用last?(), first?()判断行位置

two = parent.children[1]
puts two.lower_item.name  #=> Three
puts two.higher_item.name #=> One
#使用.lower_item访问下一行数据, 使用.higher_item访问上一行数据,使用

parent.children[0].move_lower
parent.reload

display_children(parent) #=> Two, One, Three, Four
#使用mover_lower(), mover_higher()可移动行数据
#使用parent.reload刷新数据

parent.children[2].move_to_top
parent.reload
display_children(parent) #=> Three, Two, One, Four
#使用move_to_top(), move_to_bottom()移动行数据

parent.children[2].destroy
parent.reload
display_children(parent) #=> Three, Two, Four
#一行数据删除后其下面的行会自动跟上

Acts As Tree实例:
向子表新增parent_id (int), 并将设定为表内关联键

定义方法:
class Category < ActiveRecord::Base
 acts_as_tree :order =>"name"
end

向表格添加数据:
root = Category.create(:name => "Books")
fiction = root.children.create(:name =>"Fiction")
non_fiction = root.children.create(:name => "Non Fiction")

non_fiction.children.create(:name =>"Computers")
non_fiction.children.create(:name =>"Science")
non_fiction.children.create(:name =>"Art History")

fiction.children.create(:name =>"Mystery")
fiction.children.create(:name => "Romance")
fiction.children.create(:name =>"Science Fiction")

定义显示方法:
def display_children(parent)
 puts parent.children.map {|child| child.name }.join(", ")
end

调用实例:
display_children(root) # Fiction, Non Fiction

sub_category = root.children.first
puts sub_category.children.size #=> 3
display_children(sub_category) #=> Mystery, Romance, Science Fiction

non_fiction = root.children.find(:first, :conditions => "name = ‘Non Fiction’")

display_children(non_fiction) #=> Art History, Computers, Science

puts non_fiction.parent.name #=> Books

:counter_cache => true+children_count段也可以在这里使用.用来自动计算子表行数.

发表在 Ruby on Rails | 一条评论