```ruby
class Picture < ApplicationRecord
  belongs_to :imageable, polymorphic: true
end

class Employee < ApplicationRecord
  has_many :pictures, as: :imageable
end

class Product < ApplicationRecord
  has_many :pictures, as: :imageable
end
```

product|employee.pictures -> works almost as normal has_many as far as Hyperstack client is concerned
imageable is the "alias" of product|employee.   Its as if there is a class Imageable that is the superclass
of Product and Employee.

so has_many :pictures means the usual thing (i.e. there is a belongs_to relationship on Picture) its just that
the belongs_to will be belonging to :imageable instead of :employee or :product.

okay fine

the other way:

the problem is that picture.imageable while loading is pointing to a dummy class (sure call it Imageable)
so if we say picture.imageable.foo.bar.blat what we get is a dummy value that responds to all methods, and returns itself:

picture.imageable -> imageable123 .foo -> imageable123 .bar -> ... etc.  but it is a dummy value that will cause a fetch of the actual imageable record (or nil).

.imageable should be able to leverage off of server_method.

server_method(:imageable, PolymorphicDummy.new(:imageable))

hmmmm....

really its like doing a picture.imageable.itself (?) (that may work Juuuust fine)

so picture.imageable returns this funky dummy value but does an across the wire request for picture.imageable (which should get imageable_id per a normal relationship) and also get picture.imageable_type.


start again....

what happens if we ignore (on the client) the polymorphic: and as:  keys?

belongs_to :imageable

means there is a class Imageable, okay so we make one, and add has_many :pictures to it.


and again....

```ruby
def imageable
  if imageable_type.loaded? && imageable_id.loaded?
    const_get(imageable_type).find(imageable_id)
  else
    DummyImageable.new(self)
  end
end
```

very close but will not work for cases like this:

```ruby
  pic = Picture.new
  employee.pictures << pic
  pic.imageable # FAIL... (until its been saved)
  ...
```

but still it may be as simple as overriding `<<` so that it sets type on imageable.  But we still to have a proper belongs to relationship.

```ruby
def imageable
  if we already have the attribute set
    return the attribute
  else
    set attribute to DummyPolyClass.new(self, 'imageable')
    # DummyPolyClass init will set up a fetch of the actual imageable value
  end
end

def imageable=(x)
  # will it just work ?
end
```

its all about the collection inverse.  The inverse class of the has_many is the class containing the polymorphic belongs to.  But the inverse of a polymorphic belongs to depends on the value. If the value is nil or a DummyPolyClass object then there is no inverse.

I think if inverse takes this into account then `<<` and `=` should just "work" (well almost) and probably everything else will to.

### NOTES on the DummyPolyClass...

it needs to respond to reflect_on_all_associations, but just return an empty array.  This way when we search for matching inverse attribute we won't find it.

### Status

added model to inverse, inverse_of, find_inverse

if the relationship is a collection then we will always know the inverse.

The only time we might no know the inverse is if its NOT a collection (i.e. belongs_to)

So only places that are applying inverse to an association that is NOT a collection do we have to pass the model in.

All inverse_of method calls have been checked and updated

that leaves inverse which is only used in SETTERS hurray!


### Latest thinking

going from `has_many / has_one as: ...` is easy  its essentially setting the association foreign_key using the name supplied to the as:

The problem is going from the polymorphic belongs_to side.  

We don't know the actual type we are loading which presents two problems.

First we just don't know the type.  So if I say `Picture.find(1).imageable.foo.bar` I really can't do anything with foo and bar.  This is solved by having a DummyPolymorph class, which responds to all missing methods with itself, and on creation sets up a vector to pull it the id, and type of the record being fetched.  This will cause a second fetch to actually get `foo.bar` because we don't know what they are yet.  (Its cool beacuse this is like Type inference actually, and I think we could eventually use a type inference system to get rid of the second fetch!!!)

Second we don't know the inverse of the relationship (since we don't know the type)

We can solve this by  aliasing the inverse relationship (the one with the `as: SOMENAME` option)   to be `has_many #{__hyperstack_polymorphic_inverse_of_#{SOMENAME}` and then defining method(s) against the relationship name.  This way regardless of what the polymorphic relationship points to we know the inverse is `__hyperstack_polymorphic_inverse_of_#{SOMENAME}`.  

If the inverse relationship is a has_many then we define
```ruby
def #{RELATIONSHIP_NAME}
  __hyperstack_polymorphic_inverse_of_#{SOMENAME}
end
```

If the inverse relationship is a has_one we have to work a bit harder:
```ruby
def #{RELATIONSHIP_NAME}
  __hyperstack_polymorphic_inverse_of_#{SOMENAME}[0]
end
def #{RELATIONSHIP_NAME}=(x)
  __hyperstack_polymorphic_inverse_of_#{SOMENAME}[0] = x # or perhaps we have to replace the array using the internal method in collection for that purpose.
end
```

The remaining problem is that the server side will have no such relationships defined so we need to add the `has_many __hyperstack_polymorphic_inverse_of_#{SOMENAME} as: SOMENAME` server side.