开发者

Rails How can one query association definitions

开发者 https://www.devze.com 2023-04-01 16:39 出处:网络
I have a lot of dynamic code which keeps complex relations in a string. ex: \"product.country.continent.planet.galaxy.name\"

I have a lot of dynamic code which keeps complex relations in a string. ex:

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

How can I check if these relations exist? I want a method like the following:

  raise "n0开发者_JAVA技巧0b" unless Product.has_associations?("product.country.planet.galaxy")

How could I implement this?


Try this:

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


If these are active record associations, here's how you can do it:

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

And this will tell you if this specific path has all the associations.


If indeed you are storing the AR associations in a string like that, this code placed in an initializer should let you do what you want. For the life of me I can't quite figure out why you'd want to do this, but I trust you have your reasons.

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

With this you'll need to leave off the initial model name, so for your example it would be:

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

精彩评论

暂无评论...
验证码 换一张
取 消