Hi am trying to use a many to many relationship but I cannot see what im doing wrong. This:
$meeting = new Meeting();
$meeting->attach($user);
causes: BadMethodCallException: Call to undefined method App\Models\Meeting::attach()
User model
public function meetings(): BelongsToMany
{
return $this->belongsToMany(Meeting::class);
}
Meeting Model
public function users(): BelongsToMany
{
return $this->belongsToMany(User::class);
}
Migration
Schema::create('meeting_user', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('meeting_id');
$table->unsignedBigInteger('user_id');
$table->timestamps();
});
Attach is called in the relationship, not in the model. You should use it like this:
$meeting->users()->attach($user);
Take a look at https://laravel.com/docs/7.x/eloquent-relationships#updating-many-to-many-relationships.
You have to use like this
$meeting->users()->attach($request->user); // user may have input field name
Related
I'm making a forum with Laravel 8. And I want to return a question and show the name of the user who has asked this question.
At the Model User.php I coded this:
public function questions()
{
return $this->hasMany(Question::class);
}
And also I put this at Question.php Model:
public function users()
{
return $this->belongsTo(User::class);
}
So in order to get the name of a user who has asked the question, I put this:
{{ $show->users->name }}
But now I get this error message:
Trying to get property 'name' of non-object**
So what's going wrong here? How can I fix this issue?
Note that this $show variable comes from this Controller Method and gets the question information:
public function showQuestion($slug)
{
$show = Question::where('slug', $slug)->first();
if(is_null($show)){
abort(404);
}
return view('questions.question',[
'show' => $show
]);
}
And also each question has stored the user_id of the user who has asked this question:
So if you have any idea or suggestion on this, please let me know, I would really appreciate that!
Update #1:
Here is the table users:
Update #2:
questions table migration:
Schema::create('questions', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->string('title');
$table->string('slug');
$table->text('body');
$table->string('category');
$table->string('private')->nullable();
$table->timestamps();
});
users table migration:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('phone')->unique();
$table->binary('image')->nullable();
$table->string('job')->nullable();
$table->string('location')->nullable();
$table->string('bio')->nullable();
$table->string('skills')->nullable();
$table->string('stackoverflow')->nullable();
$table->string('github')->nullable();
$table->string('instagram')->nullable();
$table->string('linkedin')->nullable();
$table->string('website')->nullable();
$table->rememberToken();
$table->timestamps();
});
}
Your relationship on Question to User should be named user instead of users. When you are letting Eloquent automatically figure out the fields for the belongsTo relationship it actually uses the name of the relationship method to help determine what the foreign key is.
If you don't want to follow that type of convention with naming the method like that you can explicitly set the foreign key used by the belongsTo method:
public function belongsTo($related, $foreignKey = null, $ownerKey = null, $relation = null)
You have to change the function name users to user in Question model. when you are letting Eloquent automatically figure out the relationship you have to name the function regarding to their relationships like one to one or one to many or many to many.
Try this
public function user()
{
return $this->belongsTo(User::class);
}
{{ $show->user->name }}
Use this for show function in controller
$student= Student::all();
return view('showData',['data' => $student]);
and for view to show data
#foreach($data as $stud)
<tr>
<td>{{$stud)->id}}</td>
<td>{{$stud)->name}}</td>
</tr>
#endforeach
return $this->belongsTo(User::class);
switch to like this, I switched to hasOne and it worked well
return $this->hasOne(User::class, 'id', 'user_id')
->withDefault(['name' => '']);
Sorry for bad English at first )
I'm new to laravel5 and trying to use polymorphic relations
here is the code
class Post extends Model
{
public function seo()
{
return $this->MorphMany('App\Seo' , 'seoable');
}
}
class Seo extends Model
{
public function seoble()
{
return $this->morphTo();
}
}
and in the view I try to retrieve post seo data like this
$post->seo()->title;
here is my DB
Schema::create('seos', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->text('keywords');
$table->text('description');
$table->string('og_type');
$table->string('og_title');
$table->text('og_description');
$table->integer('seoable_id');
$table->string('seoable_type');
$table->timestamps();
});
but I got the error
Undefined property:
Illuminate\Database\Eloquent\Relations\MorphMany::$title (View: /Applications/MAMP/htdocs/lblog/resources/views/posts/form.blade.php)
Try this:
$post->seo->first()->title; or $post->seo()->get()->first()->title;
the reason why it doesn't work because the the seo() function until now is just a query, you need to execute that query like above
I am looking for a solution for storing comments in the database, but it is not difficult at all:
In one table wants to write comments from several modules on the website.
I am currently creating a table using code 'comments table':
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->integer('module_id')->unsigned();
$table->integer('parent_id')->unsigned();
$table->text('body');
$table->timestamps();
});
}
Comments modules table:
public function up()
{
//
Schema::create('comment_module',function (Blueprint $table){
$table->increments('id');
$table->string('title',190);
$table->string('name',190)->unique();
$table->text('body');
$table->timestamps();
});
}
for now everything is okay, but i have problem with select all comments for each blog post,gallery, etc..
blog, gallery - name of modules.
code for Map.php model
public function comments(){
return $this->hasMany(Comment::class,'module_id');
}
CommentModule.php model
public function comments(){
return $this->hasMany(Comment::class,'module_id');
}
Comment.php
public function module(){
return $this->belongsTo(CommentModule::class);
}
and now how to pass a 'mmodule_id' ?
normal use with any relationships for one table will be like that:
$map->comments->body . . etc.
but for that construction don`t work, yes of course i can use raw query and use join, right ?
Is any option to use a Eloquent?
IMHO for what I understood you want to attach comments to more than one Eloquent Model. There is a clean example in the laravel docs with Polymorphic Relations
As summary you have to add two fields on the comments table: commentable_id(integer) and commentable_type (string).
After that you declare the relation on the Comment model:
public function commentable()
{
return $this->morphTo();
}
And you can use the comments() relation in each model you want to attach comments, i.e.:
class Post extends Model
{
public function comments()
{
return $this->morphMany('App\Comment', 'commentable');
}
class Map extends Model
{
public function comments()
{
return $this->morphMany('App\Comment', 'commentable');
}
Now you can retrieve comments as usual:
$post->comments;
To attach a new comment to a parent:
$post->comments()->create([array of comment attributes]);
I have the following relations set up:
public function notes()
{
return $this->belongsToMany(Note::class);
}
public function tags()
{
return $this->belongsToMany(Tag::class);
}
and pivot table like this:
Schema::create('note_tag', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->integer('note_id')->unsigned()->index();
$table->foreign('note_id')->references('id')->on('tags')->onDelete('cascade')->onUpdate('cascade');
$table->integer('tag_id')->unsigned()->index();
$table->foreign('tag_id')->references('id')->on('notes')->onDelete('cascade')->onUpdate('cascade');
});
now, i used Attach() method:
$note->tags()->attach($tagsIds);
but that doesn't work and I get this error:
[Symfony\Component\Debug\Exception\FatalErrorException]
Cannot instantiate interface phpDocumentor\Reflection\DocBlock\Tag
Looks like you've imported the wrong class that corresponds to Tag::class.
It should probably be something like this:
use App\Tag;
instead of:
use phpDocumentor\Reflection\DocBlock\Tag;
I'm trying to redirect users that go to blog/{id} to blog/{slug} with the slug being the slug of the id they entered.
What I am doing is not working. I dd{$article->slug} and get the correct string, yet when I try to redirect I get "Trying to get property of non-object" error.
I'm using route/model binding. This is my RouteServiceProvider:
$router->bind('blog', function($slug)
{
if ($slug) {
if(is_numeric($slug)) {
$article = Article::findOrFail($slug);
return redirect('blog/' . $article->slug);
}
return Article::with('images')->where('slug', $slug)->first();
}
});
This is my show method in controller:
public function show(Article $article)
{
return view('blog.show', compact('article'));
}
Any ideas would be greatly appreciated!
articles migration file:
class CreateArticlesTable extends Migration
{
public function up()
{
Schema::create('articles', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->string('title');
$table->string('slug');
$table->text('body');
$table->timestamps();
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
});
}
public function down()
{
Schema::drop('articles');
}
}
Your controller is expecting an instance of Article. So, if you're returning a RedirectResponse from your closure, it won't work.
At the moment, I can only think of 2 ways of achieving what you want with route-model binding.
The first method is simpler. Just don't type-hint the Article. Instead, check if it's a RedirectResponse. If so, return it. If not, return the view. Something like this:
public function show($article)
{
if ($article instanceof \Illuminate\Http\RedirectResponse)
{
return $article;
}
return view('blog.show', compact('article'));
}
You could also check if it's an instance of an Article just to be absolutely certain since you're no longer type-hinting.
The second method is overly complex in my opinion for a simple check. You would have to throw a custom exception, catch it from within app/Exceptions/Handler.php, and then redirect from there.