修改下 In Place Editing 插件
In Place Editing 这个插件代码非常简洁,却方便的实现了即时编辑的效果,不过自从从 Rails 的核心移出去之后,貌似就没有再升级过。
首先它不支持 Validate,In Place Editing 的保存不经过检查,即使你 validates_presence_of :name,也可以在 In Place Editing 中把 name 清空并保存,而且这样做了之后,由于 name 没有了文字,也没法点击编辑了。
另外它也不支持 protect_from_forgery。
虽说有个 REST In Place 插件,似乎是 In Place Editing 的替代品,其实稍微修改一下,In Place Editing 就能重放光芒了~
没法 validate 的缘故是因为它用了 update_attribute 的方法更新属性,只要改成 update_attributes 就可以了,然后检查保存是否成功,如果失败,将错误信息显示出来:
lib/in_place_editing.rb:
-
def in_place_edit_for(object, attribute, options = {})
-
define_method("set_#{object}_#{attribute}") do
-
@item = object.to_s.camelize.constantize.find(params[:id])
-
if @item.update_attributes({attribute.to_sym => params[:value]})
-
render :text => @item.send(attribute).to_s
-
else
-
render :text => @item.errors.on(attribute.to_sym)
-
end
-
end
-
end
也可以加个样式着重下错误信息:
-
render :text => "<span style='color:red;'>#{@item.errors.on(attribute.to_sym)}</span>"
protect_from_forgery 的问题只要加上 authenticity_token 参数就可以了:
lib/in_place_macros_helper.rb:
-
def in_place_editor_field(...)
-
...
-
in_place_editor_options[:url] = in_place_editor_options[:url] || url_for({ :action => "set_#{object}_#{method}", :authenticity_token => form_authenticity_token, :id => tag.object.id })
-
...
-
end
这样就 OK 了,效果还不错:
respond_to 新构想
respond_to 非常好用,可以根据不同的 format 来选择不同的应答策略,并且自动设置相应的 MIME 值,看上去也非常爽目。
在 Blog 系统中,比如文章的 RSS,就可以:
-
def index
-
@posts = Post.find(:all)
-
respond_to do |format|
-
format.html { ...}
-
format.rss {...}
-
end
-
end
这样比在单独构建一个 RSS action 要好得多~
不过,如果 Blog 通过 html 显示出来的话,还需要做其他一些事情,比如构建 Blog 的各个边栏,这些事情一般都放在 before_filter 中去做:
-
class PostsController < ApplicationController
-
before_filter :get_sidebars
-
...
但是这些工作在 RSS 中完全不需要,那么怎么在 RSS 忽略掉这些工作呢?
一个选择就是去掉 before_filter,把 get_sidebars 写入到 format.html { } 中去,这样的话,PostsController 里面每个 action 的 format.html 都要这样做,不是啥好办法。
第二个选择就是在 get_sidebars 里面检测 format:
-
def get_sidebars
-
if params[:format] == "html"
-
...create sidebars
这样似乎还算 ok,其他的方法还没有想出来……
前两天,正好看到 maiha 写的新 respond_to 表示方法的构想,去掉 respond_to 那个 block,而按照 aciton.format 的格式,把不同 format 的处理,放到单独的函数中去:
-
def index
-
@posts = Post.find(:all)
-
end
-
-
def index.html
-
...
-
end
-
-
def index.rss
-
...
-
end
这样看上去比 respond_to 清晰了很多,如果可以实现,那么如果在 before_filter 里面也可以:
-
before_filter :get_sidebars, :only => "*.html"
就能完美的解决上面的问题了~
用 Texvc 生成数学公式
is-Programmer 目前用 l2p 这个小程序,配合 TeX 系统来生成数学公式图片,现在又有新的选择了,那就是 Texvc ~
texvc 是 MediaWiki 附带的用来生成公式图片的小程序,在 MediaWiki 安装路径下的 Math 目录中可以找到这个程序,和 l2p 一样,需要配置好 TeX 环境。
genki 写了一个简单的 texvc 的 Ruby wrapper,这样在 ruby 中就可以方便的生成公式图片了~
首先安装,gem 包名称叫做 genki-texvc:
-
sudo gem install genki-texvc
使用方法非常简单:
-
require 'texvc'
-
Texvc.parse( 'f(x)=\int_0^x \sin(t)\,dt' ) #=> Magick::Image
就会生成:
parse 之后会返回一个 Magick::Image 实例,你可以显示出来,或者写到文件中,或者再做进一步处理~
Ruby 1.8.6 p230 p238 有内存泄漏 Bug
这两天有些奇怪,服务器上 Rails 进程的内存占用总是不断上涨,只要一天时间,内存就暴满,然后开始啃虚拟内存,网站也变得很慢。
开始以为是 ruby-gettext 的问题,因为 1.90 的 ruby-gettext 确实有这么个内存泄漏的 bug,不过我当初打过了补丁,应该不会出现问题。尝试升级到 1.91,问题依旧……
接着怀疑是代码本身的问题,不过前些日子一直正常,这两天又没有改过网站代码,所以排除。
后来想起来,上个星期把服务器上的 ruby 升级为最新的 1.8.6_p230,难道问题出在这里? Google 了一下,果然:
[Ruby 1.8 - Bug #216] (Open) Memory leaks in 1.8.6p230 and p238
看来 production 下不能使用 p230 和 p238 了,即使是 is-Programmer 这样流量很小的网站,问题都很严重。
降级回 1.8.6_p114,问题解决~
像 Lua 那样引用 Hash 元素
Lua 中的 Table 可以拿来当作多种数据格式来使用,比如 Hash ( Dictionary ):
-
h = {a=1,b=2,c=3}
-
print(h['a'])
-
1
最爽的是,可以用 h.a 这种形式来引用 Hash 中的元素:
-
print(h.a)
-
1
利用 Ruby 的 method_missing,也可以这样爽一把,仅仅需要:
-
class Hash
-
def method_missing(method, *args)
-
self[method]
-
end
-
end
即可,测试:
-
h = {:a => 1, :b => 2, :c => 3}
-
puts h.a
-
1
只要 hash 的 key 不要与 Hash 内置的方法重名就可以了~
啥?还要实现赋值? 这个好办,只要将上面的代码改为:
-
class Hash
-
def method_missing(method, *args)
-
if method.to_s =~ /=$/
-
self[method.to_s.chop.to_sym] = *args
-
else
-
self[method]
-
end
-
end
-
end
就可以了,测试:
-
h = {:a => 1, :b => 2}
-
h.a = 456
-
puts h.a
-
456
感觉不错~