Laravel Foreach Repeating in View - laravel

So, I have a form that has multiple text inputs. When the user posts info using these inputs it's put into my model with the user's ID, a "type ID", and the input from the user. So I'll end up with something like this in the database.
ID User_ID Type_ID Type_Details
1 1 1 yada
2 1 1 foo
3 1 1 bar
In my view I do this.
#foreach ($user->UserType as $type)
What happens is that in the view I then get the output 3 times, since it sees "type_id" for user #1. For reference, this table shown is a pivot table joining the user model and the type model. I simply added another column to retrieve the type_details information.
Ultimately, since there is only one Type_id (1), I want to only show that type once with the "yada", "foo", "bar". Not 3 times.
Thanks!

Instead of using a foreach, you can group the types using Collections:
$types = $user->UserType->implode('Type_Details', ', ')->toArray();
Then you can display in your view as:
{{ $types }}

Related

Laravel Collection - put specific item on last position

I have database table with different roles and I need collection where items with role owner will be last. Here is database example:
ID
Role
1
admin
2
user
3
user
4
owner
5
user
How can I sort collection with those data to get item with role owner as last? I could only think of sorting it alphabetically, saving to some variable and deleting the record with the owner role from the collection, and then pasting it into the collection as last. But it seems unnecessarily complicated to me, isn't there an easier way?
The reason why I need this is because I need remove all selected users and to be sure that user/owner is the last one.
You Can Use Conditional rendering. For That you need to use DB::raw
Example:
Model::select('id', 'role')
->orderBy(DB::raw('role = "owner"'), 'ASC');
Or Use shorthand:
Model::select('id', 'role')->orderByRaw("role = 'owner' ASC");
It will place owners At the end.
Check Fiddle here: http://sqlfiddle.com/#!9/9d2b64/2
For eloquent, you can use sortBy() method with array_search() :
$collection = Model::get();
$data = $collection->sortBy(function($item){
return array_search($item->role, ['admin', 'user', 'owner']);
});

blade - foreach $loop->iteration

I've problem with some loops.
I have 2 tables Terms [id, caption, ...] and apps [id, term_id, name, ...]
And in my view i want print all apps orderred by term_id and then by name. But i want 1 table for each term_id used in apps. and i want 1st col with correct $loop->iteration (i mean each table first row start with 1, not with +1 from previous table last row)
in controller I've passing 2 variables to my views (i have different views for each appState_id value)
$app = Application::where('ApplicationState_id',3)->get();
$term = Terms::all();
return view('admin.index')->with('terms', $term)
->with('apps', $app);
in view i used foreach inside foreach / i rebuild it little bit
foreach terms as term
foreach apps as app
if $loop->first {<table><thead> ... table caption row ...}
checking if app->term_id = term->id
$loop->iteration, and some other stuff
if $loop->last {</table>}
endforeach
endforeach
but I want it improve little bit:
it write table's first/caption/ row for all term even there is no record in app table
$loop->iteration is combined per all records
i want it per each table separately-i dont know can i do it
How can i pass all data from controller to be able print them seprately to corespond table?
Is there a better way how to do this? thanks for advice/hint
---edited litle bit shortened
Application.php
class Application extends Model
{
protected $fillable = [
'nickname',
'comment',
'term_id',
'applicationstate_id',
];
public function term()
{
return $this->belongsTo('App\Term', 'Term_id');
}
}
Term.php - this model/table is meantime filled by me, but I want to change in future that user can add another terms of events
class Term extends Model
{
public function applications()
{
return $this->hasMany('App\Application');
}
}
I had idea that i can in controller:
check how many unique term_id is in Application table {n}
loop 1... {n}
inside loop read data from DB for each query/each term_id and add result to an array
send this array of results to view
and then try print it as {n} tables for each term_id
is this good idea how to solve this, or there is something much better?
table applications
data from applications table/few records/
ideal output on page
ideal output scheme
Can you paste two models in your application
Edit
In your application class change the foreign key for trem
public function term() {
return $this->belongsTo('App\Term', 'term_id');
}
In your controller
$app = Application::with('term')->where('applicationstate_id',3)->get();
return view('admin.index')->with('apps', $app);
In your admin/index.blade.php
#foreach($apps as $item )
$item->trem->your attributes trem
$item->nickname
#endforech
I did it this way:
check how many unique term_id is in Application table {n}
loop 1... {n}
inside loop read data from DB for each query/each term_id and add result to an array
then I send this array of results to view

How to remove and update data on relations table using laravel eloquent?

I have three tables. they are,
users
id name
1 personA
2 personB
3 personC
skills
id name
1 html
2 css
3 javascript
userskills
userid skills_id
2 3
2 1
1 2
1 3
I get the data through the request like [2,1] and the user id 2. On the user skills table in userid 2 there are skills_id3,1. Now i have to remove skills_id 3 and insert skills_id 2 on the userid 2.
How can i achieve it through laravel eloquent method.
As you have a pivot table you can use belongsToMany relationship. Adding the relationship in your User Model
public function skills()
{
return $this->belongsToMany(Skill::class, 'userskills','userid', 'skills_id');
//userskills is the pivot table
}
Now to update use the sync method.
$user = User::findOrFail(2); //your request id
$user->skills()->sync([1, 2]); //request array
This will remove the 3 from the pivot table and add 2 in the table.
Read more about this relationship in here
Your question is little ambiguous but lets assume that you are getting the user id 2 and the skills you want to remove from userskills is 2,1
For deleting
UserSkills::where(['userid' => 2 ])->whereIn('skills_id',[2,1])->delete();
For inserting
UserSkills::create(['skills_id' => 2, 'userid' => 2 ]);
An easier approach using relation would be
$user->skills()->sync([2, 1]);
Sync will remove those skills which are not present in the sync method.

Laravel: get Many-to-Many column data

Yo all,
I have a users relationship pivot db table as follows:
id | user_id | relation_id | relationship
1 4 2 tutor
1 4 3 parent
The table relates user with one-and-other for various reasons.
I am trying to get the relationship column within the $user. I have managed to pull the related users
details no problem - $user->relations.
However, I just need to get the relationship - eg. Tutor or parent.
I am getting no dice with $relative->pivot->relationship
Any ideas? Thanks for taking the time to help.
#foreach($user->relations as $index=>$relative)
{{ $relative->first_name . ' ' . $relative->last_name}}
{{ $relative->pivot->relationship }}
#endforeach
To access ->pivot->whatever you need to add withPivot('whatever') to the relation definition:
public function relations()
{
return $this->belongsToMany('Relation')->withPivot('relationship');
}
Note: I wouldn't use relations and Relation names here, since it's misleading AND it may collide with Eloquent\Model stuff.

Filtering resultset with codeigniter and datamapper

I got a little problem with datamapper, and I'd like to know if there is a quick solution.
Let's say I have this kind of data
Groups table
id | Name
1 | admin
2 | guest
3 | editor
4 | moderator
In my base controller I set a global field to see only the groups that are not admin
$this->groups_ = new Group();
$this->groups_->where('id >', 1)->get();
//so I can select the users that are not admin
$users = new User();
$users->where_related('group',$id,$this->groups_)->get();
Now in my controllers I'd like to filter the groups. For example I want to select only editors and guests (id between 1 and 4). So I would like to filter the initial result set... something like this
$this->groups_->where('id <',4)->get();
But it doesn't work. It returns ALL the group ids < 4 including admin.
What would be the right way to get this?
Well, datamapper does not query objects or groups of objects. It queries the database. So when you do the second get(), you're executing a separate query on the database.
You can do this, but it will be an additional query:
$this->groups_->where('id >', 1)->where('id <', 4)->get();
or you can loop through $this->groups_ after your first query in php and filter the set there and save as an array.
A possible solution
Maybe I found a possible workaround by cloning the datamapper object.
What I want to do is not to query the db multiple times, but I'd like to have a base resultset and refine the results.
So in my base controller I would do something like
$this->groups_ = new Group();
$this->groups_->where('id >', 1);//without getting the results
//so I can select the users that are not admin
$users = new User();
//here i'm getting the results from the clone
$users->where_related('group',$id,$this->groups_->get_clone()->get())->get();
And, as I left the object "open", without getting the results, I can use it in my controllers, as a base for my other "queries"... ok,they are actually new conditions of the first query.
//now the query return the groups between 2, as I set in the base controller
//and 4, set in the child controller
$this->groups_->where('id <',4)->get();

Resources