【问题标题】:Rails How can one query association definitionsRails 如何查询关联定义
【发布时间】:2011-09-01 15:18:40
【问题描述】:

我有很多动态代码将复杂的关系保存在字符串中。 例如:

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

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

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

我该如何实现呢?

【问题讨论】:

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

标签: ruby-on-rails ruby activerecord metaprogramming


【解决方案1】:

试试这个:

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

【讨论】:

  • 刚刚用 reflect_on_association(name.to_sym) 替换了 reflect_on_association(name) 并且像一个魅力一样工作!
【解决方案2】:

如果这些是活动记录关联,您可以这样做:

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

这将告诉您该特定路径是否具有所有关联。

【讨论】:

    【解决方案3】:

    如果您确实将 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")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-11
      相关资源
      最近更新 更多