Yii2 activeDropDownList fundamentals - yii2

I'm new to Yii2 but not to MVC (trying to move my focus from MS to Yii2). I've scaffolded up an app from my DB using gii. I have a table called track I have a table called music_category. There's a n:n relationship via a link table called track_has_music_category. My track model (as scaffolded by gii) has a function
public function getMusicCategories()
{
return $this->hasMany(MusicCategory::className(), ['id' => 'music_category_id'])->viaTable('track_has_music_category', ['track_id' => 'id']);
}
But that is for retrieving the categories that have been 'link'ed to this track. So I guess I need something like
<?= Html::activeDropDownList(theCategoryModel (syntax here??), 'id', ArrayHelper::map(theCategoryModel->findAll(),'id', ''description)) ?>
Well, something like that. I feel as though the online reference could do with a few worked examples.
Any help much appreciated.
Cheers
Mark

Let's say we want to attach some categories to a track model ($model):
echo Html::activeCheckboxList($model, 'musicCategories', ArrayHelper::map(MusicCategory::findAll(),'id', ''description))
We use activeCheckboxList here since it's a multiple relation.
Although you will need to add extra $model logic to save these relations.
Have a look at this How do I work with many-to-many relations in Yii2

Related

Laravel Get Data From Relation Table

I'm building a project with Laravel 7.28. I have three tables named; projects, tags and project_tags. in project_tags table there is project_ids and tag_ids. It looks like this:
I need to get all projects with their tag and secondly I need to get projects with certain tag. So What should I do in models? Which function and how should I use? And how can I get data?
I discovered rtconner/laravel-tagging package but is it the correct way to do it? Thanks for your help
You might want to create a many to many relationship between projects and tags.
class Project extends Model
{
public function tags()
{
return $this->belongsToMany(Tag::class, 'project_tags')->withTimestamps();
}
}
Then:
// Get all projects with their tags.
Project::with('tags')->get();
// Get projects contain certain a certain tag.
Project::whereHas('tags', function ($query) {
return $query->where('tag', 'some value');
})
In addition, tags tend to be a polymorphic many to many relationships. So if you want to manually handle tagging in the long term, I suggest designing that way.
Also, checkout spatie/laravel-tags package.

How to show only a specific amount of data on a table

I made a column to my 'users' table called 'approved' which is boolean where 1=true and 0=false. What I want to do in my view is that I only want to show the data of the user with the 0/false value. What are the steps I need to make to achieve this? I'm really new to Laravel or rather at Web Development in general.
$datas=User::where('approved','0')->get();
Now in your blade use ......
#foreach($datas as $data)
#endforeach
There are so many ways to do it. First is you can directly use where clause for it like this one.
User::where('approved', 0)->get();
Second is to use local scope. In your model you will put this one.
public function scopeApprovedUser($query) {
return $query->where('approved', 0);
}
and call it to your controller like this.
User::approveduser();

Clone data from one to another database column in Laravel

I have two columns quantity and remaining_quantity in my stock table. I wanted to copy same data from quantity to remaining_quantity while doing a create function. Is there any function in Laravel for that?
You can do that by creating an observer.
1- Create a folder called observers in you app folder.
2- Create a file named MyModelObserver.php for example StockObserver.php.
3- Prepare your class like the following:
<?php
namespace App\Observers;
class StockObserver
{
//
}
Inside that class you can create creating, created, updated, updated, deleting, deleted, saving and saved methods. Which their jobs are obvious from their names.
For more details see => https://laravel.com/docs/5.5/eloquent#events
For example the following code will do something everytime an object of Stock model is created.
<?php
namespace App\Observers;
use App\Stock;
class StockObserver
{
public function created(Stock $stock)
{
$stock->remaining_quantity = $stock->quantity;
$stock->save()
}
}
But all these code won't be effective unless you observe that in the AppServiceProvide .. so in the boot method in AppServiceProvider write the following.
\App\Stock::observe(\App\Observers\StockObserver::class);
That's it .. Hope it helps.
Yes, a few different ways to do that. An easy, dirty way would be to just have two queries,
$quantity = StockTable::find($id);
StockTable::create([
'remaining_quantity' => $quantity->quantity
]);
So you grab the record you want to copy a bit of, and then set it as the remaining quantity on your creating record.

MySQL database structure advice needed. Two many-to-many from one table to two other that are in one-to-many relation

