月归档:四月 2007

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 | 一条评论

Ruby on Rails数据表格关系

一对一关系实例: one-to-one
class Order < ActiveRecord::Base
has_one :paid_order,
    :class_name =>"Order",
    :foreign_key => "order_id",
    :conditions => "paid_on is not null"
在表格上加order_id (表格名单数_id)
class Invoice < ActiveRecord::Base
belongs_to :order

可选参数:class_name, :foreign_key,  :order, :conditions
:dependent => true #删除主表行时同时删除子行
自定义的order用法:
class Customer < ActiveRecord::Base
has_many :orders
has_one :most_recent_order,
    :class_name => ‘Order’,
    :order => ‘created_at DESC’
end

主.从 将被保存
an_invoice = Invoice.new(…)
order.invoice = an_invoice # invoice被保存
从.主 将要手动保存

新增加的方法:
product(force_reload=false)
product=(obj)
build_product(attributes={})
create_product(attributes={})

一对多关系(one-to-many)
class Order < ActiveRecord::Base
has_many :line_items
可选参数除了上面的,还有:exclusively_dependent, :finder_sql,:counter_sql
:exclusively_dependent 在子行没有其它表格瓜葛的情况下使用, 加快处理速度.
:finder_sql的使用实例:
class Order < ActiveRecord::Base
has_many :rails_line_items,
     :class_name => "LineItem",
     :finder_sql => "select l. * from line_items l, products p " +
     " where l.product_id = p.id " +
     " and p.title like ‘%rails%’"
end
order的用法:
class Order < ActiveRecord::Base
has_many :line_items,
   :order =>"quantity, unit_price DESC"
end

主.从 将被保存
an_invoice = Invoice.new(…)
order.invoices <<an_invoice # invoice

class LineItem < ActiveRecord::Base
belongs_to :order
. . .

has_many后可以引用集合:
order = Order.find(123)
total = 0.0
order.line_items.each do |li|
 total += li.quantity * li.unit_price
end

新增加的方法:
orders(force_reload=false)
orders <<order
orders.push(order1, …)
orders.delete(order1, …)
orders.clear
orders.find(options…)
orders.build(attributes={})
orders.create(attributes={})

多对多关系(many-to-many):
class Product < ActiveRecord::Base
has_and_belongs_to_many :categories
. . .
class Category < ActiveRecord::Base
has_and_belongs_to_many :products
. . .

要创建一个中间表格:
categories_products
两表格名字复数形式相联, 排字母前后排序

表格内连关联键

预载子表
用:include将子表内容加入内存,提高查询速度, 但损耗内存:
for post in Post.find(:all, :include => [:author, :comments])
 puts "Post: #{post.title}"
 puts "Written by: #{post.author.name}"
 puts "Last comment on: #{post.comments.first.created_on}"
end

自动计算子表行数
 belongs_to加参数:counter_cache => true
 数据库加 子表格名(复数)_count 段, 并加 :default=>0参数.
 然后用 .size可以读取子表行数.
刷新数据读法:product.line_items(:refresh).size

发表在 Ruby on Rails | 2 条评论

越剧迷心得

1.千万不要和戏子同去应试。因为在状元只有一位的前提下,你同科高中的机率微乎其微。
2.女孩追男孩的最好方法就是满地丢东西。想找郎君的女孩最好随身带把沉香扇或紫玉钗,如果没有,普通的玉坠也是不错的选择。
3.如果想要找一个贞节烈女,那千万要去妓院。 妓院几乎常驻德才兼备的美女,她们守身如玉,冰清玉洁,知书达理,才华出众,最可贵的是通常不羡慕钱权而独爱才子,是穷苦书生泡妞的首选宝地。
4.鉴于《玉蜻蜓》,《碧玉簪》,《玉镯记》,《紫玉钗》等名戏铺道, 最好写古代戏,因为现代人基本上不戴首饰,所以为现代戏起名将成为一大难题。
5.要时常留意府里收的书童或杂工,因为他们很可能是那位公子为拐骗女儿而装扮进来的。

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

越剧中的可爱人物

看过了不少越剧. 喜欢上了越剧里面的一些人物. 我把这些人物的名字和演员的名字记下来, 以防止以后忘了这些可爱的人.

《五女拜寿》
邹士龙(茅威涛)
热心,可爱
翠云(何赛飞)
风雪中忍饿受冻为主人乞食, 不是女儿, 比女儿孝顺.

《司马相如与卓文君》

司马相如(夏赛丽)
乐观,有才有情, 忠一, 忠心, 为民
卓文君(何赛飞)
爱的就是司马相如, 不听父命另嫁郎
有主见, 敢爱就爱的卓文君私奔随情郞, 保命留情改写<梁祝>悲剧
乐观, 对丈夫信任

《玉蜻蜓》
申元宰(王君安)
一子愿养三母.知书达理, 孝顺

