Namespaces with Phalcon models - php

I have a project made with the command phalcon project simple --type=simple.
I haven't changed the structure at all.
The part where I'm stumped, is that I have two databases I look at.
I want to access the Account model for both databases A and B, with out doing something like $account = AAccount::find(); and $account = BAccount::find();.
I currently have this code:
model/AAccount.php
class AAccount extends Phalcon\Mvc\Model {
// use DB A
}
model/BAccount.php
class BAccount extends Phalcon\Mvc\Model {
// use DB B
}
What is the most optimum way of doing so? Namespaces? I cannot change the table name Account for both.

I don't know if I understand your question: you have two tables with the same name, but they are in two different schemas (databases)? If yes, I had the same problem and I solve it with the follow structure (you can see part of this code in my bauhaus project) (see this reference too: point to other schema (Phalcon - Working with Model)):
(1) Base model class located at models/:
namespace MyApp\Model;
class Base extends \Phalcon\Mvc\Model
{
// code for your model base class
}
(2) Base class for schema A located at models/schema-a/:
namespace MyApp\Model\SchemaA;
class Base extends MyApp\Model\Base
{
// ...
// returns the name of the schema A
public function getSchema()
{
return `schema_a_name`;
}
// ...
}
(3) Base class for schema B located at models/schema-b/:
namespace MyApp\Model\SchemaB;
class Base extends MyApp\Model\Base
{
// ...
// returns the name of the schema B
public function getSchema()
{
return `schema_b_name`;
}
// ...
}
(4) Account Model in the schema A located at models/schema-a/:
namespace MyApp\Model\SchemaA;
class Account extends Base
{
// ...
}
(5) Account Model in the schema B located at models/schema-b/:
namespace MyApp\Model\SchemaB;
class Account extends Base
{
// ...
}
This solution works good when you have a fixed number of schemas, but If you have no-fixed number of schemas, I think a better solution would be to create an logic in the getSchema function of the model base. Something like:
public function getSchema()
{
// this is just a suggest
return $this->getDI()->scope->currentSchema;
}
I hope this can help you.
Note: you will have to be careful to create relationships between models with namespace.

Related

using a single method in two Models in Laravel; OOP PHP

I have 4 models held together by 4 pivot tables:
User, Company, Phone, Address
The User and Company are both tied together to Phone with the pivot tables user_phone and company_phone.
User has a method: addDefaultPhone( Request $request ). It grabs $request->input() and creates a phone number and attaches it to the User.
The same exact method can be used in the Company class. How can I include addDefaultAddress to both classes (without copying and pasting of course)?
You may use inheritance or trait. Choose whatever you want.
Inheritance
Create a base class:
namespace App;
use Illuminate\Database\Eloquent\Model;
class ThingWithAPhone extends Model {
public function addDefaultPhone() {
/* Whatever you want... */
}
}
Then both User and Company could extend this class:
// In the user file
class User extends ThingWithAPhone { /* ... */ }
// In the company file
class Company extends ThingWithAPhone { /* ... */ }
Trait
Create a trait:
namespace App;
class Phonable {
public function addDefaultPhone() {
/* Whatever you want... */
}
}
Use this trait:
// In the user file
class User extends Model {
use Phonable;
/* ... */
}
// In the company file
class Company extends Model {
use Phonable;
/* ... */
} }
With trait you can create class which have X traits, and one other class with Y traits and some of these traits may be common to both classes.
The Best i can think of is to create a trait and share among the classes.

How to share scopes between classes in Laravel 5

I have several Laravel models which have the same functionallity.
I'm trying to implement some sort of ::All() functionallity but with another logic behind it.
For example: all my models have an "Active" boolean flag, which means that I get all of my languages like: $language = Language::where('active', 1)->orderBy('name')->get();. The same goes for hobbies, semesters, etc.
I'm trying to do something like this in my base_model from which all other models extend:
public static function getActive()
{
return this::where('active', 1)->orderBy('name')->get();
}
this would save me lots and lots of redundant code, but as a newbie I'm struggling with the code.
How can I dynamically define the Model I want to retrieve?
Any ideas?
You can use Laravel query scopes for this. For example:
//your base model
class BaseModel extends Model
{
//every class inheriting from this will have this scope
public function scopeActive($query)
{
return $query->where('active', 1)->orderBy('name')->get();
}
}
//your child models will inherit the scope from the parent class
class Language extends BaseModel
{
//your model's methods
}
//use the scope to get all the active languages
$languages = Language::active();

