module StaticModels::BelongsTo

When included, it adds a class method that works similar to rails 'belongs_to', but instead of fetching an association it gets a static model.

Public Instance Methods

belongs_to(association, opts = {}) click to toggle source
Calls superclass method
# File lib/static_models.rb, line 133
def belongs_to(association, opts = {})
  super(association, opts) if defined?(super)

  expected_class = unless opts[:polymorphic]
    module_name = self.to_s.split("::")[0..-2].join("::")
    [ opts[:class_name],
      "#{module_name}::#{association.to_s.camelize}",
      association.to_s.camelize,
    ].compact.collect(&:safe_constantize).compact.first
  end

  define_method("#{association}") do
    klass = expected_class || send("#{association}_type").to_s.safe_constantize

    if klass && klass.include?(Model)
      klass.find(send("#{association}_id"))
    elsif defined?(super)
      super()
    end
  end

  define_method("#{association}=") do |value|
    if expected_class && !value.nil? && value.class != expected_class
      raise ValueError.new("Expected #{expected_class} got #{value.class}")
    end

    if value.nil? || value.class.include?(Model)
      if opts[:polymorphic]
        # This next line resets the old polymorphic association
        # if it was set to an ActiveRecord::Model. Otherwise
        # ActiveRecord will get confused and ask for our StaticModel's
        # table and a bunch of other things that don't apply.
        super(nil) if defined?(super)
        send("#{association}_type=", value && value.class.name )
      end
      send("#{association}_id=", value && value.id)
    else
      super(value)
    end
  end

  #Adding accesor for code_representation
  define_method("#{association}_code=") do |value|
    if thing = expected_class.find_by_code(value)
      instance_variable_set("@invalid_#{association}_code", nil)
      send("#{association}=", thing)
    else
      instance_variable_set("@invalid_#{association}_code",
        value.try(:to_sym))
    end
  end 

  define_method("#{association}_code") do
    send(association).try(:code) ||
      instance_variable_get("@invalid_#{association}_code")
  end
end