I am working on a query but can't find the solution to this one.
The structure i have at the moment is:
A project has 1 machine, but a machine can belong to multiple projects.
A machine can have multiple issues.
Now i want to get all projects with the issues created after the project got created.
The query that i have at the moment, but doesn't work:
$allProjects = Project::with(['machine',
'machine.issues' => function ($query) {
$query->where('created_at', '>=', 'project.created_at');
}
])
->orderBy('id')
->get();
I am not getting the issues at all by using this query, when i switch the operator to: < then i get all the issues even the ones after project.created_at
You can have a pivot do most of the work for you. I tried reproducing your problem statement as below.
<?php
class Project extends Model
{
use HasFactory;
public function machine()
{
return $this->hasOneThrough(Machine::class, MachineProject::class, 'machine_id', 'id', 'id', 'project_id');
}
public function issues()
{
return $this->hasManyThrough(Issue::class, Machine::class, 'id', 'machine_id')->whereDate('issues.created_at', '<=', $this->created_at);
}
}
class Machine extends Model
{
use HasFactory;
public $with = ['issues'];
public function projects()
{
return $this->belongsToMany(Project::class);
}
public function issues()
{
return $this->hasMany(Issue::class);
}
}
class Issue extends Model
{
use HasFactory;
public function machine()
{
return $this->belongsTo(Machine::class);
}
}
class MachineProject extends Pivot
{
//
}
To retrieve the Project with issues, you just do
$allProjects = Project::with(['machine' => function ($machine) {
$machine->with('issues');
}])->get();
Related
I am trying to add custom rule to form. I have added a custom function in model but it's not working for me.
class BackendUser extends ActiveRecord implements IdentityInterface
{
public function rules()
{
return [
['username','validateUsername','params'=>'username'=>'username']],
];
}
public function validateUsername($attribute, $params)
{
if (preg_match('/[^a-z])/i', $this->$attribute)) {
$this->addError($attribute, 'Username should only contain
alphabets');
}
}}
In PHP there is no construct like you used here (a => b => c, maybe it's a typo) and you don't have to pass any parameters anyway since you don't use them in the validator method. Simple
public function rules()
{
return [
['username','validateUsername'],
];
}
is enough.
There are few typos in your code. Try using $this->{$attribute} in dynamic attributes and also params key should be an array while calling inline validation.
class BackendUser extends ActiveRecord implements IdentityInterface
{
public function rules()
{
return [
['username','validateUsername','params'=>['username'=>'username']],
];
}
public function validateUsername($attribute, $params)
{
if (preg_match('/[^a-z])/i', $this->{$attribute})) {
$this->addError($attribute, 'Username should only contain alphabets');
}
}
}
I'm having trouble with a Laravel 5 relationship. I have 2 models Crew and Event with the corresponding tables crews and events. Crews have many events, and events have one crew. I set up my models and migration as follows:
Schema:
//Crews
Schema::connection('scheduling')->create('crews', function ($table) {
$table->increments('id');
$table->text('name');
$table->boolean('solo');
$table->boolean('active');
$table->text('phone');
});
//Events
Schema::connection('scheduling')->create('events', function ($table) {
$table->increments('id');
// ...
$table->integer('crew_id')->unsigned();
$table->foreign('crew_id')->references('id')->on('crews');
$table->text('notes');
// ...
$table->timestamps();
});
Models:
namespace App\Models\Scheduling;
use Illuminate\Database\Eloquent\Model;
class Crew extends Model {
public $connection = "scheduling";
public $table = "crews";
public function events() {
return $this->hasMany('App\Models\Scheduling\Event', 'id', 'crew_id');
}
public static function active() {
return Crew::where('active', 1)->get();
}
}
namespace App\Models\Scheduling;
use Illuminate\Database\Eloquent\Model;
class Event extends Model {
public $connection = "scheduling";
public $table = "events";
public function crew() {
return $this->belongsTo('App\Models\Scheduling\Crew', 'crew_id', 'id');
}
}
If I run Crew::find(102)->events; I end up with an empty collection.
If I run Events::where('crew_id', 102)->get(); I end up with the list of events I expected.
Any idea what I'm doing wrong here?
Your definition of events relation is invalid - you pass the arguments in wrong order.
Replace:
return $this->hasMany('App\Models\Scheduling\Event', 'id', 'crew_id');
with
return $this->hasMany('App\Models\Scheduling\Event', 'crew_id', 'id');
or simply
return $this->hasMany('App\Models\Scheduling\Event');
as you are using the default values for the column names, so no need to pass them to the relation definition.
I am creating tables on the fly. If I created the tables Schools and Classes. How can I create the models for them and specify relationships among them.
I searched but did not get anything on this topic. Any help would be appreciated. Thank you.
The only way I can figure out is to use "global variables" for tables - e.g. in Yii::$app->params['ar_tables'] and redefine them dynamically:
In config:
[
....
'params' => [
'ar_tables' => [
'Parent' => 'parent',
'Child' => 'table2'
]
]
....
]
Parent class:
class Parent extends \yii\db\ActiveRecord
{
public static function tableName()
{
return Yii::$app->params['ar_tables']['Parent'];
}
public function getChildren
{
return self::hasMany(Child::className(), ['parent_id' => 'id']);
}
}
Child class:
class Child extends \yii\db\ActiveRecord
{
public static function tableName()
{
return Yii::$app->params['ar_tables']['Child'];
}
public function getParent
{
return self::hasOne(Parent::className(), ['id' => 'parent_id']);
}
}
After that you can dynamically change Yii::$app->params['ar_tables'] values for getting what you want. I have already tried this. And didn't like :)
I am trying to use many-to-many relationships between my posts and categories models. So far I created posts , categories and post_categories tables.
In my models, I have my relationships
class Post extends Eloquent {
public function categories()
{
return $this->belongsToMany('Category', 'post_categories','category_id');
}
}
class Category extends Eloquent {
public function posts()
{
return $this->belongsToMany('Post','post_categories');
}
}
and in my controllers when I try to create a Post instance by :
$post = new Post;
$post->title = e(Input::get('title'));
$post->slug = e(Str::slug(Input::get('title')));
$post->content = e(Input::get('content'));
// Was the blog post created?
if($post->save())
{
$id = (int) Input::get('category_id');
$category = Category::find($id);
$post->categories()->attach($category);
// Redirect to the new blog post page
return Redirect::to("admin/blogs/$post->id/edit")->with('success', Lang::get('admin/blogs/message.create.success'));
}
After submitting form , I can see blog post is created normally. When I check the db , Category_id is inserted inside post_categories table but post_id is always 0.
Can anyone help me to fix this?
$post->categories()->attach($category->id);
I was using relationships in a wrong way. The table had to know the second table column name.
class Post extends Eloquent {
public function categories()
{
return $this->belongsToMany('Category', 'post_categories','category_id','post_id');
}
}
class Category extends Eloquent {
public function posts()
{
return $this->belongsToMany('Post','post_categories',,'post_id','category_id');
}
}
The best usage will be changing the table name and make it category_post table. This way all I have to do is
class Post extends Eloquent {
public function categories()
{
return $this->belongsToMany('Category');
}
}
class Category extends Eloquent {
public function posts()
{
return $this->belongsToMany('Post');
}
}
My model: as seen below, very basic
class User extends CI_Model
{
function __construct()
{
parent::__construct();
}
function getAll()
{
$this->db->order_by("lastName", "asc");
$this->db->order_by("firstName", "asc");
$this->db->order_by("userName", "asc");
$query = $this->db->get('user');
// test for result
if($query->num_rows() > 0)
{
return $query->result();
}
return NULL;
}
}
My controller: actually part of my controller, every time loading the users/display function by default route, the error (further down) shows up. Should a model loaded in a controller's contructor be available for all other function in the same controller?
class Users extends CI_Controller
{
function __contruct()
{
parent::__construct();
$this->load->model('user');
}
function display()
{
$data['users'] = $this->user->getAll();
$head['pageTitle'] = 'Users Panel';
$this->load->view('security/redirect');
$this->load->view('template/head', $head);
$this->load->view('user/usersPanel', $data);
$this->load->view('template/foot');
}
}
My error: refering to the line, "$data['users'] = $this->user->getAll()", in above controller
A PHP Error was encountered
Severity: Notice
Message: Undefined property: Users::$user
My environment:
Codeigniter 2.1.0;
Mac Lion;
MAMP 2.0;
Shouldn't this:
class Users extends CI_Controller
{
function __contruct()
{
be like this:
class Users extends CI_Controller
{
function __construct()
{
replace contruct with construct.
Shouldn't this:
$data['users'] = $this->user->getAll();
be this:
$data['users'] = $this->user_model->getAll();
sorry
also the model name:
$this->load->model('user_model');
and class name User_model extends CI_Model
All of my CI projects are set up this way.
http://codeigniter.com/user_guide/general/models.html