Using Yii relational query - php

Is it possible while defining a related Model in an ActiveRecord definition to specify a relation scope that allows only those models to be related whose corresponding column(s) match some predefined critaria in the joining table ?
eg. let us have a users table with fields : id(pk), username(pk),pwd_hash(text), pwd_salt(text)
and an items table : id(pk), itemData(text)
and a correlating table : id(pk),user_id(pk), item_id(pk), some_attribute(int)
Now I would like to define a Many-to-Many relationship such that User Model has a field xitems which would provide me only those items for which the value of some_attribute is greater than some value y. Is it possible to do so using Yii ActiveRecord implementation.
I do understand that I can define a model corresponding to the correlating table which would have belongs-to relation with both items and users and query this table ... but I was looking for a more succinct approach.
[edit]
Probably my best bet would be define a model method which abstracts an inner join operation.

I'm fairly sure you do need a model for the join table to get access to its data, which your example needs. Without the join table model, AR will only deal with the FKs in the join table (AFAIK).
This article may be of help to you: Accessing data in a join table with the related models

Related

How to define a one-way one-to-one relationship in Laravel (5.4) Eloquent?

Think I'm missing something obvious here, but I want to define a one way, one to one relationship from table_1 to table_2, e.g. table1 schema:
Schema::create('table1', function (Blueprint $table) {
// Some field definitions
$table->integer('table2_id')->unsigned();
$table->foreign('table2_id')->references('id')->on('table2')->onDelete('cascade');
});
Table 2 doesn't know anything about Table 1, so just has a bunch of fields defined. Model for Table 1 has:
public function table2() // Get table2 record
{
return $this->hasOne('App\Table2');
}
Questions:
a.) Is that relationship in the record necessary just to be able to lookup the relevant table2 record from a table1 record?
b.) How do I set the relationship in my code? Currently my controller code is:
$table_1_record = new Table1();
// What code here to define the relationship, using Eloquent? Or do I just do:
$table_1_record->table2_id = my_table2_record->id;
// But this just sets it manually doesn't it, rather than using Eloquent?
Thing that is confusing me is in here: https://laravel.com/docs/5.6/eloquent-relationships#one-to-one a bit further down from the link, where it says
Eloquent determines the foreign key of the relationship based on the
model name. In this case, the Phone model is automatically assumed to
have a user_id foreign key.
Applying that example to my code, the thing is I don't want to have to define a table1_id in my Table_2 - but sounds from that quote from the docs that I need to, to find a table2 record from table1...?
c.) Is there any point in this line in the migration: $table->foreign('table2_id')->references('id')->on('table2')->onDelete('cascade'); and indeed using Eloquent at all (I want to do things the proper Laravel way), or shall I just simply manually set table2_id as in question b.) above?
Note: I don't want to define the inverse of the relationship, as I don't need to find a table_1 record from a table_2 record.
Thanks for any help.
Relationships in Eloquent only work in the directions that they are defined. If you want to be able to find Table2 based on the foreign key defined in Table1, you would add a relationship to the Table1 model only. You do not need to define relationships on both models in order to go one direction.
Given your table1 schema, you are actually using the inverse of a one-to-one relationship. table1 is considered a child of table2. Your relationship would look like this:
class Table1
{
public function table2()
{
return $this->belongsTo(\App\Table2::class);
}
}
As for setting the relationship, my recommendation is to simply apply the ID from table2 manually when creating the initial record:
`$table1->table2_id = $table2->id;`
If you're updating a Table1 record, you can use associate(). More info on that here in the docs. Note that this does require you to define the other side of the relationship on Table2. If you don't want to do that, just update the column manually when updating also.
Keep in mind that all of this is powered by Eloquent. Just because you're defining a column value manually instead of using a relationship helper method doesn't mean you're doing something ineffectively or incorrectly.
Is there any point in [the foreign key] line in the migration
This creates a foreign key constraint in the database software itself, and has nothing to do with Eloquent. Eloquent doesn't use or care if you have a foreign key defined. There are benefits to using foreign keys, though, and suggest you look into it further to determine if they're a good idea for your application.

laravel models fill additional field inside many-to-many table

