簡體   English   中英

Laravel通過hasOne獲取屬性

[英]Laravel going through hasOne to get attributes

我有以下型號。

  • Player
    • ( hasMany(Monster::class) )
  • Monster
    • hasOne(MonsterSpecies::class,'id','species_id')
    • hasOne(MonsterColor::class,'id','color_id') )
  • MonsterSpecies
  • MonsterColor
    • (兩者幾乎都是空的,只是public $timestamps = false;

然后,播種后,在php artisan tinker I select 一名玩家:

$player = Player::all()->first();

有用。 然后我檢查怪物。

Illuminate\Database\Eloquent\Collection {#3561
     all: [
       App\Models\Monster {#3569
         id: 1,
         created_at: "2021-12-09 16:39:29",
         updated_at: "2021-12-09 16:39:29",
         name: "Alberto Mills",
         level: 17,
         currHealth: 68,
         maxHealth: 76,
         strength: 42,
         defense: 29,
         movement: 13,
         species: 28,
         color: 34,
         player_id: 1,
       },
       App\Models\Monster {#4505
         id: 2,
         created_at: "2021-12-09 16:39:29",
         updated_at: "2021-12-09 16:39:29",
         name: "Darlene Price",
         level: 9,
         currHealth: 16,
         maxHealth: 32,
         strength: 44,
         defense: 19,
         movement: 61,
         species: 28,
         color: 34,
         player_id: 1,
       },
     ],
   }

然后$player->monster->get(0)->color;

 App\Models\MonsterColor {#4508
     id: 34,
     name: "Red_Blue",
   }

現在我相信我可以添加getSpeciesAttribute()getSpeciesAttribute()來直接返回名稱,或者可能執行以下操作:

public function getSpeciesAttribute($value)
{
    $colors = explode("_",$value->name); // I don't know if this is how I get the name
    $out = "Your monster's color is ";
    if (count($colors) > 1) {
        $out .= "a mesh of " . implode(", ",array_slice($colors, 0, -1)) . " and ";
    }
    $out .= array_pop($colors);
    return $out;
}

但我不知道如何訪問MonsterColorname屬性。

編輯:

這是 Monster、MonsterColor 和 MonsterSpecies 模型。

class Monster extends Model
{
    use HasFactory;

    protected $fillable = [
        'name',
        'level',
        'currHealth',
        'maxHealth',
        'strength',
        'defense',
        'movement',
        'species',
        'color'
    ];

    public function player()
    {
       return $this->belongsTo(Player::class);
    }

    public function species()
    {
       return $this->hasOne(MonsterSpecies::class,'id','species_id');
    }

    public function color()
    {
        return $this->hasOne(MonsterColor::class,'id','color_id');
    }

    public function getSpeciesAttribute()
    {
        return $this->species->name;
    }

    public function getColorAttribute()
    {
        return $this->color->name;
    }
}

class MonsterColor extends Model
{
    use HasFactory;

    public $timestamps = false;
}

class MonsterSpecies extends Model
{
    use HasFactory;

    public $timestamps = false;
}

訪問器getColorAttribute()在 model class 上創建“虛擬” color屬性。 但是您也有一個名為color()的關系方法。 關系方法還創建虛擬屬性,您嘗試使用$this->color訪問這些屬性。

所以問題只是名稱沖突之一。 最簡單的解決方案是將訪問器重命名為其他名稱。

問題與您的其他訪問器相同,而且它們不接受參數; 它們作為屬性訪問,因此無法傳遞一個。

public function getColorNameAttribute()
{
    return $this->color->name;
}

public function getSpeciesDescriptionAttribute()
{
    $colors = explode("_", $this->color->name);
    return sprintf(
        "Your monster's color is %s",
        implode(" and ", $colors)
    );
}

現在您可以通過$player->monsters[0]->color_name$player->monsters[0]->species_description訪問這些。


其他幾點注意事項:

  • 你不應該在$fillable中有colorspecies ,因為它們不是數據庫列
  • 你不需要在關系方法中聲明列名(例如$this->hasOne(MonsterColor::class,'id','color_id') ),除非它們是非標准的——你的不是
  • 如果一個關系返回一個集合,它應該用復數命名(即不是你的問題中的$player->monster
  • 一定要研究一下關系的急切加載

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM