Controller sends null value in a set command in Symfony2 - symfony-2.7

I have a controller that inserts new records, but sends NULL value to idUsuario which is the ID of the user who is creating the new record.
I have already checked the entity file, the estructure of the table, even setting a manual value like 1. I have tried the sql command directly in mysql command window and the problem in that idUsuario is comming NULL.
Controller:
function createAction ....
$user = $this->getUser();
$idUser = $user->getId();
$entity = new InProveedor();
$entity->setIdUsuario($idUser);
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
Entity:
/**
* #ORM\ManyToOne(targetEntity="Nival\AccesoBundle\Entity\AdUsuario",
inversedBy="proveedorUsuario")
* #ORM\JoinColumn(name="id_usuario", referencedColumnName="id_usuario")
*/
protected $proveedorUsuario;
/**
* #var integer
*
* #ORM\Column(name="id_usuario", type="integer", nullable=false)
*/
private $idUsuario;
/**
* Set idUsuario
*
* #param integer $idUsuario
* #return InProveedor
*/
public function setIdUsuario($idUsuario)
{
$this->idUsuario = $idUsuario;
return $this;
}
/**
* Get idUsuario
*
* #return integer
*/
public function getIdUsuario()
{
return $this->idUsuario;
}
An exception occurred while executing 'INSERT INTO in_proveedor (razon_social, nombre_comercial, direccion, telefono, email, nrc, nit, contacto, fecha_ingreso, id_forma_pago, dias_entrega, id_aut1_asig, id_notificado, fecha_notificado, id_aut1, fecha_aut1, id_categoria, id_usuario, fecha_creado, activo, id_empresaa) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)' with params ["GM Consulting SA de CV", "GM Consulting SA de CV", "9 Calle poniente 81 Ave norte col Escal\u00f3n 7-29, San Salvador", "22875000", "gmccapacitaciones2019#gmail.com", "22222", "222", "Astrid Cuadra", "2019-05-28", 1, null, 1, null, null, null, null, 1, null, "2019-05-28 20:50:41", 0, "2"]:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'id_usuario' cannot be null
So, it seems that even if I set a value for field idUsuario, it always return as NULL. Please help me out.

Well, what I did it was so weird, I had to remove the relationship beteewen tables, and save a record with the ID, then I put back the relationship in the entity files (both: AdUsuario and InProveedor) and it worked properly.

Related

Laravel: Get root class in nested relationship query

