我有很多动态代码,可以在字符串中保持复杂的关系。 例如:
"product.country.continent.planet.galaxy.name"
如何检查这些关系是否存在? 我想要一个像下面这样的方法:
raise "n00b" unless Product.has_associations?("product.country.planet.galaxy")
我怎么能实现这个?
答案 0 :(得分: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
答案 1 :(得分: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
这将告诉您此特定路径是否具有所有关联。
答案 2 :(得分: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")