代码之家  ›  专栏  ›  技术社区  ›  Walt Jones

如何迭代ActiveRecord属性,包括attr_访问器方法

  •  6
  • Walt Jones  · 技术社区  · 17 年前

    我到处寻找一个优雅的解决方案。基本的问题似乎是映射到数据库列的ActiveRecord属性在ActiveRecord::Base中的处理方式与attr_访问器方法完全不同。

    我想做如下的事情:

    model.attribute_names.each do |name|
      # do stuff
    end
    

    以一种方式,也包括attr_访问器字段,但不包括任何其他实例方法。我知道这不是内置的,但最优雅的方式是什么?

    3 回复  |  直到 9 年前
        1
  •  9
  •   Orion Edwards    17 年前

    你不能真正解决这个问题。你可以估计出一个黑客,但这不是一个能很好地工作的东西。

    model.attribute_names 应该给你所有的活动记录,但是 attr_accessor 字段不是字段。它们只是普通的Ruby方法,获得它们的唯一方法是 model.instance_methods .

    想法1

    你可以做到 model.attribute_names + model.instance_methods 但是你必须过滤掉所有其他普通的Ruby方法 initialize, save 等等,这是不切实际的。

    帮助筛选 instance_methods 你可以把它们和 model.instance_variables (你必须说明 @ 手动登录实例变量),但问题是实例变量在第一次分配之前根本不存在。

    想法2

    在你 environment.rb 之前 还有别的吗 加载,定义自己的 self.attr_accessor 在里面 ActiveRecord::Base . 这样就可以包装底层 访问器 同时将属性名保存到私有列表中。那你以后就可以从这个名单中退出了。但是我建议你不要这样…猴子修补核心语言设施,如 访问器 一定会给你带来很多痛苦。

    想法3

    定义你自己 custom_attr_accessor 在里面 活动记录::基础 它与IDEA 2执行相同的操作,并在您希望能够检索属性名的代码中使用它。这是安全的,因为你不会击倒内置的 访问器 方法,但必须更改所有代码才能使用 自定义访问器 必要时

    总而言之,你想做什么,需要知道 访问器 领域?如果可以的话,试着从另一个角度来看待你的问题。

        2
  •  3
  •   Mab879    13 年前

    我来这里是想做同样的事情,由于猎户座的回答,我发现这完全是错误的做法。

    如果其他人的用例与我的类似,这里是我的解决方案。我在用 attr_accessor 在从ActiveRecord查询模型后向模型添加额外的属性。然后我想将结果输出为JSON等。

    更好的解决方案是首先将模型从ActiveRecord转换为常规哈希,然后添加 访问器 属性作为常规哈希键。

    例子:

    model_hash = model_from_activerecord.attributes.to_options
    model_hash[:key] = value
    
        3
  •  0
  •   MTarantini    9 年前

    我自己想出的解决方案建立在奥里安·爱德华兹的回答之上。

    代码:

    klass_attributes = klass.column_names + klass.instance_methods(false). map(&:to_s).keep_if{|a| a.include?('=')}.map{|a| a.sub('=', '')}

    故障:

    klass.instance_methods(false) 只返回实例方法,而不返回继承的方法。

    map(&:to_s) 将符号数组转换为字符串数组,以便使用 include? 方法。还需要与列名称返回的字符串数组合并。

    keep_if{|a| a.include?('=')} 将删除数组中没有等号的所有字符串。这很重要,因为我注意到attr访问器属性都有“=”。例如:“app-url”与“login”url='

    map{|a| a.sub('=', '')} 是最后一个从数组中的每个字符串中删除“=”的项。

    最后得到一个表示属性的字符串数组,包括attr_访问器属性。

    推荐文章