will_paginate分页:limit参数不升效
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
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实现随机验证码
ValidatorImageGeneratorController.rb代码如下
ruby 代码
- class ValidatorImageGeneratorController < ApplicationController
- before_filter :record_code
- skip_filter :record_url
- def image
- if session[:code_image]
- send_data(session[:code_image], :type => ’image/jpeg’)
- else
- #exception thrown
- end
- end
- private
- def record_code
- image = ValidatorImage.new
- session[:code] = image.code
- session[:code_image] = image.code_image
- end
- end
ValidatorImage.rb代码如下(此文件位于app/model下面)
ruby 代码
- require ’rubygems’
- require ’RMagick’
- class ValidatorImage
- include Magick
- attr_reader :code, :code_image
- Jiggle = 5
- Wobble = 5
- Len = 4
- def initialize
- code_array = []
- 1.upto(Len) { code_array << rand(9).to_s }
- granite = Magick::ImageList.new(’xc:#EDF7E7′)
- canvas = Magick::ImageList.new
- canvas.new_image(20 * Len, 20, Magick::TextureFill.new(granite))
- text = Magick::Draw.new
- #text.font_family = ”times”
- text.pointsize = 15
- 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, 15 + rand(Jiggle), c){
- self.rotation=rot
- self.font_weight = weight
- self.fill = ’green’
- }
- cur += 20
- }
- @code = code_array.to_s
- @code_image = canvas.to_blob{ self.format = ”JPG” }
- end
- end
需要使用的时候在html的img标签中引入就可以了。
code_image_url方法片段:
ruby 代码
- def code_image_url
- url_for :controller => :validator_image_generator, :action => :image
- 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发邮件的两个方法
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’)
浏览器的等宽字体
<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 编码中文,计算字符串个数问题。
这样中文字符串的个数就对了,否则会计算成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
require ‘benchmark’
puts Benchmark.realtime {
system “…..”
}
会打印初程序运行的时间。
性价比高的网球品牌
Bonny-波力
http://www.bonny.cn/
Teloon 天龙
http://www.teloon.com/
在rails里面怎么做loading或显示花了多少时间?等结果出来自动跳转到结果页面
我有一个contorller要调用system做个运算在返回结果,但是时间比较久大概1分钟,我怎么在页面做个类似loading或者显示已用时间的功能,等结果出来自动跳转到结果呢?
def app
“system ….”大概一分钟,结果返回到一个文件result.txt
@str = IO.read(”result.txt”)
end
怎么在页面做个类似loading或者显示已用时间的功能,等结果出来自动跳转到结果呢?
app.rhtml
<%= @str %>
hash数组从调出value相同的子散列
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里面?
<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有什么方法吗?