Yii: add prefix/postfix to model class naming

Is there any way I can get Yii to work with models that have a prefix or postfix in their class name?
For example, I have a table user, which corresponds to the model User. Now, I want this model to have a prefix, say, EmulatedUser. Is there any way to achieve that without renaming my table?
The table and class name don't have to be the same. You can override the tableName in your model:
<?php
class EmulatedUser extends CActiveRecord {
public function tableName() {
return 'user';
}
}

Laravel 4 Model only works if i take another name for the class and file

Hello i have a Controller:
class AddressController extends BaseController {
public function showIndex()
{
$address = Postcode::all();
return 'hello';
}
And a Model (which doesn't work):
class Postcode extends Eloquent {
protected $table = 'postcode';
}
But it only works with another name like:
class Kla extends Eloquent {
protected $table = 'postcode';
}
Anybody knows why?
You have named something else in the root namespace as Postcode. Most common this is the database migration. This is why database migrations generally should be a class name describing what it is doing, so in your case CreatePostcodeTable.
This is also why you should be using namespaces.
Just to be clear in-case you don't understand namespaces. You have 2 classes with the same name. The composer autoloader has grabbed the first one it finds (the one that isn't your model) and tried to use it. There is no static method all on the other class so you get an error (which you should have pasted in your question).

Generating classes at runtime in yii framework is a bad idea?

Let's assume that we have module called 'UsersModule' with the following model in it:
class User extends CActiveRecord
{
// Some code here
}
We use this module in different applications and some time we want to extend User model to add some custom methods or properties to it. More over, often we want to change tables in database to store this new properties in it. But we don't want to change code in the UsersModule itself because it comes from the master repository (GitHub for ex.) and when we fix some bugs in it we want to simply update this module from repository in all our projects. At the same time we want to save custom changes made for the projects. So we have the following idea:
In UsersModule.php we do the following:
class UsersModule extends CWebModule
{
public $usersBaseClass = 'UsersBase';
}
In Users.php:
$extendClass = Yii::app()->getModule('users')->usersBaseClass;
$version = '1.0';
$usersFile = Yii::getPathOfAlias('application.runtime').'/Users_extends_'.$extendClass.'_v'.$version.'.php';
if(!file_exists($usersFile)) {
$code =<<<PHP
<?php
/**
* This is the model class for table "{{users}}".
*/
class Users extends {$extendClass}
{
/**
* Returns the static model of the specified AR class.
* #param string \$className active record class name.
* #return Users the static model class
*/
public static function model(\$className=__CLASS__)
{
return parent::model(\$className);
}
}
PHP;
file_put_contents($usersFile, $code);
}
if(!class_exists('Users', flase))
require_once($usersFile);
Also we introduce UsersBase.php:
class UsersBase extends CActiveRecord
{
// All base Users model logic is here
}
So when we use Users class somewhere in our application our code in Users.php generates real Users class that extends desired base class. In each project when we want to extend our Users model we can do the following:
In configs/main.php of the project:
'modules' =>
'users => array(
'usersBaseClass' => 'MyUsers'
)
And also we add MyUsers.php some where in our application:
class MyUsers extends UsersBase
{
// All the custom logic goes here
}
So my question is:
Is it a good idea to generate classes automatically in runtime or not?
Genrating php code during runtime could work, but not the best solution imho. You should use some kind of table inheritance.
More info:
http://www.yiiframework.com/wiki/198/single-table-inheritance/
http://learnyii.blogspot.hu/2012/04/yii-table-inheritance-single-active.html

Categories