《风雨渔樵》
(好酷的脚本)
刘玉仙(华怡青)
关心他人, 明理, 坚强
(朱买臣泼水后她说的话好酷.)
平常心境平常过,疏疏淡淡对坎坷
弱女不服命, 伤痛自己抚

《盘妻索妻》
刘仁元(郭丽英)
英雄救美, 又成人之美, 将救来的美女做媒给同学, 可见热心之真纯.

《碧玉簪》
李秀英(金采凤)
再三拒风寇, 对虽然已经成了状元的丈夫的人性看得透彻
无奈受世俗伦理影响, 最后接寇也是不得已的出路.

《陈三两》
陈三两(黄依群)
身在风尘, 心系黎民
住在青楼却传教高尚人品

《卖油郎》
卖油郎(毕春芳)

忠厚热心的卖油郎, 这也是毕春芳舞台形像的化身.

《情洒罗山》
李良臣(钱惠丽)
不羡皇宫千佳丽, 只望得与妻相守一生

《紫玉钗》
崔允明(章瑞虹)
为朋友两肋插刀,当在所不辞

《追鱼》
鲤鱼(王文娟)
可爱还须要理由吗?

《柳永与虫娘》
虫娘(王桂萍)
识柳永奇才, 说行行出状元,劝柳永放弃功名, 把自己的兴趣做成事业, 见解大胆.
为琴献身, 为情献身, 即便失身真节在, 青楼女原是如此明白人.
晏殊(裘巧芳)
二万金钱青楼沽笑, 只为成人之美.

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

论 重庆女大学生靠色情服务月入可超2万

新闻原文:不久前,《新京报》披露了重庆市警方破获一起女大学生从事色情服务的消息。据警方掌握的情况,重庆目前约有近百家此类公司,招募为数不详的女大学生从事色情服务。涉案的女大学生多供职于各类伴游、商务咨询公司、商务俱乐部,实质从事着三陪、卖淫活动。该案牵涉当地数所院校,一些从事色情服务的女大学生月收入超过2万元。
论 重庆女大学生靠色情服务月入可超2万

女大学生在色情场所吃香且价格畸高,是一种让人感到苦涩不堪的“知识经济”。那些乐于在女大学生面前大把大把甩钞票的人,他们所购买的,除去女大学生与其他女性无甚差别的生理方面服务外,还有女大学生相对比较高雅的谈吐和修养。

如果你是卖身的?
长于人生长远规划方面考虑, 我介意你马上找一所三流大学就读. 最好是艺术学院, 外语学院次之. 现在只要有钱基本上就能进大学, 或能跟校长发生关系更好. 不要在乎这付出, 因为进去后你身价倍增, 你的投资马上就能收回.

但是, 为什么要卖身呢?
除此了女大学生希望了解社会,证明自己的成熟或报复与惩罚心理,或寻求慰藉等原因外, 更主要的原因是钱.
一者社会变革,思想上人对性价值观的改变. "性解放"让女人不再守节, 男人不再忠一. "洁身自爱"不但得不到表扬, 而且可能受人嘲讽. 二来社会上物质和金钱的作用越来越大. 人们开始明白金钱不但可以换来生活日用品, 还可以换得学位, 官职, 爱情甚至生命. 有了这两者, 中间加性可以互换金钱(性<=>金钱), 出现女大学生"献身"色情服务可谓"全情全理","天经地义".

活生生的性交易实录 –“他说要帮我找工作”
文慧(化名)是重庆某大学2000级大学生,即将毕业离校。

"我出生在吉林农村,家里很穷,我父母都是很好很老实的人,母亲很多年没有穿过新衣服,父亲不抽烟不喝酒也不赌博,他们只是没有谋生技能而已,所以,我不管走到什么样的境地,都觉得没有任何怪罪他们的理由。换句话说,我是咎由自取。"

"从小我就比别人长得好看,我有北方农村少见的白皮肤,父母因此很疼惜我,很少让我干家务活。我在村里上小学,在镇上上初中,在县城里上高中,我的外号就从“村花”变成“镇花”再变成“县花”。高一的时候,我自编的独舞还在学校汇演中得了一等奖。"

……..

"辛苦读完四年大学. 你不知道有多少人都在等一份工作,最后发现原来一家小公司的小文秘都需要重点本科英语六级容貌俏丽身高165厘米以上,最后说薪水不过800元,还有几乎上百人排队等面试。这本来就是一个投机的社会,我总要活下去。"

"大四下学期,朋友给我介绍了一个所谓的作家,我看过他的东西,文采平平,用《像鸡毛一样飞》里面的台词来说,“十年以前是个新人,十年以后还是个新人”,喜欢自吹自擂,认为自己才高八斗。我很配合,装作很崇拜的样子,其实每次听到他千篇一律的演讲词,我就觉得好笑。 "

"他说他要帮我找工作。 "

