I have a schema of 2 classes:
class Anomaly(DjangoObjectType):
class Meta:
model = models.Anomaly
class Batch(LoggedModel):
class Meta:
model = models.Batch
where LoggedModel is
class LoggedModel(DjangoObjectType):
class Meta:
model = models.LoggedModel
originally both inherited from DjangoObjectType but then neither of the two was exposing a field logs defined in the superclass of the model
class LoggedModel(models.Model):
recursive_field = "parent_model"
logs = models.ManyToManyField(Log, related_name="%(app_label)s_%(class)s")
class Meta:
abstract = True
class Anomaly(LoggedModel):
...
class Batch(LoggedModel):
anomalies = models.ManyToManyField(Anomaly)
Now, after declaring in the schema Batch a subclass of LoggedModel instead of DjangoObjectType, logs is exposed for both classes. Anyone can shed some light?
Any related fields that you wish to have in your models need to be explicitly declared, as you've done in your second example. In the first example, logs isn't automagically exposed even though it exists, I assume, in the model definition.
In the second, it is exposed in LoggedModel, thus also for Anomaly and Batch.
You should find that they both work simply as DjangoObjectTypes if you explicitly expose logs in them.
Take a look here: https://stackoverflow.com/a/56173485/214150
Related
I have a class User that inherits from ApplicationRecord. When I check User.ancestors.include?(Class), the result is false but for User.class, the result is Class.
What's the use case for the information supplied by the class method in such cases? What does it really tell me to be of practical use? It doesn't seem to have anything to do with inheritance.
What's the use case for the information supplied by the class method in such cases? What does it really tell me to be of practical use? It doesn't seem to have anything to do with inheritance.
class works the same way for every object. Calling class on a class provides the same information as calling class on an instance. That's because in Ruby, classes are instances, too.
'foo'.class returns String because 'foo' is an instance of String. Likewise, User.class returns Class because User is an instance of Class.
In particular, User is not an instance of ApplicationRecord.
It might not be obvious that User is an instance of Class when creating it via the class keyword:
class User < ApplicationRecord; end
But it becomes very obvious when you create it explicitly via Class.new: (both examples produce the same result)
User = Class.new(ApplicationRecord)
User.class #=> Class
Because the above is just like: (using String.new for demonstration purposes)
foo = String.new('foo')
foo.class #=> String
User is a class. All classes are instances of the class Class (i.e., User.class #=> Class). Therefore, all instance methods defined on Class, or on Class's ancestors, can be invoked on User (i.e., every instance method of Class is a class method of User).
For example, one of Class's instance methods is instance_methods. One can therefore execute User.instance_methods to obtain an array of User's instance methods.
After reading another StackOverflow post, I realized that it can only be understood by keeping the following in mind:
User class has a double role. It plays Class as well as Object.
As Class, it lets other classes inherit from it.
As Object, it inherits the class method all the way up from the Object class.
If I wanted my User.class to behave on the traditional lines (that is, User.class shows ApplicationRecord), then I have to override
it as follows:
class User
def self.class
self.superclass
end
end
Classes in Ruby are first-class objects—each is an instance of class
Class
User is an object of class Class (which inherits from Object).
class is an instance method of Object. It returns the class of the object. Therefore, User.class returns Class. Every object will have this method, and it is useful to know what the object is (e.g., for debugging). Consider this code:
1.class
# => Fixnum
"q".class
# => String
The reason why User.ancestors does not return Class is because it returns the modules included in the module. For example, Class.ancestors will include Class, but not User because User is an object of Class, which includes its own modules.
I need to do some custom data binding and I tried to use the #BindUsing annotation on a class (http://grails.org/doc/latest/api/org/grails/databinding/BindUsing.html), however, it's being ignored. I am under the assumption that since the annotation is used on the class that would mean that every time a data binding happens and that class is involved, the BindingHelper class would be used, but it's never actually called. Is there something that I'm missing or doing wrong?
Here's the class definition where UserBinding is a class that implements the BindingHelper interface:
#BindUsing(UserBinding)
class User extends SomeOtherClass
{
...
Also am I correct in understanding that basically creating a ValueConverter and using #BindUsing on a class accomplish the same thing?
BindUsing on a class is not used often and there seems to be a bug reported around that already. [From the link] The problem could be that there are multiple request parameters with the same name it might be using the helper only for the first one.
Using a property level #BindUsing annotation should be simpler to implement and is less likely to fail (even when there are multiple entries in the params map with the same name).
I've three classes that implement the composite patter, Item, Cluster and Element.
class Item extends Locatable {
...
}
class Cluster extends Item {
static hasMany = [items:Item]
...
}
class Element extends Item {
...
}
My domain model is more complex than this, but it's just an example.
When I have an instance of Item and I want to know if it is a Cluster or a Element with ins.getClass().getSimpleName() I'm getting a weird class name: Item_$$_javassist_165, if I do a println ins.toString() I get the correct class name printed (the toString method returns this.getClass().getSimpleName()).
how to get the correct class name? What is this "Item_$$_javassist_165" class name?
What is this "Item_$$_javassist_165" class name?
It means that the object you have is a Hibernate lazy-loading proxy. The first time you try and access anything other than the id of that object, Hibernate will go to the database and load the real data, then delegate any future method calls to the real object.
The obvious approach of ins instanceof Cluster may not work correctly in the presence of proxies when you have one domain class that extends another, but GORM provides an injected instanceOf method that does what you need and will handle proxies correctly.
if(ins.instanceOf(Cluster)) { .... }
You can use GrailsHibernateUtil.unwrapIfProxy(object) to receive the original object instance from a proxy object. After unwrapping you should be able to get the real class name with getClass().getSimpleName(). Be aware that you loose features like lazy loading on the unwrapped object.
I find a method that give the real name:
org.hibernate.Hibernate.getClass(ins).getSimpleName()
I have a loop in my controller that does something like this:
for(d in grailsApplication.domainClasses) {
def c = d.getClazz().count()
// construct table containing object instance counts
}
My intent is to use this loop to count the instances of non-leaf domain classes in my database. Is there a way to query the domain class itself to find out if it is abstract or not? I wasn't sure if there were some member functions automatically added by the framework since I am still new to Groovy/Grails. I couldn't find anything that addressed it in the Grails documentation.
Figured it out after a few minutes of poking around the Groovy documentation. The function isAbstract() can be invoked on the domain class to determine whether or not the domain class is a leaf node in the class hierarchy
Here's my scenario, I have 2 classes "com.project.ClassA" and "com.project.ClassB", I'm trying to map the fields ClassA.name to ClassB.person.nameObj.firstName.
As you can see, Dozer needs to create person object and nameObj before it can do the mapping, there is some factory classes to initiate the Person and NameObj objects.
I know we can define custom create method in field and class level, but that only applies to the field or the class that you are mapping. In my example, the mapping are between 2 String fields, but 2 objects are required to be created before the mapping is performed.
The error I'm getting now is
org.dozer.MappingException: java.lang.NoSuchMethodException: com.project.ClassB.Person.()
Any helps or ideas will greatly appreciated. Thanks.
Two things
1. ClassB needs a constructor which initialized obj Person, similarly Person needs a constructor to initialize nameobj.
2. accessor and mutator methods should be present (getters and setters).
After you do both these steps this should work.