سلام دوستان من دوتا جدول دارم یوزر و پروفایل
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('username')->nullable();
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
Schema::create('profiles', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->string('fname');
$table->string('lname');
$table->string('mobile')->nullable();
$table->enum('gender' , User::$genders)->nullable();
$table->string('avatar')->nullable();
$table->text('address')->nullable();
$table->text('post_code')->nullable();
$table->longText('description')->nullable();
$table->foreign('user_id')->references('id')->on('users')->onDelete('CASCADE');
$table->timestamps();
});
روابطشون هم به این شکل هست
class User extends Authenticatable implements MustVerifyEmail
{
public function profile()
{
return $this->hasOne(Profile::class);
}
}
class Profile extends Model
{
protected $guarded = [];
public function user()
{
return $this->belongsTo(User::class);
}
}
به این صورت هم عکس کاربر رو از دیتابیس واکشی میکنم با استفاده از ریلیشن دوتا مدل
<img src="{{'/storage/' . auth()->user()->profile->avatar}}" class="rounded-circle mCS_img_loaded">
مشکلم اینه وقتی کاربری که لاگین میکنه و عکس پروفایلی از قبل برا خودش ست نکرده ارور Trying to get property 'avatar' of non-object
رو میده چجوری میتونم کاری کنم که اگر کاربر عکسی از قبل نداشت ارور ابجکت رو نگیره و یه عکس پیشفرض براش ست بشه
ممنون میشم اگر کسی بتونه کمک کنه به رفع این مشکل
خوب خیلی راحت کافیه یک شرط بزاری قبلش که دو مورد رو چک کنه یا حتی یک تابع درست کنی توی خود یوزر که کل این کارها توی اون انجام بشه و ویو شما شلوغ نشه
1- چک کنه ببینه مقداری برای عکس پروفایل ست شده یا نه حالا خالی باشه یا نال باشه
2- چک کنه ببینه اگر خالی نیست آیا فایلش موجود هست یا نه
if(!empty(user()->avatar)){
if(File::exist('/storage/'.user()->avatar)){
return '/storage/'.user()->avatar;
}else{
return 'df-avatar';
}
}else{
return 'df-avatar';
}
@Alitavil
این قطعه کد رو توی مدل یوزر بنویسیم؟
والا خودم توی مدل یوزر اینو نوشتم کار نکرد
public function getAvatarAttribute(){
if(!is_null($this->profile->avatar)){
return '/storage/' . $this->profile->avatar;
}else{
return 'test.jpg';
}
}
@mehrdadroshanraee68
سلام .
روشی که میخواید روش خوبی هست و اصطلاحا accessor نامیده میشه . به اینصورت که هربار یک فیلدی از دیتابیس صدا میزنید تا مقدارش رو دریافت کنید یک عملیاتی روش انجام میشه و بعد مقدار تغییر یافته به شما برگشت داده میشه . منتها باید Accessor رو در مدلی که میخواید فیلدی از دیتابیسش موقع واکشی اطلاعات تغییر پیدا کنه استفاده کنید. در مثالتون باید در مدل Profile این اکسسور رو تعریف کنید :
public function getAvatarAttribute($picture)
{
return $picture ?? 'default-image.jpg;
}
@SobhanDadkhah
اقای دادخواه من به یکی دو روش اکسسور تعریف کردم نمیشه نمیدونم چرا اخر سر لینک عکسارو مجبور شدم علی الحساب برای رفع ارور این مدلی بگم
optional(auth()->user()->profile)->avatar
با درود
در ابتدا پیشنهاد میکنم برای ادرس دهی همیشه از asset استفاده کنید و به وسیله دستور شرط چک کنید که کاربر آیا تصویر پروفایلی ست کرده یا خیر و کد به صورت زیر بنویسید
<img src="{{auth()->user()->profile->avatar?asset('storage/'.auth()->user()->profile->avatar:'defult avatar') }}" class="rounded-circle mCS_img_loaded">
و خطای Trying to get property 'avatar' of non- بدین منظور رخ میدهد که شما فیلد را از نوع nullable تعریف کردی درون مایگریشن و اگر کاربر تصویر پروفایل ست نکند خطای Trying to get property 'avatar' of non- را مشاهده خواهید کرد پس بهتر است
درون دیتابیس درون ماگیرشن در هنگام تعریف فیلد های خود مقدار دیفالت قرار دهید مانند کد زیر
$table->string('avatar')->default('default avatar');
بدین روش در صورتی که کاربر پروفایلی هم ست نکند یه تصویر پیش فرض اعمال خواهد شد
با تشکر
حسین افتخارراد
@mehrdadroshanraee68 ببينيد اكسسور در واقع يك ميانجي بين ديتابيس و شما . يعني با ست كردن اكسسور اطلاعات از ديتابيس خوانده ميشه ، در بين راه توي اكسسور مربوطه همون فيلدي كه تعريف شده در مثال شما "avatar" چك ميشه و بعد اطلاعات در دسترس قرار ميگيره. آيا فيلد ديتابيستون كه آدرس عكس رو ذخيره ميكنيد اسمش avatar هست؟
شما بعد از اينكه اكسسور رو تعريف ميكنيد ، داخل يكي از كنترلر ها يكي از يوزر هارو انتخاب كنيد و روي اون يوزر avatar رو صدا بزنيد . با die dump چك كنيد ببينيد چي دريافت ميكنيد ؟
$user = User::find(1);
dd($user->avatar);
آیا مایل به ارسال نوتیفیکیشن و اخبار از طرف راکت هستید ؟