"有一天傍晚,他给我打电话说帮我找了一家外地的杂志社,说里面的那个主任以前是他的学生,小说都是跟他学的。我可以进去先在杂志发行部做着。他在电话中一再强硬让我马上过他那里去一趟,说要跟我细谈。他老婆回娘家去了,他给我收拾了客房,很正人君子的样子。我不动声色,看他能支撑多久。结果我睡了不到10分钟,他敲门进来,手里托着围棋,说要跟我切磋一下。 "

"我知道他心里在想什么,因为我的烂技术竟然把他杀得溃不成军,可见他的心思根本不在棋上。他鬼祟得让我觉得可悲。"

—-"最后事情发生了吗? "

"发生了。很可笑,是我提出来的,我看见他那个样子,觉得他比我好不到哪儿去。 "

—–"工作的事情怎么样?"

"没有回音,所谓的杂志社主任,看起来根本不买他的账,推托得很明显。其实看他那样子,我就知道事情没有他说得那么轻巧。现在我已经绝望了,我觉得我所托非人,因此得不偿失。"

—–"如果下一次有人能确实解决你的问题,而需要你付出身体,你会不会答应?"

"也许会。得到一些东西,总要付出一些东西,而除了身体我什么都没有,我只能拿它去换. "

23岁不到,言语中对这个世界,却已经有明显的嘲讽。

文慧说,人就是要拿自己有的东西,去换自己没有的东西。她觉得她只有身体,而没有的东西,实在太多。

评论
文慧的大学也是用身体换来的. 她用身体从一厂长那换来了2万元的学费. 或你会同情她: 她家里穷, 上不了大学, 没有办法.
我到曾在海南儋州里的华南热带农业大学里住过. 那里没钱, 家里交不起大学学费的人有很多. 但他们不卖身, 他们贷款交学费, 他们下课后收破烂赚生活费.
还有, 中国的烂大学, 你不上它就没有别的办法成才?
很多自考生在外企工作了. 他们当时上不起大学, 到深圳打工, 一办打工赚钱养活自己(可能还要寄钱给家里的弟弟或妹妹上学),一边学习.
只要你想, 问题就一定有解决的办法. 只要你从内心堕落, 你总能找到借口.
上文中最后一句说:"她觉得她只有身体,而没有的东西,实在太多。"
我想问文慧啊, 你四年大学都玩什么了? 你玩到自己只有身体了. 你就不会用四年的大学时间学一门技术? 学外语, 学好了当同声传译, 老俞说那个工资是一小时5000元, 要不你学机械技工啊, 学好了到东莞, 一个月工资5000也没问题…
你用你的身体换来了20000元的学费, 然后到学校玩了四年, 你对得起你四年前的那个身体吗???
说你混到现在, 只留下了身体? 我问你, 这身体真的是你的? 那是你父母给你的. 你的父母给了你身体, 不但不能指望你来光宗耀祖, 你还混到了你卖你父母给你的身体过日子, 先不要说"没有任何怪罪父母的理由", 你先问问自己, 你对得起自己的父母吗?
最可悲的是你而竟然放弃了你的舞蹈天赋…

问题的重点
"她觉得她只有身体,而没有的东西,实在太多"
她有什么?
健康的身体, 健全的智商. 有了这两样, 加上耐心和刻苦, 你还有什么得不到的???
她没有什么?
一个安分守己的心, 一个知足常乐的心. 或她最缺的应该是另一盒化妆品. 但这化妆品永远填不满虚荣的心.

你能美多久?
SK-II能让你美多久? 化妆品不会让50岁的女人年轻, 但会让50岁的女人看起来更像妖精.

你能美多久??
年过花甲的戚雅仙站在舞台上老态龙钟, 但她只要张嘴唱出那越剧, 我感叹她很美.

什么是金钱?
金钱是工具, 借助它我可以生存,并实现我的其它愿望.
但它只是手段, 实现人生目标的手段.
为了人生而用合适的方法赚一定的金钱.
而不为了金钱而人生.
卖淫可以得到了金钱, 但从她第一次卖淫开始, 她的身心将一生背负一个永远不能擦洗的烙印, 如果这个烙印不是你的人生目标之一, 我想对卖淫之前的她说"赚钱有的是办法."

发表在 其它 | 留下评论

Ruby on Rails 数据库Migration操作语句实例

def self.up     # db schema更新到下一版本
  create_table :table, :force => true do |t| #创建表格
    t.column :name, :string
    t.column :age, :integer, { :default => 42 }
    t.column :description, :text
    # :string, :text, :integer, :float, :datetime, :timestamp, :time, :date,
    # :binary, :boolean
  end
  add_column :table, :column, :type #添加段

  rename_column :table, :old_name, :new_name #修改段名
  change_column :table, :column, :new_type #修改段数据类型
  execute "SQL语句"
  add_index :table, :column, :unique => true, :name => ‘some_name’  #添加索引
  add_index :table, [ :column1, :column2 ]
end

def self.down   # 撤消操作
  rename_column :table, :new_name, :old_name
  remove_column :table, :column
  drop_table :table #删除表格
  remove_index :table, :column
end

发表在 Ruby on Rails | 留下评论