I have this setup as my database structure which already works pretty well, but I feel like it could be better, but cannot figure out how.
Database Structure:-
Events can have multiple sub-events. Users can join these events and optionally their sub-events. With this structure I have all constraints, but the one that links the event attending with the sub event attendings => there can be sub event attendings left without having the main event attending (this shouldn't be possible as users who don't attend the main event cannot attend it's sub events).
I am currently working with Laravel so it looks like this:
User:
hasMany Event (as organizer of these events)
belongsToMany EventAttending (which events is a user joining)
belongsToMany SubEventAttending (which sub-events is a user joining)
Event:
belongsTo User
hasMany SubEvent
belongsToMany EventAttending (which users are attending this event)
SubEvent:
belongsTo Event
belongsToMany SubEventAttending (which users are attending this sub-event)
The problem arises when trying to manage the sub-event attendings of a user. How would I make this constraint between the event and sub-event attendings exist, while keeping it clean with the capabilities of Laravel / What can you give as advice for a better structuring / How would you guys do it?
Edit
To clarify, the events and sub-events store different things, have different properties. Also I need to store information for the event attendings (like did he attend in real life) and sub-event attendings, most likely differing ones.
Edit
Edward Haber has the better structure, but as my two pivot tables (the connection between User-Event and User-SubEvent) store additional diferent type of information, currently chose to remain with the initial design.
One of the biggest problems I am facing (which does exist with both structure) is querying for a User while getting the attended Events with the attended SubEvents. Trying to achive this result:
User[]:{
...,
attending_events[]:{
...,
attending_sub_events[]:{
...
}
}
}
Been thinking for hours for a clean solution, couldn't get anything else to work. Wouldn't like to write the whole SQL query manually. My current implementation with the two pivot table looks like this (result not nested, code messy):
$users = User::withCount(['attendingEvents' => function($query) use($eventId){
$query->where('event_id', $eventId);
}])
->with(['attendingSubEvents' => function($query) use($eventId){
$query->select('id')->whereHas('event', function($query) use($eventId){
$query->where('id', $eventId);
});
}]);
With this approach I get the sub-events separated from the main event. (querying only for the main attending-event count, because I only need to determine whether he is joining or not).
The pattern for this type of solution is to use a Polymorphic Relationship. This solution focuses just on connecting the User to the Event and SubEvent - the rest of the relations look correct.
<?php
class User extends Model {
public function attending() {
return $this->morphTo();
}
}
<?php
class Event extends Model {
public function attendees() {
return $this->morphMany('App\User', 'attending')
}
}
<?php
class Subevent extends Model {
public function attendees() {
return $this->morphMany('App\User', 'attending')
}
}
The users table needs these fields:
*users*
-----
id
attending_id
attending_type
This is all untested - but the basic idea. (Edited: changed name of polymorphic method to attending from attendee)

Kohana ORM store count in many-to-many relationship

I'm building a application using Kohana 3.2 and Kohana ORM.
The application has systems. Systems contain components. A system may contain multiple components, but also multiple components of the same type. E.g. System_A may have 10 Component_Y and 3 Component_Z
So instead of just having two belongs_to fields in my pivot table I also want to store the count.
If I just use a has-many-through I won't be able to access the count. Without ORM I'd just join the count onto the component in SQL, because the count is unique for the System + Component combination and so I can access the count for the component when I visit the object in the context of a certain system.
How best to go about this in Kohana ORM?
I solved it partially this way:
protected $_has_many = array(
'omvormer' => array(
'model' => 'omvormer',
'through' => 'systeemomvormer'
),
'systeemomvormer' => array(
'model' => 'systeemomvormer',
)
);
I've added the pivot tabel systeemomvormer separately to systeem.
I can now do this:
$so = ORM::factory("systeemomvormer");
$so->where('systeem_id', '=', $systeem_id);
$so->where('omvormer_id', '=', $omvormer_id);
$result = $so->find();
$result->aantal = $omvormer_count;
But it really still only is a partial solution, because I'm not able to update() the result. Kohana says that the result is not loaded. However that's outside the scope of this question and I'll open a new question for that.
This was also helpfull:
http://forum.kohanaframework.org/discussion/7247/kohana-3-orm-save-for-update-a-many-to-many/p1
To store more data in a junction table than just the two keys, you need to create a model for it.
So,
system _has_many system_component
component _has_many system_component
system_component _belongs_to component
system_component _belongs_to system
However, you may not need to store the count if you do it this way. Instead, you can do the following:
$system->components->count_all();
Then, to access them:
foreach($system->components->find_all() as $component)
echo $component->component->name;