How can I get the root class in a nested eager relationship? Basically, I want to get something like this:
$entities = Entity::with(['attribute.valueable' => function ($query) {
$root = $query->getRootParent();
$query->where('entity_id', $root->id);
}])->get();
SQL-queries should be like
select * from `entities`;
select * from `entity_types_attributes` where `entity_types_attributes`.`entity_type_id` in (?);
select * from `entity_attribute_value_int` where `entity_attribute_value_int`.`attribute_id` in (?, ?, ?)
AND `entity_attribute_value_int`.entity_id` = ? // this part should be appended

Laravel 4.2 Custom Relationship Adding Eager Constraint for Complex Multi DB Query

We are working with a system that links teachers with classes, departments, schools and periodic surveys, responses & answers.
We use limesurvey for the survey component. However the teacher interface is contained within a laravel codebase.
In this example there is a relationship between courses and their surveys. This should be able to return a collection of any survey that is related to that survey.
Here is what I've done in the CourseModel:
public function surveys()
{
$related = new Survey();
$parent = $this;
return new CourseSurveysRelation($related->newQuery(), $this);
}
The relationship class:
use Pivotal\Cycle\Models\Cycle;
use Pivotal\Models\CourseInterface;
use Pivotal\Survey\Models\Survey;
use Pivotal\Course\Models\Course;
use Illuminate\Auth\UserInterface;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Relations\Relation;
class CourseSurveysRelation extends Relation
{
/**
* Create a new relation instance.
*
* #param \Illuminate\Database\Eloquent\Builder $query
* #param \Illuminate\Database\Eloquent\Model $parent
* #return void
*/
public function __construct(Builder $query, CourseInterface $parent)
{
$survey_ids = $parent::getModel()
->newQuery()
->select('cycles_classes.limesurvey_id')
->join('cycles_classes', 'classes.id', '=', 'cycles_classes.class_id')
->where('cycles_classes.class_id','=',$parent->id)
->lists('limesurvey_id');
$this->query = $query
->whereIn('sid', $survey_ids)
->groupBy('sid');
$this->parent = $parent;
$this->related = $query->getModel();
$this->addConstraints();
}
public function addEagerConstraints(array $models)
{
$survey_ids = [];
$course_ids = $this->getKeys($models, 'id');
$survey_ids = \DB::table('cycles_classes')
->select('cycles_classes.limesurvey_id')
->whereIn('cycles_classes.class_id',$course_ids)
->lists('limesurvey_id');
$this->query->whereIn('sid', $survey_ids);
}
public function initRelation(array $models, $relation)
{
}
public function addConstraints()
{
}
public function match(array $models, Collection $results, $relation)
{
}
public function getResults()
{
$results = $this->query->get();
return $results;
}
}
To explain the above a bit, the cycles_classes table holds the cycle, class and survey id.
Here is the Survey Model:
use \Config;
use Illuminate\Database\Eloquent\Model;
use Pivotal\Course\Models\Course;
use Pivotal\Cycle\Models\Cycle;
use Pivotal\Survey\Models\Collections\SurveyCollection;
use Pivotal\Survey\Models\Relations\SurveyCourseRelation;
use Pivotal\Survey\Models\Relations\SurveyCycleRelation;
use Pivotal\Survey\Models\Relations\SurveyResponseRelation;
use Pivotal\Survey\Models\SurveyInterface;
class Survey extends Model implements SurveyInterface
{
protected $connection = 'limemysql';
protected $table = 'surveys';
protected $primaryKey = 'sid';
public function __construct($attributes = array())
{
$this->table = Config::get('limesurvey.db_prefix').$this->table;
parent::__construct($attributes);
}
public function questions()
{
return $this->HasMany('Pivotal\Survey\Models\Question','sid','sid');
}
public function responses()
{
$instance = new Response;
$instance->setSid($this->sid);
return new SurveyResponseRelation($instance->newQuery(),$this);
}
public function cycle()
{
$instance = new Cycle();
return new SurveyCycleRelation($instance->newQuery(),$this);
}
public function course()
{
$instance = new Course();
return new SurveyCourseRelation($instance->newQuery(),$this);
}
public function newCollection(array $models = [])
{
return new SurveyCollection($models);
}
}
The code seems right and works when I'm not doing any more complex modifications to the model calls, however for example, when I call:
$parent->with('courses.surveys')->get()
I get the following sql related error:
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') and sid in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?' at line 1 (SQL: select * from surveys where sid in () and sid in (531557, 211231, 316692, 899214, 974717, 247825, 697782, 552663, 345392, 818373, 628794, 934974, 181774, 981825, 768386, 556866, 867981, 454781, 997136, 681294, 219854, 536314, 533283, 661282, 419684, 643469, 893499, 951161, 766562, 238263, 289637, 975286, 149335, 179627, 932135, 763659, 219722, 214899, 144844, 381495, 462774, 949323, 918832, 414629, 646126, 342421, 365583, 286479, 386494, 177941, 693328, 634294, 434532, 721241, 881355, 425659, 971835, 997579, 653716, 775787, 437953, 758524, 931996, 557856, 179298, 251354, 236281, 565872, 898672, 862168, 264461, 383562, 855941, 351452, 734981, 523667, 616126, 723435, 282423, 275988, 549494, 644412, 112726, 876769, 637444, 233532, 276116, 953935, 353756, 912427, 862134, 996477, 331321, 322652, 917295, 842584, 123751, 628385, 871618, 417254, 352626, 523421, 217281, 532171, ) group by sid)
It seems like I need to get rid of the first instance of $this->query->whereIn('sid', $survey_ids);
What am I missing here?

Laravel 5 Nested models with parent relationship

I am struggling with Laravel 5 nested models with a parent-child relationship. I manage to get the information i need but it takes 8 - 9 queries, and i believe that it should be doable with only 4.
The 3 tables look similar to this:
Article table
id | title | description | parent_id | user_id
-----------------------------------------------
1 | Some title | Awes. text | null | 1
2 | Child title | Super text | 1 | 2
3 | Child2title | Super text | 1 | 1
Comments table
id | article_id | user_id | comment
1 | 1 | 2 | Funny commment
And the Users table
id | name | ... | ...
And i have the following models defined:
Article model
class Article extends Model {
public function user()
{
return $this->hasOne('App\User', 'id', 'user_id')->select(array('id', 'name', 'points'));
}
public function comments()
{
return $this->hasMany('App\Comment')->with('user');
}
public function children()
{
return $this->hasMany('App\Article', 'parent_id', 'id')->with('user', 'comments')->select(array('id', 'parent_id', 'description', 'votes', 'updated_at', 'user_id'));
}
}
Comment model
class Comment extends Model {
public function user()
{
return $this->hasOne('App\User', 'id', 'user_id')->select(array('id', 'name', 'points'));
}
public function article()
{
return $this->belongsTo('App\Article');
}
}
User model
class User extends Model {
protected $table = 'users';
protected $fillable = ['name', 'email', 'password', 'points'];
protected $hidden = ['email', 'role', 'password', 'remember_token'];
}
Now I can get the parent article with user and comments (and users from comments) together with all the child articles with again the user that posted the article + all comments with users that posted the comments with the following query:
$article = Article::with('user', 'comments', 'children')->findOrFail(1);
But it results in 8 queries
select * from `articles` where `articles`.`id` = ? limit 1
select `id`, `name`, `points` from `users` where `users`.`id` in (?)
select * from `comments` where `comments`.`article_id` in (?)
select `id`, `name`, `points` from `users` where `users`.`id` in (?, ?, ?)
select `id`, `parent_id`, `description`, `votes`, `updated_at`, `user_id` from `articles` where `articles`.`parent_id` in (?)
select `id`, `name`, `points` from `users` where `users`.`id` in (?, ?, ?, ?)
select * from `comments` where `comments`.`article_id` in (?, ?, ?, ?, ?, ?)
select `id`, `name`, `points` from `users` where `users`.`id` in (?, ?, ?, ?, ?, ?, ?, ?)
I have tried many things but i keep getting 8 - 9 queries.
I feel like this should be doable with only 4 queries:
Get parent article
Get childs articles
Get comments
Get users
Am I missing something ?

magento Bug with ressource collection

I noticed something strange in magento behavior.
it looks like either a bug, or i missed something...
I do a simple query to retreive products
$collection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToSelect('price')
->addAttributeToSelect('sku')
->addAttributeToSelect('name')
->addAttributeToFilter(array(array(
'attribute' => 'my_attribute',
'eq' => 'my_value' )
));
//Then I update
foreach($collection as $_product){
$_product->setData("name","my_other_val");
$_product->save();
}
Magento will not only update "name", it will update ALL required fields and set the default value!!
So for instance, it changes the "visibility" attribute to "search, catalog" while the products were having another visibility!!
I have the mess now with my configurable products, and it changes also other attributes.
How do you explain this?
I did a reverse and the whole list of attributes is retrieved while saving the product, in this method:
walkAttributes
it does this:
case 'backend':
$instance = $attribute->getBackend();
Which retrieve ALL attributes. Since they have no value (they are not in the addAttributeToSelect section) then it uses the default value.
One soluton is to add
->addAttributeToSelect('visibility')
and all required attributes.
but too dangerous, I could miss one, or a new attribute could be added with the required attribute right?
For me it's a bug, because the default value should only apply to NON existing attribute value, but magento does not do a check, it does this query which either INSERT or UPDATE..
SQL: INSERT INTO catalog_product_entity_int (entity_type_id,attribute_id,store_id,entity_id,value) VALUES (?, ?, ?, ?, ?), (?, ?, ?, ?, ?), (?, ?, ?, ?, ?), (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE value = VALUES(value)
...
Thanks,
Rod
This is not a bug. It's actually a feature. When loading a collection of products, not all attributes are loaded for the product, for performance reasons.
In order to be able to save it you need to call $product->load($id) and then $product->save().
Also you have to make sure that you are running your script under the store with id 0 (admin). The save works only for that. Add this at the top of your script
Mage::app()->setCurrentStore(Mage::getModel('core/store')->load(Mage_Core_Model_App::ADMIN_STORE_ID));
But here is an other idea. Don't use save. It's slow and you can do some damage if you are not careful. Use this instead.
Mage::getSingleton('catalog/product_action')->updateAttributes($productIds, $attributes, $storeId);
This works even if you are not on the admin store and it only changes the attributes you specify. This is what the parameters mean:
$productIds - an array with the product ids you need to change. array(12, 17, 219)
$attributes - an array with what you want to change array('name'=>'Your name here', 'description'=>'Your description here')
$storeId - the id of the store for which you do the change. Use 0 for default values.
Note: If you want to set different attribute values for different products you need to call this for each attribute value.
For example calling:
Mage::getSingleton('catalog/product_action')->updateAttributes(array(12, 17, 219), array('name'=>'Your name here'), 0);
will change the name for products with id 12,17 and 219
What you should do is update the product, from the collection result, after you load it explicitly.
Here's an example of what I mean:
$product_collection = Mage::getModel('catalog/product')
->getCollection()
->addAttributeToFilter(array(array(
'attribute' => 'my_attribute',
'eq' => 'my_value'
)));
foreach ($product_collection as $p) {
$product = Mage::getModel('catalog/product')->load(
$p->getId()
);
$product->setName('NEW NAME HERE');
try {
$product->save();
echo 'Product '. $product->getSku() .' has been updated.<br />';
} catch (Exception $e) {
echo 'Failed to update product '. $product->getSku() .' - '. $e->getMessage() .'<br />';
}
}
I am not saying this is the ONLY way to do this; however this works as intended.

Does Eloquent ORM change CamelCase to underscores?

Im getting an error in Laravel using Eloquent which is:
SQLSTATE[42S02]: Base table or view not found: 1146 Table
'task_manager.rel_developers_projects' doesn't exist (SQL: insert into
`rel_developers_projects` (`project_id`, `developer_id`, `updated_at`, `created_at`)
values (?, ?, ?, ?)) (Bindings: array ( 0 => '1', 1 => '1', 2 => '2013-07-31 08:23:35', 3
=> '2013-07-31 08:23:35', ))
However, the Model is called RelDevelopersProject and the table is called RelDevelopersProjects.
Does Eloquent try to convert CamelCased names to underscores?
Do not use camel case for table names.
If you however need to, try this:
class RelDevelopersProject extends Eloquent {
protected $table = 'RelDevelopersProjects';
}
See eloquent in the Laravel Docs.
Yes, it does.
Just define the table name as a property in Model
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'RelDevelopersProject';

Resources