检索的AR模型中的所有关联的属性? [英] Retrieve all association's attributes of an AR model?

查看:124
本文介绍了检索的AR模型中的所有关联的属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你怎么想这是更优化的方法来检索所有,一个AR模型?

How do you think is the more optimum way to retrieve all the attributes for each association that an AR model has?

例如:假设我们有模型目标

i.e: let's say we have the model Target.

class Target < ActiveRecord::Base
  has_many :countries
  has_many :cities
  has_many :towns
  has_many :colleges
  has_many :tags

  accepts_nested_attributes_for :countries, :cities, ...
end

我想通过调用一个目标实例的方法来检索关联的所有属性:

I'd like to retrieve all the association's attributes by calling a method on a Target instance:

target.associations_attributes
>> { :countries => { "1" => { :name => "United States", :code => "US", :id => 1 }, 
                     "2" => { :name => "Canada", :code => "CA", :id => 2 } },
     :cities => { "1" => { :name => "New York", :region_id => 1, :id => 1 } },
     :regions => { ... },
     :colleges => { ... }, ....
   }

目前我做这项工作是通过遍历每个关联,然后对联想的每一个模型,但它是一种昂贵的,你怎么认为我可以优化这个?

Currently I make this work by iterating on each association, and then on each model of the association, But it's kind of expensive, How do you think I can optimize this?

刚一说明:我意识到,你不能叫 target.countries_attributes 的has_many 协会与 nested_attributes one_to_one 协会允许调用 target.country_attributes

Just a note: I realized you can't call target.countries_attributes on has_many associations with nested_attributes, one_to_one associations allow to call target.country_attributes

推荐答案

我不清楚你用迭代上的所有关联的意思。您是否已经使用反射?

I'm not clear on what you mean with iterating on all associations. Are you already using reflections?

不过好奇,如果有一个更合适的方法,但是这是我能想出,这在哈希或多或少的结果你出现在您的例子:

Still curious if there's a neater way, but this is what I could come up with, which more or less results in the hash you're showing in your example:

class Target < ActiveRecord::Base
  has_many :tags

  def associations_attributes
    # Get a list of symbols of the association names in this class
    association_names = self.class.reflect_on_all_associations.collect { |r| r.name }
    # Fetch myself again, but include all associations
    me = self.class.find self.id, :include => association_names
    # Collect an array of pairs, which we can use to build the hash we want
    pairs = association_names.collect do |association_name|
      # Get the association object(s)
      object_or_array = me.send(association_name)
      # Build the single pair for this association
      if object_or_array.is_a? Array
        # If this is a has_many or the like, use the same array-of-pairs trick
        # to build a hash of "id => attributes"
        association_pairs = object_or_array.collect { |o| [o.id, o.attributes] }
        [association_name, Hash[*association_pairs.flatten(1)]]
      else
        # has_one, belongs_to, etc.
        [association_name, object_or_array.attributes]
      end
    end
    # Build the final hash
    Hash[*pairs.flatten(1)]
  end
end

下面是通过脚本/控制台的IRB会议来显示它是如何工作的。首先,一些环境:

And here's an irb session through script/console to show how it works. First, some environment:

>> t = Target.create! :name => 'foobar'
=> #<Target id: 1, name: "foobar">
>> t.tags.create! :name => 'blueish'
=> #<Tag id: 1, name: "blueish", target_id: 1>
>> t.tags.create! :name => 'friendly'
=> #<Tag id: 2, name: "friendly", target_id: 1>
>> t.tags
=> [#<Tag id: 1, name: "blueish", target_id: 1>, #<Tag id: 2, name: "friendly", target_id: 1>]

下面是来自新方法的输出:

And here's the output from the new method:

>> t.associations_attributes
=> {:tags=>{1=>{"id"=>1, "name"=>"blueish", "target_id"=>1}, 2=>{"id"=>2, "name"=>"friendly", "target_id"=>1}}}

这篇关于检索的AR模型中的所有关联的属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