该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间: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也可以解决部分简单的需求。 |
|
返回顶楼 | |
发表时间: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很酷。谢谢。 |
|
返回顶楼 | |
发表时间: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吧:)。 |
|
返回顶楼 | |
发表时间:2007-10-28
楼主的行文让人叹为观止,看得有点累。
我想了解,这种新途径是否支持ptions 和字符串形式的属性,例如 'CHAR(40)' 谢谢 |
|
返回顶楼 | |
发表时间:2007-11-08
"希瑞~ 请赐予我力量吧! ",很熟但记不清哪部电视剧还是动画片里的了。
|
|
返回顶楼 | |