2011-09-01 48 views
2

我有很多动态的代码保持复杂的关系在一个字符串中。 例如:Rails如何查询关联定义

"product.country.continent.planet.galaxy.name" 

我如何检查是否存在这些关系? 我想要一个类似如下的方法:

raise "n00b" unless Product.has_associations?("product.country.planet.galaxy") 

我该如何实现这个?

+0

我想我们需要更多的代码在这里,你在字符串中存储了什么样的关联?活跃的记录协会? – Jimmy

回答

2

试试这个:

def has_associations?(assoc_str) 
    klass = self.class 
    assoc_str.split(".").all? do |name| 
    (klass = klass.reflect_on_association(name.to_sym).try(:klass)).present? 
    end 
end 
+0

刚刚通过reflect_on_association(name.to_sym)替换reflect_on_association(name)并像魅力一样工作! –

0

如果这些活动记录协会,这里是你如何能做到这一点:

current_class = Product 
has_associations = true 
paths = "country.planet.galaxy".split('.') 

paths.each |item| 
    association = current_class.reflect_on_association(item) 
    if association 
    current_class = association.klass 
    else 
    has_associations = false 
    end 
end 

puts has_association 

,这将告诉你,如果这个特定的路径具有的所有关联。

0

如果确实要将AR关联存储为类似的字符串,则放置在初始化程序中的此代码应该允许您执行所需的操作。对于我的生活,我无法弄清楚为什么你想这样做,但我相信你有你的理由。

class ActiveRecord::Base 
    def self.has_associations?(relation_string="") 
    klass = self 
    relation_string.split('.').each { |j| 
     # check to see if this is an association for this model 
     # and if so, save it so that we can get the class_name of 
     # the associated model to repeat this step 
     if assoc = klass.reflect_on_association(j.to_sym) 
     klass = Kernel.const_get(assoc.class_name) 
     # alternatively, check if this is a method on the model (e.g.: "name") 
     elsif klass.instance_method_already_implemented?(j) 
     true 
     else 
     raise "Association/Method #{klass.to_s}##{j} does not exist" 
     end 
    } 
    return true 
    end 
end 

有了这个,你就需要离开过最初的型号名称,所以你的例子那就是:

Product.has_associations?("country.planet.galaxy")