I am a newbie at Laravel framework and trying to work me in.
I already understand how to generate N:M relationships and handle them inside the models. Now I am asking you how to fill an additional field inside the many to many tables?
For example:
Table Foo
Table User_Foo
user_id
foo_id
is_owner (bool)
Table User
Now I want to declare which of the foo users is the real owner.
In my opinion, the N:M Table has stored this information an not the Foo itself.
So how is it possible to declare those additional fields inside of my Foo and User model?
Retrieve additional fields you can with withPivot() method
return $this->belongsToMany('App\User')->withPivot('is_owner');
Fill you can with sync() or attach() methods.
Laravel relations doc
Laravel provides us with concept of pivotwhen defining N-M relationships. By default the table will have the both connected keys. But if you want to add extra fields in that bridge table.
$model->belongsToMany('Model')->withPivot('column1', 'column2');
In above case, your pivot table will have two additional columns and you can access these columns as:
$model->pivot->column1
$model->pivot->column2

How do I integrate inheritance technique when writing the database

I am trying to use inheritance for sake of re-usability and I have a base class named 'Partner' and two sub classes 'Lawyer' and 'Accountant' as below:
abstract class Partner{
}
class Lawyer extends Partner{
}
class Accountant extends Partner{
}
It's all good with the code, but I was wondering more when it comes to database, how do I store these information in db, should I have one table partners for both entities, or I should have separate tables for each entity, based on fact that these two differs from each other based on their attributes.
If I keep it in separated tables, and I have another table 'cases' which is related to partner:
cases: case_id, subject, description,partner_id.... My question is, how do I inner join entities based on user logged in, let say if he is laywer join lawyer table or vice versa, what if I keep adding more entities in future?
How would I do it in such a way that eventhou in future I add more Entities my db queries will not have to be changed again and again.
I can't say I favor the idea of combining lawyers and acct's into one table partners. My suggestion is to keep your db entities separate. So you will have three tables (lawyer, accountant, and cases) and cases will contain foreign keys from lawyer and accountant. Your inner joins will be simple in this case. You'll have two 1:1 relationships whereas using a partner table it will have to be 1:M relationship to get both the lawyer and the accountant - each being its own record within the Partners table. Plus don't forget all the useless NULLS you'll have since lawyers and accountants have their own specific attributes..eew!
Since you are going to use Lawyers and Accountants in the same context, I think it makes sense to use the same table.
You can simply create a partners table with the common properties, and create separate accountants and lawyers tables with a 1:1 relationship. This basically means these two tables don't get their own auto-incrementing primary key, but just a partner_id that is primary and refers to the id in the partner table.

Difference between HABTM relationship and 2 $belongsTo relationship with a third model

I'm creating a project management system which projects are assigned to users
What's the difference between creating a Model ProjectsUser and defining 2 $belongsTo relationship and defining HABTM relationships in both Project and User models? What would be the most correct way, though? And how do I save the data in the projects_users table?
From my experience, if you want to be able to save or delete rows only from the join table (the one with 2 IDs), then it is much more simple using three models associated through both a hasMany and a belongsTo association.
You can also retrieve data from the join table directly and do the queries you want much more easily
This is what CakePHP documentation says refering to HABTM and saving data:
However, in most cases it’s easier to make a model for the join table and setup hasMany, belongsTo associations as shown in example above instead of using HABTM association.
Here you can find more the full text:
http://book.cakephp.org/2.0/en/models/saving-your-data.html#what-to-do-when-habtm-becomes-complicated
I have used this method for a "reads" table (with post_id and user_id) as well as for subscriptions and similar kind of relationships.
The first way is called "hasAndBelongsToMany" [details here].
The second is called "hasMany through" [details here].
The second link relating to "hasMany through" has details and a lengthy explanation about when and why you would want to use it.
Not sure about the specifics of cakephp, but in general defining the relation model explicitly gives you more control over it, for instance if you wanted to do some validation or add callbacks on creation of this relationship.

Fuel PHP Orm, join

I have been playing with fuelphp lately and am trying something with the ORM.
Never used an ORM before so I think I don't understand very well.
My database consists of object types with multiple objects meta´s.
So I have three tables.
object_types which has multiple object_types_meta which is a join table to objects_meta_type
But I don't know how to convert this to the ORM. Can someone please point me in the correct direction?
I thought it would be:
object_types has many object_types_meta and then object_types_meta belongs to objects_types but what do I do with object_meta_type?
Thanks in advance!
It looks like you may be using a many to many relationship with object_types_meta being the in between table?
http://fuelphp.com/docs/packages/orm/relations/many_many.html
If the join table doesn't contain any extra columns except the two foreign keys, you should use a many-many relation, and use the join table as 'through' table.
If it does contain columns you need to access, you have to create a model for the join table too, and create two one-to-many relations from the join table to the two other models.

Categories