How I can add column before another column in dbforge? - codeigniter

I want to add column that name 'accept_loc', type 'VARCHAR' to 3 database tables (use dbforge library from codeigniter) Assum they are named t1,t2,t3.
t1 structure:
id
bla_bla
pick_up_loc
....
t2 structure:
id
pick_up_loc
....
t3 structure:
id
bla_bla
pick_up_loc
....
if I used this code below in my migration up function:
$fields = array(
'accept_lat' => array(
'accept_loc' => 'VARCHAR',
'constraint' => '50',
'after' => 'id',
),
);
$this->dbforge->add_column('t1',$fields);
$this->dbforge->add_column('t2',$fields);
$this->dbforge->add_column('t3',$fields);
result:
t1 structure:
id
accept_loc
bla_bla
pick_up_loc
....
t2 structure:
id
accept_loc
pick_up_loc
....
t3 structure:
id
accept_loc
bla_bla
pick_up_loc
....
it's not a good looking structure. How can I add column before 'pick_up_loc' to all of them (n database tables).

Please try to put the after in uppercase, that is 'AFTER', there was a bug in that after key and mentioned got fixed here.
$fields = array(
'accept_lat' => array(
'accept_loc' => 'VARCHAR',
'constraint' => '50',
'AFTER' => 'id'
)
);

The third argument in add_column() is $after_field. So you can't add the column before another column but you can do this:
$this->dbforge->add_column('t1', $fields, 'bla_bla');
$this->dbforge->add_column('t2', $fields, 'id');
$this->dbforge->add_column('t3', $fields, 'bla_bla');
Also, you seem to be naming the field 'accept_lat' and then using 'accept_loc' instead of the 'type' element which is confusing things.

Late to the party but to clarify your code, on t1 for example, should look like this:
$fields = array(
'accept_lat' => array('type' => 'TEXT')
);
$this->dbforge->add_column('t1', $fields, 'id');
So accept_lat will be added after the id column in table t1.

Related

Insert row in parents and childs table laravel

Im so lost. I have table, model and controller named Navbar. Here I create navbar buttons. I made child table called "type_1". So "navbar" id goes to table "type_1" and its column called "navbar_id".
$form_data = array(
'tipas' => $tipas,
'p_id' => $p_id,
'name' => $request->title,
'text' => $request->text,
'img' => $name
);
navbar::create($form_data); //created parent row
Here navbar button is created. How can I create childs empty row with parent (navbar) id? Should I use models or I can do it here?
On your Parent model, you need to define a relation like this :
public function child()
{
return $this->hasMany(Child::class);
}
Now you can insert data with eloquent method like this :
$form_data = array(
'tipas' => $tipas,
'p_id' => $p_id,
'name' => $request->title,
'text' => $request->text,
'img' => $name
);
$q = Parent::create($form_data); //created parent row
$q->child()->create(['name' => 'John', 'email' => 'me#john.com']); // here parent_id will be created by the model
Official documentation of the create method

Yii filter search working for one relation but not for other

I am using Yii GridView filter and my data comes from Purcahses table.
That tables realted to
1 .vendors
2 .clients
Below are my relations in Purchases Model
'vendor' => array(self::BELONGS_TO, 'Vendors', 'Vendor'),
'client' => array(self::BELONGS_TO, 'Clientsinfo', 'clientID'),
and i am using that relations in my admin view , Below is code of admin.php file
$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'purchases-grid',
'dataProvider' => $model->search(),
'filter' => $model,
'columns' => array(
array(
'name' => 'Vendor',
'value' =>'$data->vendor->VendorName',
),
array(
'name' => 'clientID',
'value' =>'$data->client->Company'
),
array(
'name' => 'PurchaseType',
'value' => 'Purchasetype::model()->findByPk($data->PurchaseType)->PurchaseType',
'filter' => '',
),
),
));
and lastly here is model search function where is use with and together to get data from other tables
public function search() {
$criteria = new CDbCriteria;
$criteria->together = true;
$criteria->with = array('vendor');
$criteria->with = array('client');
$criteria->compare('PurchaseType', $this->PurchaseType);
$criteria->compare('vendor.VendorName', $this->Vendor, true);
$criteria->compare('client.Company', $this->clientID, true);
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
));
}
Getting data from client successufully , but when i use vendor fitter it throw me error below
CDbException
CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]: Column not found: 1054 Unknown column
'vendor.VendorName' in 'where clause'. The SQL statement executed was: SELECT COUNT(DISTINCT t.PurchaseID
) FROM purchases t LEFT OUTER JOIN clientsinfo client ON (t.clientID=client.ClInfoID
) WHERE ((Vendor=:ycp0) AND (vendor.VendorName LIKE :ycp1)) (C:\xampp\htdocs\laurenparker\framework
\db\CDbCommand.php:543)#0 C:\xampp\htdocs\laurenparker\framework\db\CDbCommand.php(433): CDbCommand-
queryInternal('fetchColumn', 0, Array)
Youre overriding relations in criteria. Change this:
$criteria->with = array('vendor');
$criteria->with = array('client');
To this:
$criteria->with = array('vendor', 'client');

Yii Sortable Column in CGridView

