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

migrations不止可以更性感,还可以更感性,甚至更个性

浏览 17100 次
该帖已经被评为精华帖
作者 正文
   发表时间:2007-09-29  
cvu 写道
rainchen 写道
把fields写在model里,更容易扩展出多语系应用,比如 field name在错误信息中的显示,就不用再另外配置一份field name 的映射配置。
唔~这不又是一次DRY?


我还看到这样做的一个好处,更有利于Aspect Programming。

比如,Model假删除:现在Rails里的Model.destroy就是从数据库里彻底删除,我想把系统里的几个模型做成假的删除。就是把is_active字段设为false,find也找不到它。

    要做到find找不到假删除的记录,只要hack一下ActiveRecord::Base就行了,但是is_active字段还是要一个个数据表里去加的。

    如果把数据库字段也定义在Model里,就可以在一个插件里一揽子解决这个问题。

    做一个插件,先添加一个is_active字段,default设为true,然后hack一下find,还要hack一下destroy方法。起个名字,比如acts_as_fake_delete。然后在需要的Model里call一下就都搞定了。

DRY的好处之外,是代码有意义。

    实际项目的数据表中有不少功能性字段,比如Rails考虑到的created_at, updated_at,is_locked,再比如Rails没考虑的is_active,created_by, updated_by等等,都可以用插件抽象出来。

期待这个变化。



这个与migrations关系不大吧,倒是有个插件可以做到你需要的“数据隐形”:
http://railsify.com/plugins/63-acts-as-filterable
其实也只需定义个find_active也可以解决部分简单的需求。
0 请登录后投票
   发表时间:2007-09-29  
rainchen 写道

这个与migrations关系不大吧,倒是有个插件可以做到你需要的“数据隐形”:
http://railsify.com/plugins/63-acts-as-filterable
其实也只需定义个find_active也可以解决部分简单的需求。


你似乎没懂我的意思,is_active不仅仅是Model的一个attribute,还是数据库里的一个字段。

你建议的那个插件可以解决object里的需要,但是没有更新数据库。就是说,如果数据reload了,这些设置就都丢了。

当你需要为一些模型设置同样的机制,而且都要保存到数据库的话,就可以用这个sexy migration把所需的field加入类似acts-as-filterable这样的插件。做完设置后,再在插件里保存到数据库。model里使用的方式与这个acts-as-filterable例子还是一样的。

这样的例子在企业级应用里很常见,大量的数据表要有created_by(user_id),is_active,created_at这样的字段。

再举一个例子,每次用到created_by的话,都要先写migration,再在model里定义belongs_to :created_by_user, :class_name => 'User', :foreign_key => :created_by;还要before_save的时候设置self.created_by = current_user.id;以及controller/view上CRUD的一整套东西。现在因为必须用migration定义field,这个“repeat yourself”的逻辑就不能彻底抽出来,做到增减随意。

而你介绍的sexy migration是对症的。

BTW,这个acts-as-filterable很酷。谢谢。
0 请登录后投票
   发表时间:2007-09-29  
cvu 写道
rainchen 写道

这个与migrations关系不大吧,倒是有个插件可以做到你需要的“数据隐形”:
http://railsify.com/plugins/63-acts-as-filterable
其实也只需定义个find_active也可以解决部分简单的需求。


你似乎没懂我的意思,is_active不仅仅是Model的一个attribute,还是数据库里的一个字段。

你建议的那个插件可以解决object里的需要,但是没有更新数据库。就是说,如果数据reload了,这些设置就都丢了。

当你需要为一些模型设置同样的机制,而且都要保存到数据库的话,就可以用这个sexy migration把所需的field加入类似acts-as-filterable这样的插件。做完设置后,再在插件里保存到数据库。model里使用的方式与这个acts-as-filterable例子还是一样的。

这样的例子在企业级应用里很常见,大量的数据表要有created_by(user_id),is_active,created_at这样的字段。

再举一个例子,每次用到created_by的话,都要先写migration,再在model里定义belongs_to :created_by_user, :class_name => 'User', :foreign_key => :created_by;还要before_save的时候设置self.created_by = current_user.id;以及controller/view上CRUD的一整套东西。现在因为必须用migration定义field,这个“repeat yourself”的逻辑就不能彻底抽出来,做到增减随意。

而你介绍的sexy migration是对症的。

BTW,这个acts-as-filterable很酷。谢谢。


is_active当然是要一个字段才能保存数据的持久状态啊,倒可能是你没看到他的例子吧,你只需改动他的例子:
class Post < ActiveRecord::Base
   acts_as_filterable
  
   def is_deleted?
     self.is_active == 0
   end
  
   invisible_if :is_deleted?
end

至于is_active的值的更新当然是得由你自己来维持,你可以定义个delete 方法来设置该值,然后你在像往常的一样用find时就会自动忽略掉已被隐藏的条目。
这个插件也正好是别人用来做虚拟删除时介绍给我的。

至于你说的关联设置,似乎只是跟generator的“方便”程度有关,如像Chris那样定义一个timestamps!,就会生成两个字段定义:
     t.column :created_at, :datetime 
     t.column :updated_at, :datetime
你可以给generator也增加一个方法,如create_by! :model_name。然后在背后帮你生成相关的字段定义。
至于:class_name => 'User', :foreign_key => :created_by 这些参数一般都只有要用到非默认值才需改动,如has_many等的中的多态虚拟关联,恰好是方便的地方,你不能指望生成器还能智能到能预感到你设置的Friend Model其实是个虚拟自User Model吧:)。
0 请登录后投票
   发表时间:2007-10-28  
楼主的行文让人叹为观止,看得有点累。

我想了解,这种新途径是否支持ptions 和字符串形式的属性,例如 'CHAR(40)'

谢谢
0 请登录后投票
   发表时间:2007-11-08  
"希瑞~ 请赐予我力量吧! ",很熟但记不清哪部电视剧还是动画片里的了。
0 请登录后投票
论坛首页 编程语言技术版

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