If you create a checkbox list in symfony 1.2 you get an array with the checked options back in the form. If you save the form, your database now contains the words "Array". Is there a way around this? Or should I just json_encode / json_decode the array as ncecessary and save it manually? Seems awfully tedious.
Thanks for reading.
You can use serialize() and unserialize() functions when saving and getting data.
I don't know which orm using but i can explain with propel way.
For example you have post table and Post class. And post table has options column with text or varchar data type.
in Post.class.php your model directory you can define two override methods
setOptions($v)
{
parent::setOptions(serialize($v));
}
getOptions()
{
return unserialize($this->options);
}
Just like that.
In your view or action you can get all options with $post->getOptions() and you have an Array that contains all option related to your database record.
Related
How to save multiple selected dropdown values into a single column in Grails?
Input will look like
<g:select name="item1Price" from="${1..10}"/>
<g:select name="item2Price" from="${1..10}"/>
<g:select name="item3Price" from="${1..10}"/>
And Output Should be stored in one field
ItemPrice: 2,8,6
Your question is a bit vague, so hopefully a somewhat vague answer will be helpful too!
If you have a domain object Foo:
class Foo {
String itemPrice
}
Then in your controller action, you can just do something like:
def save() {
Foo f = new Foo()
f.itemPrice = [params.item1Price, params.item2Price, params.item3Price].join(",")
f.save()
}
Really all you're trying to do is join your parameters from your page into one string, right?
Now this actually seems like bad design to me. What happens if the order changes, or if nothing is selected for item 2? Or what happens if somebody wants to edit your object and you need to parse the values back out? Obviously you could split on commas...until one of the values contains a comma!
You're better off storing one value for each field that means something different, or storing a single field as a structured value. You might want to look at encoding a Map into JSON and storing that, for example, if you really just want to have one field in your domain object.
I have a table with this columns:
param_id
val_value
val_flag
date_value
tmp_value
tmp_flag
And I have an array of elements, I always have param_id and date_value, but sometimes i have val columns and other times I have tmp columns.
I use $data->save() because sometimes I need to create a new register in db and other times I need to update the register with param_id and date_value.
The question is: Is there any way to do an insert/update but when is an update, only update tmp columns or val columns? I think a find First is my only option, but maybe there is another way.
Thank you.
[EDIT]
I'm trying with the whitelist but it does not work. Let me explain how the method works: I get a request to a web service, process the xml and generate an array of elements with the information collected, after processing these elements I have an array of elements of the class appropriate to save, but these may be new or existing and may contain tmp or val values, I have tried with this but I still change the values to null.
if ($medida->tipo == 'temporal'){
$whiteList = array('val_value','val_flag');
}else if ($medida->tipo == 'validado'){
$whiteList = array('tmp_value','tmp_flag');
}
$dato->save(null, $whitelist);
I do not have data of the post, I use null instead, I have also tried to use an array with the manual assignment of the data obtaining the same result.
Here are two options that can help you:
1) Use 'whitelist' for the save() method.
$obj->save($this->request->getPost(), ['tmp_1', 'tmp_2']);
More info in the documentation.
2) Use the 'Event Manager'.
The methods beforeCreate() and beforeUpdate() will be useful so you can decide which fields to use.
More info in the documentation.
Also if you really want phalcon phql to update only columns which changed you need to enable dynamic update.
I am new to learning and understanding how Hydration works, just wanted to point that out first. I'm currently able to Hydrate Select and Insert queries without any problems.
I am currently stuck on trying to Hydrate Update queries now. In my entity I have setup the get/set options for each type of column in my database. I've found that the ObjectProperty() Hydrator works best for my situation too.
However whenever I try to update only a set number of columns and extract via the hydrator I am getting errors because all the other options are not set and are returning null values. I do not need to update everything for a particular row, just a few columns.
For example in my DB Table I may have:
name
phone_number
email_address
But I only need to update the phone_number.
$entity_passport = $this->getEntityPassport();
$entity_passport->setPrimaryPhone('5551239876');
$this->getTablePassport()->update($this->getHydrator()->extract($entity_passport), array(
'employeeid' => '1'
));
This returns an error because setName() and setEmailAddress() are not included in this update and the query returns that the values cannot be null. But clearly when you look at the DB Table, there is data already there. The data that is there does not need to be changed either, only in this example does the PrimaryPhone() number.
I've been looking and reading documentation all over the place but I cannot find anything that would explain what I am doing wrong. I should note that I am only using Zend\Db (Not Doctrine).
I'm assuming I've missed something someplace due to my lack of knowledge with this new feature I'm trying to understand.
Perhaps you don't Hydrate Update queries... I'm sort of lost / confused. Any help would be appreciated. Thank you!
I think you're having a fundamental misconception of hydration. A hydrator simply populates an entity object from data (hydrate) and extracts data from an entity object (extract). So there are no separate hydrators for different types of queries.
In your update example you should first retrieve the complete entity object ($entity_passport) and then pass it to the TableGateway's update method. You would retrieve the entity by employeeid, since that's the condition you're using to update. So something like this:
$entity_passport = $passportMapper->findByEmployeeId(1);
$entity_passport->setPrimaryPhone('5551239876');
$this->getTablePassport()->update($this->getHydrator()->extract($entity_passport), array(
'employeeid' => $entity_passport->getId()
));
This is assuming you have some sort of mapper layer. Otherwise you could use your passport TableGateway (I assume that's what getTablePassport() returns, no?).
Otherwise, if you think retrieving the object is too much overhead and you just want to run the query you could use just a \Zend\Db\Sql\Sql object, ie:
$sql = new \Zend\Db\Sql\Sql($dbAdapter);
$update = $sql->update('passport')
->set(array('primary_phone' => $entity_passport->getPrimaryPhone()))
->where(array('employeeid' => $employeeId));
Edit:
Maybe it was a mistake to bring up the mapper, because it may cause more confusion. You could simply use your TableGateway to retrieve the entity object and then hydrate the returned row:
$rows = $this->getTablePassport()->select(array('employeeid' => 1));
$entity_passport = $this->getHydrator($rows->current());
[...]
Edit 2:
I checked your gist and I noticed a few things, so here we go:
I see that your getTablePassport indeed does return an object which is a subclass of TableGateway. You have already set up this class for it to use a HydratingResultset. This means you don't need to do any manual hydrating when retrieving objects using the gateway.
You also already implemented a Search method in that same class, so why not just use that? However I would change that method, because right now you're using LIKE for every single column. Not only is it very inefficient, but it will also give you wrong results, for example on the id column.
If you were to fix that method then you can simply call it in the Service object:
$this->getTablePassport->Search(array('employeeid' => 1));
Otherwise you could just implement a separate method in that tablegateway class, such as
public function findByEmployeeId($employeeId)
{
return $tableGateway->select(array('employeeid' => $employeeId));
}
This should already return an array of entities (or one in this specific case). P.S. make sure to debug and check what is actually being returned when you retrieve the entity. So print_r the entity you get back from the PassportTable before trying the update. You first have to make sure the retrieval code works well.
Following many tutorials from official and non-official docs, there is no such a clear vision for common approach for creating editing the entity and updating just specific fields.
The main questions are:
1 - Create the entity - fill the form, validate, create entity object and populate it with exchangeArray and then save, in save method via docs we must configure an array from passed object like:
$data = array(
'artist' => $album->artist,
'title' => $album->title,
);
Can we avoid this array re-configuring in save method?
2 - Update the entity - same logic
3 - What if we want to update only one specific field?
I pass the array to updateEntity method, but is it normal way to pass object(and configure array inside method) to save method and pass array to update method?
4 - Almost same thing with 3 but issue now when we have an array with another keys among our entity fields keys, we can strip 'bad' array keys using hydrator and make something like array_intersect style, but what you suggest?
You can use a smart combination of your entity, form, input filter and hydrator to have almost no logic to get CRUD things done. For an admin interface I usually generate my controller, form and other classes. I use Sublime Text 2 and the snippets to generate these classes can be found in my repository.
This results in:
A controller with index (listing), view (single item), create, update and delete
A form to contain all entity fields
A repository (Doctrine) to query entities
A service to persist to the database (either create one, save one or delete one)
This will solve #1 and #2. Due to the way ZF2 filtering and hydration works, this will also solve #4 for you. Then, it is possible to set only a select no. of fields to be filtered, but I have not implemented that (yet). I can only refer to the manual to know how to do that.
If you want to know the implementation of above snippets, take a look at Soflomo\Portfolio which uses a similar strategy.
PHP, contrary to other languages, is array centric than object centric. Most task could be done via Array. In this case, instead of use
<?php
class SomeClass {
public $artist;
public $title;
}
$album=new SomeClass();
$data = array(
'artist' => $album->artist,
'title' => $album->title,
);
?>
We should use
<?
$SomeObject=array("artist"=>xxx,"title"=>xxxx);
$data = $someObject;
?>
i.e. we should avoid to use classes when we are referencing a POCO class and instead we should use the (less elegant) array. Otherwise, sometimes we will be forced to do such conversion between array and object.
Anyways i we will need to keep it as a object then, we can do the conversion between object to array using:
<?php
class SomeClass {
public $artist;
public $title;
}
$album=new SomeClass();
$data = (array)$album;
?>
However, this conversion sometimes is tricky.
how can i automatically update my entity objects changed values and save them to db.
I hava an Action like that
public ActionResult Update()
{
User userToUpdate = new User();
TryUpdateModel<User>(userToUpdate,ValueProvider);
BaseRepository.Context.AttachTo("User",userToUpdate);
BaseRepository.Context.SaveChanges();
return Json("");
}
ValuProvider : has the items that come
from the client as post data.
The problem on this code is the code update all the values but i want to update only the changed values.
How can i find the changed values on my entity object.
You should check out the ObjectContext.ApplyPropertyChanges Method
it is suppose to do what your asking for...
msdn
Two options:
On the View you could know the values that were changed by using Javascript and then you could pass that information to your controller.
You could simply compare the previous values (which you already have since you populated a view) and check each value before updating the DB.
I prefer last option, since at this point you could also check for data validation.
This is really a problem for your data access code, not anything to do with your controller. Pick an ORM that handles this for you and forget about the problem.