论坛首页 编程语言技术论坛

在rails中优雅的进行模型校验

浏览 19560 次
该帖已经被评为精华帖
作者 正文
   发表时间:2008-09-08  
dave liu 写道
不管代码是怎么来的   代码中处理的方法似乎比gigix的好   gigix的有牛刀宰鸡的嫌疑

如果你半年里每天对着这一两百个action你就不会这么想了
0 请登录后投票
   发表时间:2008-09-08  

 

gigix 写道
dave liu 写道
不管代码是怎么来的 代码中处理的方法似乎比gigix的好 gigix的有牛刀宰鸡的嫌疑

如果你半年里每天对着这一两百个action你就不会这么想了

 

 俺们做的系统需要处理的有这种需求的表单不会有上百个,而且无非加个判断而已,是可以接收的,而且gigix的方法貌似是存在的写文件的问题。

 

另外我想问问gigix同学,你的方法中,在过滤器是不是要判断对哪个表单进行校验,怎么弄的啊?如果有些model的保存只涉及一个model也要去过滤下全修改全不修改吗?哎……头疼

13 请登录后投票
   发表时间:2008-09-08  
right now 写道
另外我想问问gigix同学,你的方法中,在过滤器是不是要判断对哪个表单进行校验,怎么弄的啊?如果有些model的保存只涉及一个model也要去过滤下全修改全不修改吗?哎……头疼

sigh
以前Spring那么火的时候你们在干什么呢…真疑惑…
对于绝大多数action,你不需要知道里面出了”什么“错,你只需要知道只要里面出了错,那么所有的数据库操作都应该回滚
对于少数action,你需要在回滚的同时再回调一些东西来收拾残局
就这么简单
0 请登录后投票
   发表时间:2008-09-08  
around_filter的方法确实比较巧妙,一开始看到就想起了spring,这个解决方案应该是优雅的,而且非常的通用。至于说什么删除图片的问题,根本不会存在,因为transaction fail的时候after_save这些根本也不会被调用的。用了快两年的rails,还没用过around_filter,汗。。。 这里学了一招 。
0 请登录后投票
   发表时间:2008-09-08  
在保存模型时还要处理上传图片时,我自己的做法通常是在 before_save 中处理图片。
因为需要按照上传时间等信息生成 hash 后的图片文件名,再把图片文件名放入模型,最后保存模型。

在 before_save 中处理图片失败时可以抛出异常来引起事务回滚,如果放在 after_save 里面处理图片就不好办了吧?
0 请登录后投票
   发表时间:2008-09-15  
gigix 写道
liuqiang 写道
呵呵,针对20个表单的过滤器,代码肯定不止20行,2者代码都不是很多,没必要斤斤计较啦,综合考虑,您再仔细琢磨琢磨,哪种方法比较爽

8行
class TransactionFilter
  def filter(controller)
    return yield if controller.request.get?
    ActiveRecord::Base.transaction do
      yield
    end
  end
end

你大概还需要2~3行把它声明在application.rb里面
作为比较,我这个项目大概有150~200个action

重点在于:
(1)重复
(2)不必要的思考

 

比较欣赏这个方法。有点像简化版的声明型事务。

 

0 请登录后投票
   发表时间:2008-09-15  
gigix 写道
right now 写道
另外我想问问gigix同学,你的方法中,在过滤器是不是要判断对哪个表单进行校验,怎么弄的啊?如果有些model的保存只涉及一个model也要去过滤下全修改全不修改吗?哎……头疼

sigh
以前Spring那么火的时候你们在干什么呢…真疑惑…
对于绝大多数action,你不需要知道里面出了”什么“错,你只需要知道只要里面出了错,那么所有的数据库操作都应该回滚
对于少数action,你需要在回滚的同时再回调一些东西来收拾残局
就这么简单

 

 sigh , 我当然要知道出什么错啦,我还指望返回错误信息给用户呢!

 

LZ 和快克王给出的是错误校验的具体办法,你所说的是事务,你只不过是想说把这个校验放到filter中而已,这本身就是2回事。用了事务(当然是必须的),难道就不需要数据校验了不成?这个事情是省不掉的,但照你的意思,就是管他什么格式,只要知道出错了就可以了,我觉得这样太恐怖了。当然你可能又另有蹊径去解决,你还是说清楚吧(这种校验也是必要的),省得误导群众。

 

PS:借用一句话,这年头谁也不比谁多懂一点,劝各位还是按gigix的做法实践一遍在发言吧

13 请登录后投票
   发表时间:2008-11-06  
gigix 写道
liuqiang 写道
注意,您还是把您这个方法的调用,说明下

class ApplicationController < ActionController::Base
  around_filter :transaction_filter
  def transaction_filter(&block)
    TransactionFilter.new.filter(self, &block)
  end

今天在google一个rails transaction问题的时候发现又回到了这篇,用gigix的这种方法会有一个问题:
rails的around_filter是在整个action执行完以后才会执行,这样事务边界就被扩大到了整个action
def foo
#希望有个改进的filter机制从这里开始
  model1.save
  model2.save
#在任何render之前结束
  render :action => :bar
#而不是象现在的around_filter在这里结束
end

回头再看看rails的代码,是否能够找个简单的地方hack一下。
0 请登录后投票
   发表时间:2008-11-06  
我非常反对gigix这种不管三七二十一,任何请求进来都统统最后给commit一把的做法。因为很早以前我就做过性能测试,对于每个请求都commit的做法,虽然对请求处理的速度影响很小(大约5%的性能损失),但是对数据库会造成非常大的压力,会让数据库的CPU占用率直线上升。

0 请登录后投票
   发表时间:2008-11-06  
robbin 写道
我非常反对gigix这种不管三七二十一,任何请求进来都统统最后给commit一把的做法。因为很早以前我就做过性能测试,对于每个请求都commit的做法,虽然对请求处理的速度影响很小(大约5%的性能损失),但是对数据库会造成非常大的压力,会让数据库的CPU占用率直线上升。

gigix之前贴的代码里面是有判定非get request才进行transaction的open/commit,所以对数据库不会有影响的。
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics