logoruby


will_paginate分页:limit参数不升效

Posted in rails by wanguan2000 on the 09月 22nd, 2008

will_paginate有一个隐藏属性total_entries返回的是总记录数。
@todos = Todo.paginate :page => params[:page],:total_entries => 20

total entries  not needed unless you want to count the records yourself

will_paginate插件很好用,但是在Rails的development模式下查看SQL日志时发现这样的现象:
使用paginate_by_sql方法来search数据时生成这样的两条SQL语句:

SELECT COUNT(*) FROM(select a.* from table_a where ... order by id asc) AS count_table

select a.* from table_a where ... order by id asc

这样的SELECT COUNT语句的性能就很有问题了。
查看will_paginate的实现-》finder.rb:

def paginate_by_sql(sql, options)
        options, page, per_page = wp_parse_options!(options)
        sanitized_query = sanitize_sql(sql)
        total_entries = options[:total_entries] || count_by_sql("SELECT COUNT(*) FROM (#{sanitized_query}) AS count_table")

        returning WillPaginate::Collection.new(page, per_page, total_entries) do |pager|
          options.update :o ffset => pager.offset, :limit => pager.per_page
          add_limit! sanitized_query, options
          pager.replace find_by_sql(sanitized_query)
        end
      end

原来paginate_by_sql方法有一个:total_entries参数,这样我们可以自己写优化的不需要order by的省略很多查询条件的count语句,然后将count number作为参数:total_entries传过去即可:

def get_count_of_xxx
  count_by_sql "select count(1) from table_a a where ..."
end

def get_xxx
  paginate_by_sql "select a.* from table_a where ... order by id asc", :total_entries => get_count_of_xxx
end
评论关闭

Rails实现随机验证码

Posted in rails by wanguan2000 on the 09月 19th, 2008

ValidatorImageGeneratorController.rb代码如下

ruby 代码

  1. class ValidatorImageGeneratorController < ApplicationController   
  2.      
  3.   before_filter :record_code  
  4.   skip_filter :record_url  
  5.   
  6.   def image       
  7.     if session[:code_image]   
  8.       send_data(session[:code_image], :type => ’image/jpeg’)   
  9.     else  
  10.       #exception thrown   
  11.     end  
  12.   end  
  13.      
  14.   private   
  15.   def record_code   
  16.     image = ValidatorImage.new  
  17.     session[:code] = image.code   
  18.     session[:code_image] = image.code_image   
  19.   end  
  20.      
  21. end  

ValidatorImage.rb代码如下(此文件位于app/model下面)

