In base class:
#method enum getWeightType() Returns the current record's
"weight_type" value
Subclass:
class Exercise extends BaseExercise
{
public function getWeightType()
{
$type = parent::getWeightType();
if ($type == 'free') {
return 'Wolny';
} else {
return 'Stacjonarny';
}
}
}
so basically I want to ouput values other than stores in database.
In indexSuccess:
echo $exercise->getWeightType()
I am getting error:
Fatal error: Maximum function nesting level of '100' reached, aborting
Could somebody give me any advice?
You need to use the protected method when overriding:
$type = $this->_get('weight_type');
Otherwise youre jsut going to run yourself in circles because its going to keep trying to call accessor method youre overriding never getting to a method that actually gets the internal value.
Related
In a SYMFONY FORM (ORM is not use (PDO is used for DB query instead)).
I have a class MyEntityType in which the buildForm function has:
$builder->add('my_attribute',ChoiceType::class,array(
'choices'=>$listForMyAttribute,
'multiple'=>'true',
'attr'=>array('data-native-menu'=>'false'),
'label'=>'Multiple Select on my attribute'
));
My attribute is an array of an entity named MyEntity which has:
/**
* #Assert\NotBlank()
*/
private $myAttribute;
With a getter and a setter for that variable $myAttribute.
When I submit the form in the Controller, it doesn't pass the validation check and logs this error:
Unable to reverse value for property path "myAttribute" : Could not find all matching choices for the given values.
When I start to look for solution around this error message, it leads to something named "How to Use Data Transformers" in SYMFONY Cookbook; And it seems a solution would involve to create new Class and write a lot of code for something that one should be able to by-pass in a much straight forward way.
Does anyone have an idea?
My problem was that my array $listForMyAttribute was defined in the buildForm() function and its definition was relying on some conditional.
The conditional to make the array were met when this one was displayed for the first time.
After pushing the submit button, the buildForm was regenerated in the Controller, this second time, the condition were not met to make the array $listForMyAttribute as it was on the first display. Hence the program was throwing a "contraint not met error" because the value submited for that field could not be find.
Today I face exactly the same problem. Solution is simple as 1-2-3.
1) Create utility dummy class DoNotTransformChoices
<?php
namespace AppBundle\DataTransformer;
use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface;
class DoNotTransformChoices implements ChoiceListInterface
{
public function getChoices() { return []; }
public function getValues() { return []; }
public function getPreferredViews() { return []; }
public function getRemainingViews() { return []; }
public function getChoicesForValues(array $values) { return $values; }
public function getValuesForChoices(array $choices) { return $choices; }
public function getIndicesForChoices(array $choices) { return $choices; }
public function getIndicesForValues(array $values) { return $values; }
}
2) Add to your field the following additional option:
...
'choice_list' => new DoNotTransformChoices,
...
3) Congratulations!
I'm reasonably proficient with Groovy insofar as my job requires, but not having a background in OOP means that some things still elude me, so apologies if some of the wording is a little off here (feel free to edit if you can make the question clearer).
I'm trying to create an overloaded method where the signature (ideally) differs only in the return type of the single Closure parameter. The Closure contains a method call that returns either an ItemResponse or ListResponse object, both of which could contain an object/objects of any type (which is the type I would like to infer).
The following code is a simplified version of what I'm trying to implement - an error handling method which takes a reference to a service call, safely attempts to resolve it, and returns the item/items from the response as appropriate:
public <T> T testMethod(Closure<ItemResponse<T>> testCall) {
testCall.call().item as T
}
public <T> List<T> testMethod(Closure<ListResponse<T>> testCall) {
testCall.call().items as T
}
Obviously this doesn't work, but is there any alternate approach/workaround that would achieve the desired outcome?
I'm trying to create an overloaded method where the signature
(ideally) differs only in the return type of the single Closure
parameter.
You cannot do that because the return type is not part of the method signature. For example, the following is not valid:
class Demo {
int doit() {}
String doit() {}
}
As mentioned by yourself and #jeffscottbrown, you can't have two methods with the same parameters but different return value. The workaround I can see here is to use a call-back closure. The return value of your testMethod would default to Object and you would provide an "unwrapper" that would the bit after the closure call (extract item or items). Try this out in your GroovyConsole:
class ValueHolder <T> {
T value
}
Closure<List<Integer>> c = {
[1]
}
Closure<ValueHolder<String>> d = {
new ValueHolder(value:'hello world')
}
Closure liu = {List l ->
l.first()
}
Closure vhsu = {ValueHolder vh ->
vh.value
}
// this is the generic method
public <T> Object testMethod(Closure<T> testCall, Closure<T> unwrapper) {
unwrapper(testCall.call()) as T
}
println testMethod(c, liu)
println testMethod(d, vhsu)
It works with both a list or a value holder.
-(instancetype)filter:(BOOL (^)(id value))block {
NSCParameterAssert(block != nil);
Class class = self.class;
return [[self flattenMap:^ id (id value) {
if (block(value)) {
return [class return:value];
} else {
return class.empty;
}
}] setNameWithFormat:#"[%#] -filter:", self.name];
}
This is the implementation of filter of ReactiveCocoa.I don't know what this code means.Also I can't get any reference to the second return method.
return [class return:value];
Also, what does this instancetype mean? Suppose the value is a string and I check whether its length is greater than 2. What will be returned by using filter method?
The filter method invokes the class method of the current class to get a RACStream subclass using that method. Using return: will give a signal that sends the value passed and then completes. Using empty gives a signal that immediately sends completed without sending a next value, which removes the value filtered value from the stream thanks to flattenMap: switching out the signal with the one being created.
i use afterUpdate method reflected by GORM API in grails project.
class Transaction{
Person receiver;
Person sender;
}
i want to know which field modified to make afterUpdate behaves accordingly :
class Transaction{
//...............
def afterUpdate(){
if(/*Receiver is changed*/){
new TransactionHistory(proKey:'receiver',propName:this.receiver).save();
}
else
{
new TransactionHistory(proKey:'sender',propName:this.sender).save();
}
}
}
I can use beforeUpdate: and catch up the object before updating in global variable (previous as Transaction), then in afterUpdate, compare previous with the current object.
Could be?
Typically this would be done by using the isDirty method on your domain instance. For example:
// returns true if the instance value of firstName
// does not match the persisted value int he database.
person.isDirty('firstName')
However, in your case if you are using afterUpdate() the value has already been persisted to the database and isDirty won't ever return true.
You will have to implement your own checks using beforeUpdate. This could be setting a transient value that you later read. For example:
class Person {
String firstName
boolean firstNameChanged = false
static transients = ['firstNameChanged']
..
def beforeUpdate() {
firstNameChanged = this.isDirty('firstName')
}
..
def afterUpdate() {
if (firstNameChanged)
...
}
...
}
I have a need to have a method to return Id in case of success and list of errors in case of fail.
ex code snippet:
def save = {
def errors = []
if(Employee.save(flush:true)){
return Employee.id
}else{
errors.add("Can't be saved")
return errors.
}
}
In Service class
ICalling
Employee.save() - .. so how to check if it is error or id that save method returns
Any suggestions around would be appreciated.
I agree with Burk not to return different types, it can lead to unexpected errors.
Another solution to the problem is using Java's exception handling mechanism. You can add a context field to the Exception which will hold the list of validation errors.After catching the exception you can extract the errors.
void save(Employee employee) {
// do save
// ...
// on error:
def errors = [ "terrible error nr. 5" ]
throw new ValidationException(errors)
}
try {
fooService.save(employee)
} catch(ValidationException e) {
def errors = e.erorrs
// do stuff with the errors
}
An additional advantage: When no validation error is expected, the try-catch block can be ommited in Groovy, which makes the code cleaner because you don't have to care about any validation error fields.
Don't do this - even if you can make it somewhat more usable with Groovy, it's a bad idea. In this case though, there are a few simple solutions. If you're just passing the Employee instance and saving it in the service method, you don't need to return anything:
void save(Employee employee) {
employee.save(flush:true)
}
This is because if it's successful, the id will be set on the instance you passed in, and if not there will be one or more validation errors in the errors property (there's no need for you to return a generic error message when there are actually useful error messages available).
For example this would be the code you'd have in a controller calling the service:
def employee = new Employee(...)
fooService.save(employee)
if (employee.hasErrors()) {
// do something with employee.errors
}
else {
// success - use the id if you need via employee.id
}
If you want to pass in the data to create and save the new instance and return an Employee (this is the approach I usually take), it's similar:
Employee save(String name, int foo, boolean bar, ...) {
Employee employee = new Employee(name: name, foo: foo, bar: bar, ...)
employee.save(flush:true)
return employee
}
In this second case it's important to separate the save call and the return, since if there is a validation error save returns null and you want to always return a non-null instance. So do not do this:
return employee.save(flush:true)
If you separate them you can check the errors and/or the id.
Also, make sure that you do not use closures in services like you have in your code (def save = { ...). Only methods will be transactional since the Spring transaction handling doesn't know about Groovy closures - they're just fields that Groovy calls as if they were methods, but they're not.