How to generate database table models with Gii in Yii? - php

Problem:
I used gii to generate database table models. So If I have any change in users table structure, I used gii and all my relations and other methods are removed from class. So I need to make backup of class and regenerate class and bring back other methods and relations.
Possible Solution:
I changed my class into two classes like this for a table 'users':
class Users extends UsersMapper {
public function tableName() {
return 'users';
}
public function rules() {
.....
}
public function relations() {
.....
}
}
class UsersMapper extends CActiveRecord {
public function getAllUsers() {
......
}
public function getBlockedUsers() {
......
}
}
Question:
Above method is working for me and I am using only Users class everywhere in my code. Is it valid method or there is any problem with this logic. Is there any other method.
Thanks

The Giix extension will create a models/Users class and a models/_base/BaseUsers class for your case. The Users class extends the BaseUsers class. Thus only the BaseUsers class needs to be regenerated on changing the database. It also comes with a couple of extra methods that I use quite a lot.

Related

Laravel way to add a column value on all models like created_at

I need to add a column to some of my database tables and populate that on Model::create().
All I want is functionality like Laravel built in timestamps i.e created_at and updated_at
I know of some solutions but I wanted to know if something else could be done in such case.
For example:
protected static function booted()
{
static::created(function ($user) {
//
});
}
OR
class UserObserver
{
public function creating(User $user)
{
//
}
}
I will need to do that for every model which is repeating myself.
Another solution that comes to my mind is creating a BaseModel and then extend everything from that.
I wanted to do something like we have in SoftDeletes trait, Add whatever logic inside of that and populate that column using some laravel hook that I am not aware of. If someone can guide me to accomplish such thing using traits and HOW?
You can extend all your models off of a base model class (a small refactor), and then in that class add a booted method with your custom logic.
If you then need (or already have) extra logic in a model (say the user model) that uses the booted method, you can still keep that, but make sure you call parent::booted();
class BaseModel extends Model {
protected static function booted()
{
static::created(function ($model) {
//logic
});
}
}
class User extends BaseModel {
protected static function booted()
{
parent::booted();
//any other logic you may have/want in user
}
}
This is in my opinion the most scalable approach. Make use of OOP! You can also then reuse this base class for other global logic in the future.

Trying to get property of non-object in laravel 5.3 app though model relations seems appropriate

User model
class User extends Authenticatable{
public function enrollments() {
return $this->hasMany('App\enrollments','user_email');
}
}
Batch model
class batch extends Model{
protected $table = 'batch';
public function enrollments() {
return $this->hasMany('App\enrollments');
}
}
Enrollments model
class enrollments extends Model{
public function batch() {
return $this->belongsTo('App\batch');
}
public function user() {
return $this->belongsTo('App\User','email');
}
}
if I use $enrollment->batch->title, it works..
but if I use $enrollment->user->name, it gives an error
Trying to get property of non-object
Please help, I am stuck
Thanks in advance
EDIT
The problem arose after I changed the foreign key from between user and enrollment from id to email and renamed my column to user_email from user_id. Before that code was working fine.
Solved
Got the problem, It was with some data in enrollment which didn't have registered email with user.
This code will note work simply because User is not a child of Model. To fix it you must extend from Model. Authenticatable is an interface and there is an equivalent trait; there is no such class.
You must implement the interface if you want your user class to be Authenticatable. But to answer your question, extend the base model, Model.
class User extends Model {
public function enrollments() {
return $this->hasMany('App\enrollments','user_email');
}}
In addition:
If you need to log an existing user instance into your application,
you may call the login method with the user instance. The given object
must be an implementation of the
Illuminate\Contracts\Auth\Authenticatable contract. Of course, the
App\User model included with Laravel already implements this
interface:
https://laravel.com/docs/5.3/authentication

PHP OOP UML Separate databse config details from class

I am developing a eCommerce store for school project.
i have several classes like this that uses same database connection.
so i have to separate those.
1. how to use a single database connection file for all of my classes.I have sevaral classes same as this
2. I draw some use case and class diagram. if any one has experience in UML - (ecommerce ) can you verify those?
class abc {
public $id;
public $name;
public $email;
public $db;
function __construct()
{$this->db=new mysqli('localhost','root','','cart');}
public function newsletter_subcribe()
{$sql="insert into table (id,name,email) value('$this->id','$this->name','$this->email')";
$this->db->query($sql);}
this class is do some query to your database for CRUD, the best thing you can do is make one more controller to access to this class, also make sure every function to do that is in private, not public.
so basicly the controller will post data to class to do CRUD.
more like Model in CI.
CONTROLLER -->> YOUR CLASSS -->> DATABASE
CLASS A
{
private function dbconnection()
{
}
private function a($param)
{
dbconnection();
//CRUD HERE
}
}
CLASS B
main function()
{
//load class A here, and you can access all method
$result = a($param);
}

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';
}
}

Categories