ruby 代码

  1. require ’rubygems’   
  2. require ’RMagick’   
  3.   
  4. class ValidatorImage   
  5.   include Magick   
  6.   attr_reader :code, :code_image  
  7.   Jiggle = 5   
  8.   Wobble = 5   
  9.   Len = 4   
  10.      
  11.   def initialize   
  12.     code_array = []   
  13.     1.upto(Len) { code_array << rand(9).to_s }   
  14.     granite = Magick::ImageList.new(’xc:#EDF7E7′)   
  15.     canvas = Magick::ImageList.new  
  16.     canvas.new_image(20 * Len, 20, Magick::TextureFill.new(granite))   
  17.     text = Magick::Draw.new  
  18.     #text.font_family = ”times”   
  19.     text.pointsize = 15   
  20.     cur = 10       
  21.     code_array.each { |c|    
  22.       rand(10) > 5 ? rot = rand(Wobble) : rot = -rand(Wobble)   
  23.       rand(10) > 5 ? weight = NormalWeight : weight = BoldWeight   
  24.       text.annotate(canvas, 0, 0, cur, 15 + rand(Jiggle), c){   
  25.         self.rotation=rot   
  26.         self.font_weight = weight   
  27.         self.fill = ’green’   
  28.       }   
  29.       cur += 20   
  30.     }   
  31.     @code = code_array.to_s   
  32.     @code_image = canvas.to_blob{ self.format = ”JPG” }   
  33.   end  
  34. end  

需要使用的时候在html的img标签中引入就可以了。    

    code_image_url方法片段:

ruby 代码

  1. def code_image_url   
  2.     url_for :controller => :validator_image_generator, :action => :image  
  3. end  

简单说明,利用RMagick插件随机生成数字,调用validator_image_generator controller 下的 image action 时候,由于record_code filter的存在,会将验证码存储在session中。验证时候从sesssion中取就可以了

#2

class Part < ActiveRecord::Base

require ‘RMagick’

require “cgi”

 

include Magick

attr_reader :code, :code_image  #类的2个属性

  Jiggle = 15

  Wobble = 15

def initialize(len)

  #chars = (’a’..’z').to_a-['a','e','i','o','u']

  code_array=[]

  codex=”"

  rr=0

  1.upto(5) {

    rr=65+rand(25)

    code_array << rr

    }            #随机生成5个大写字母

  #code_array=[rand(rr).chr,rand(rr).chr,rand(rr).chr,rand(rr).chr]

  #1.upto(len) {code_array << chars[rand(chars.length)]}

  granite = Magick::ImageList.new(’granite:’)    #生成granite样式的背景

  canvas = Magick::ImageList.new    #定义一个画布

  canvas.new_image(24*4,20, Magick::TextureFill.new(granite))   #granite放画布上

  text = Magick::Draw.new    #文字

  #text.font_family = ‘times’

  text.pointsize = 20                  #文字大小

  cur = 10

  code_array.each{|c|

     c=c.to_i

     c=c.chr

     codex=codex+c               #acs码(数字)转为字母

    #rand(10) > 5 ? rot=rand(Wobble):rot= -rand(Wobble)

    rand(10) > 5 ? weight = NormalWeight : weight = BoldWeight

    ra=1000

    while ra<100000

        ra=rand(999999)

    end

    rn=’#'+ra.to_s

    text.annotate(canvas,20,20, cur,18,c){      #text对象放canvas上

      self.rotation=rand(30)                     #旋转角度

      self.font_weight = weight

    

      self.fill = rn                              #text(文字)颜色

    }

    cur += 15

  }

  @code = codex                                #生成文字(字符串格式)

 

  @code_image = canvas.to_blob{              #生成图片(二进制格式)

    self.format=”JPG”

  }

end

        

#3

rails实现验证码

    网上其实有一大堆这样的资料了,我再写也没多大价值,谈下几个注意点吧。
1.在windows上安装Rmagic,如果你是通过gem安装的,

require ’Rmagic’

要修改为:

require ’rubygems’
require ’Rmagick’

才能正确引入。

2.网上那个例子,画布是使用Rmagic内置的图像格式,Rmagic内置的图像格式还有:

gradient*

梯度,比如gradient:red-blue

granite

花岗石,比如: "granite:".

logo

logo型的图像. 如: "logo:",后面会多显示一个五角星^_^

netscape

非常漂亮的彩条。如: "netscape:"

null*

空白 使用方式: "null:"

rose玫瑰 使用方式 : "rose:"

xc*

设置一个背景色,比如”xc:green”
一个修改的例子,在rails的models下存为noisy_image.rb,在Controller就可以这样调用NoisyImage.new(6) :

require ’rubygems’
require ’Rmagick’
class NoisyImage
include Magick
attr_reader :code, :code_image
Jiggle = 15
Wobble = 15

def initialize(len)
chars = (’a’..’z').to_a - ['a','e','i','o','u']
code_array=[]
1.upto(len) {code_array << chars[rand(chars.length)]}
granite = Magick::ImageList.new(’xc:#EDF7E7′)
canvas = Magick::ImageList.new
canvas.new_image(32*len, 50, Magick::TextureFill.new(granite))
text = Magick::Draw.new
text.font_family = ’times’
text.pointsize = 40
cur = 10

code_array.each{|c|
rand(10) > 5 ? rot=rand(Wobble):rot= -rand(Wobble)
rand(10) > 5 ? weight = NormalWeight : weight = BoldWeight
text.annotate(canvas,0,0,cur,30+rand(Jiggle),c){
self.rotation=rot
self.font_weight = weight
self.fill = ’green’
}
cur += 30
}
@code = code_array.to_s
@code_image = canvas.to_blob{
self.format=”JPG”
}
end

end

3.与rails应用的结合,和一般的验证码原理一样,将产生的随机数存储在session或者request范围内,提交的时候进行比较验证即可。比如产生图片的时候将随机字母存储在session[:code]中:

 session[:noisy_image] = NoisyImage.new(6)

 session[:code] = session[:noisy_image].code

验证的时候,比较提交的type_code与session[:code]即可,为了安全性考虑,最好还是不考虑使用客户端验证。

 unless session[:code]==params[:type_code]
flash[:notice]=’验证码填写错误,请重新注册,谢谢!’
return redirect_to :action=>:new
end

在页面显示图片,类似servlet一样直接调用Controller的action:

 def code_image
image = session[:noisy_image].code_image
send_data image, :type => ’image/jpeg’, :disposition => ’inline’
end

<img height=’30′ src=”/test/code_image”>

 

 

评论关闭

ruby发邮件的两个方法

Posted in ruby by wanguan2000 on the 09月 19th, 2008

require ‘net/smtp’
Net::SMTP.start(’smtp.sina.com’, 25 , ’sina.com’ ’spring_test@sina.com’,'123456′,:login) do |smtp|
smtp.send_message(’dsfdsfsdf’, ’spring_test@sina.com’,’spring_test@sina.com’)
end

安装这些

sudo gem install actionmailer
sudo gem install mime-types

ActionMailer::Base.delivery_method = ’smtp’
ActionMailer::Base.smtp_settings = {
:address => “smtp.sina.com”,
:domain => “sina.com”,
:authentication => “login”,
:user_name => “spring_test@sina.com”,
:password => “123456″
}
ActionMailer::Base.default_charset = “utf-8″

#2222

require ‘rubygems’
require ‘action_mailer’

ActionMailer::Base.smtp_settings = {
:address => “smtp.163.com”,
:port => 25,
:domain => “163.com”,
:user_name => “wanguan_2000@163.com”,
:password => “2.71828″,
:authentication => :login
}

ActionMailer::Base.default_charset = “utf-8″

class SimpleMailer < ActionMailer::Base

def simple_message(recipient)
from ‘wanguan_2000@163.com’
recipients recipient
subject ‘A single-part message’
body ‘This message !!!!’

end
end

#puts SimpleMailer.create_simple_message(’wanguan2000@gmail.com’)

SimpleMailer.deliver_simple_message(’wanguan2000@gmail.com’)

评论关闭

浏览器的等宽字体

Posted in rails by wanguan2000 on the 09月 18th, 2008

<style>
BODY   {
margin:0;
line-height:12px;
font-size:12px;
font-family:”mono”;
font-style:normal;
font-weight:normal;
font-variant:   small-caps
}
</style>

评论关闭

linux下:unicode 编码中文,计算字符串个数问题。

Posted in rails, ruby by wanguan2000 on the 09月 17th, 2008

这样中文字符串的个数就对了,否则会计算成3个。

$KCODE=’u’
require ‘jcode’

a= ‘好’

puts a.size
puts a.jsize

puts a.length
puts a.jlength

在rails里面更简单,用 puts a.chars.length

加chars就可以了,是rails自带的方法。

评论关闭

程序运行的时间benchmark

Posted in ruby by wanguan2000 on the 09月 12th, 2008

require ‘benchmark’

puts Benchmark.realtime {
system “…..”
}

会打印初程序运行的时间。

评论关闭

性价比高的网球品牌

Posted in 网球 by wanguan2000 on the 09月 12th, 2008

Bonny-波力
http://www.bonny.cn/

Teloon 天龙
http://www.teloon.com/

评论关闭

在rails里面怎么做loading或显示花了多少时间?等结果出来自动跳转到结果页面

Posted in 未分类 by wanguan2000 on the 09月 11th, 2008

我有一个contorller要调用system做个运算在返回结果,但是时间比较久大概1分钟,我怎么在页面做个类似loading或者显示已用时间的功能,等结果出来自动跳转到结果呢?

def app
“system ….”大概一分钟,结果返回到一个文件result.txt
@str = IO.read(”result.txt”)
end

怎么在页面做个类似loading或者显示已用时间的功能,等结果出来自动跳转到结果呢?
app.rhtml

<%=  @str %>

评论关闭

hash数组从调出value相同的子散列

Posted in ruby by wanguan2000 on the 09月 11th, 2008

empty = {’two’ => 2, ‘eight’ =>8, “one” => 2, “third” => 2 }

p empty.find{|k,v| v == 2 }
p empty.find_all{|k,v| v == 2 }
p empty.select{|k,v| v == 2 }

评论关闭

javascript的函数的参数值怎么传到rails里面?

Posted in rails by wanguan2000 on the 09月 9th, 2008

<html>
<head>

<script language=”javascript” type=”text/javascript”>
<!–

function generatePara(){
var a=10;
return a;
}

function generatePara2(){
window.location.href=”http://localhost:3000/look/form/”+generatePara;
}

//–>
</script>
</head>
<body>

Response.Write(”<script language=javascript>alert(’恭喜您,注册成功!’);window.location.href=’main.html’</script>”)
<input type=button name=aa value=”返 回” onclick=”window.location.replace=”http://localhost:3000/look/form/”+generatePara”>

<input type=button name=aa value=”返 回” onclick=”window.location.replace(’”http://localhost:3000/look/form/”+generatePara /’)”>

</body>
</html>

rails有什么方法吗?

评论关闭
下一页 »