关于 rails ActiveRecord 属性 以及 foreign_key 不直接用数据库项目 时的一些讨论


引发这个问题的是 需要用类似于下面的功能
belongs_to :major,:foreign_key  =>  :major_id  
但是数据库中并不直接有major_id这一项,而是从其他项表出[比如从一个xml项中解析出来]
最先想到的很简单
def major_id

end

def major_id
= (m)

end
觉得这样实现就可以了,但是现实是残酷的
   调用x.major时返回nil ,设置x.major = Major.find(1)时变量也不被设置
于是查看了ActiveRecord的源代码,:foreign_key实际读写的是x.attributes[name]项
也就是说自己定义的读取方法并不属于x.attributes
在API里查看到以下内容
Overwriting  default  accessors

All column values are automatically available through basic accessors on the Active Record object, but sometimes you want to specialize 
this  behavior. This can be done by overwriting the  default  accessors (using the same name as the attribute) and calling read_attribute(attr_name) and write_attribute(attr_name, value) to actually change things. Example:

  
class  Song  <  ActiveRecord::Base
    # Uses an integer of seconds to hold the length of the song

    def length
= (minutes)
      write_attribute(:length, minutes 
*   60 )
    end

    def length
      read_attribute(:length) 
/   60
    end
  end

You can alternatively use self[:attribute]
= (value) and self[:attribute] instead of write_attribute(:attribute, value) and read_attribute(:attribute) as a shorter form.
尝试后发现:
如果设置x.major_id=...,可以使用x.major,一切正常
如果设置x.major,x.major_id也正常
但是
=  X.find( 1 )
x.major会出错
也就是说如果不调用读写方法,x.attributes[major_id] == nil,而foreign_key直接调用x.attributes[major_id]
只有调用钩子
def after_initialize
  self[:major_id] 
=  
end
这样就可以正常读取,写入

但对于写入方法,建议是在before_save钩子中完成,而不是使用覆盖属性读写的方法

转载于:https://www.cnblogs.com/Tachikoma/archive/2008/03/29/1128525.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值