I have a calculated column I wanna have sortable.
I have a get method for it...
public function getCur_margin() {
return number_format(($this->store_cost / $this->store_price) / $this->store_cost * 100, 2) . '%';
}
And I followed this thread...
CGridview custom field sortable
But now it's looking for an actual column in the database. How can I fetch a field using <calculations> AS cur_margin only temporarily for this CActiveDataProvider?
Here is the controller code for the provider:
$dataProvider = new CActiveDataProvider('Products', array(
'criteria' => array(
'condition' => 'store_id IN (SELECT `id` FROM `stores` WHERE `user_id` = ' . Yii::app()->user->id . ')',
),
'pagination' => array(
'pageSize' => 15,
),
'sort'=>array(
'attributes'=>array(
'cur_margin' => array(
'asc' => 'cur_margin ASC',
'desc' => 'cur_margin DESC',
),
),
),
));
Have you tried to specify your custom field in select property of CDbCriteria?
'select' => array(
..., // fields to select
'(<calculations>) AS cur_margin'
)
You don't have to declare getCur_margin() method then but only declare a public $cur_margin member in your model. All required calculations will be done in SQL query.
You can also refer to this thread as an example.

cakephp 2.1 contain second level different field name

I can't get the values from a second level contain using different field name as link.
Asistencia model:
var $belongsTo = array('Employee');
Horario model:
var $belongsTo = array('Employee');
Employee model:
var $hasMany = array(
'Horario' => array(
'foreignKey' => 'employee_id',
'dependent' => true
),
'Asistencia' => array(
'foreignKey' => 'employee_id',
'dependent' => true
)
);
I'll explain using these values on my example record:
Asistencia: employee_id = 3701
Employee : id = 3701
In my find() from Asistencia, I get to contain Employee by switching Employee primaryKey just fine:
$this->Asistencia->Employee->primaryKey = 'id';
$this->paginate = array(
'contain' => array(
'Employee' => array(
'foreignKey' => 'employee_id',
//'fields' => array('id', h('emp_ape_pat'), h('emp_ape_mat'), h('name')),
'Horario' => array(
'foreignKey' => 'employee_id',
//'fields' => array('id' )
))
),
'conditions' => $conditions,
'order' => 'Asistencia.employee_id');
However, my Horario record is linked to Employees via another field: emp_appserial
Employee : emp_appserial = 373
Horario : employee_id = 373
How can my Employee array contain Horario array? (they do share the value just mentioned).
Currently, the Horario contain is using the value on Asistencia.employee_id and Employee.id (3701). (checked the sql_dump and is trying to get the Horario via
"WHERE `Horario`.`employee_id` = (3701)"
but for the Employee to contain Horario, it should use the value on Employee.emp_appserial and Horario.employee_id (373).
This is what i get (empty array at bottom)
array(
(int) 0 => array(
'Asistencia' => array(
'id' => '5',
'name' => null,
'employee_id' => '3701',
'as_date' => '2012-11-19',
),
'Employee' => array(
'id' => '3701',
'emp_appserial' => '373',
'emp_appstatus' => '8',
'AgentFullName' => '3701 PEREZ LOMELI JORGE LORENZO',
'FullNameNoId' => 'PEREZ LOMELI JORGE LORENZO',
'Horario' => array()
)))
Please notice:
'employee_id' => '3701', (Asistencia)
and
'emp_appserial' => '373', (Employee)
my Horario has 'employee_id' = 373.
How could I make the switch so the relation Employee<->Horario is based on emp_appserial?
Thank you in advance for any help.
Firstly you may be getting problems because you're using Spanish words for your Model names and I suspect you're also using them for Controllers.
This is a very bad practice since CakePHP's idea is:
Convention over configuration.
This is achieved through the Inflector class which "takes a string and can manipulate it to handle word variations such as pluralizations or camelizing and is normally accessed statically". But this works ONLY WITH English words. What this means for you is that you may be missing the data because Cake is not able to build the DB queries right, since you're using Spanish words. By doing so you're making the use of CakePHP's flexible persistence layer obsolete - you will have to make all the configurations by hand. Also most likely pagination will NOT WORK. Other parts of the framework may also not work properly:
HtmlHelper, FormHelper, Components, etc. ...
These problems will expand if you try to use more complex Model associations such as HABTM or "hasMany through the Join Model".
So I do not know why exactly you aren't seeing the Horario record, but what I just explained most likely is your problem.
What you're trying to do is against the core principles of CakePHP and you'd save yourself a lot of problems if you refactor a bit and use English words. Your other option is NOT TO use Cake.

yii active record join models

Using Yii framework.
I have 3 models.
Articles - table articles(id, name)
ArticlesToAuthors - table articles_to_authors (id, article_id, author_id, type)
Authors - table authors (id, name)
I need to get authors.*, article_to_authors.type for specific article_id.
I was trying to make relation in ArticlesToAuthors model like that:
'authors' => array(self::HAS_MANY, 'Authors', array('id' => 'author_id'), ),
then i made query:
$authors = ArticlesToAuthors::model()->with('authors')->findAll(array('condition' => 'article_id=2217') );
foreach($authors as $a)
{
//this is not working
#var_dump($a->authors->name);
#var_dump($a->name);
//this works fine
foreach($a->authors as $aa)
{
var_dump($aa->name);
}
}
Can i get all active record object in one and not to do foreach in foreach?
I need an analogue to sql "SELECT atoa., a. FROM articles_to_authors atoa LEFT JOIN authors a ON atoa.author_id=a.id WHERE atoa.article_id=:article_id"
Am i doing right?
p.s. - sorry for my bad english.
It looks like you need the following relations:
in your ArticlesToAuthors table:
'author' => array(self::BELONGS_TO, 'Authors', 'author_id'),
'article' => array(self::BELONGS_TO, 'Articles', 'article_id'),
and, for completeness, in your Authors table:
'articlesToAuthors' => array(self::HAS_MANY, 'ArticlesToAuthors', array('id' => 'author_id'), ),
This should allow you to access $a->author->name. Not tested, that's just off the top of my head.

Resources