检索的AR模型中的所有关联的属性? [英] Retrieve all association's attributes of an AR model?
问题描述
你怎么想这是更优化的方法来检索所有,一个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屋!