We are finding that some Cardtypes need to have additional class level support. We already can load instance methods based on the set classes, and loading these methods into the singleton classes for each object, but we don't load any class methods or use AR class methods to define additional validation and the like.
What this means is that we have to load anything we need on some cards for all cards. Case in point are the attachment (paperclip) related setup that is needed only for File and Image cards. Similarly if we want something like Active Cards Models, we probably want to add a bunch of stuff at the class level that we really only want for that specific class.
The tricky part will be Card initialization (Card.new) when we don't yet have all the matching patterns and such that can influence what the type (and other patterns) are for this card until late in initialization.
I don't think loading class methods into the singleton would be difficult at all. Basically, when we do include_set_modules, we also do an extend of whatever submodule applies.
I've been assuming we would want to turn all the validations into events, perhaps making use of lower-than-AR code in ActiveModel or ActiveSupport, wherever it is.
The "tricky part" you mention (knowing when to switch to the subclass) was a huge hassle in the old system. Without a comprehensive plan there, I don't think we should proceed with that idea.
Ultimately, the reason this failed before was that it elevated the cardtype set over all other sets, making it difficult or impossible to customize cards based on anything other than cardtype. I think doing something like this with Account has the same flaw.
For example, suppose a card had both an account and a sol. When you go to initialize that card, what type do you want? Account? Sol?
Basically, we have our solution: we want a singleton card.
The only subclasses I was suggesting were NON-CORE subclasses that were really just adapters for other apis. In that sense, ActiveCard more of an analogue of ActiveResource than ActiveRecord. It wouldn't be for representing internal wagn logic, just for managing external communications with cards.
by the way, this is great to be hashing this out here. Thanks for doing this.
I'm not sure we actually do need/want this, but I think the point about loading into the class is wrong. Took me a while to get this, but as I understand, a class is already an instance of the class Class and so the class methods already are singleton methods. So, class Card is the only singleton class we have. I seem to recall that we ran into this when we were trying to do this with the set module loading. I thought that you figured out that whenever we tried to load special class methods for a set, they got added to Card, which is what I'd expect.
Yeah, I think this idea was a little wrong-headed. We can close it.
I've actually sometimes just done 'def self.whatever' in the module. Then you can do Card::Set::Foo::Bar.whatever when you need it.
I think this idea could come back with namespaces. I don't want to go back to the STI thing Wagn used to have, but it is less of a problem is a namespace loaded as: class ActiveCard < Card
As much as I thought the card extension thing was pretty ugly, I am seeing it as more desirable to be able to access other models from Wagn. I'm now thinking that the namespace concept would be a good way to do this sort of thing.
Maybe:
class MyModel < ActiveCard
validate :foo
after_save :bar
end
and to support this:
class ActiveCard < ActiveRecord::Base (or just includes ActiveModel, etc.)
include CardModel
...
end
I know, this isn't exactly right. Needs more baking, and maybe the discussion belongs with ActiveCardModel anyway.
+discussed in support tickets
+relevant user stories