我有一个音乐流应用程序。该应用中有多首歌曲。每个用户可以将歌曲“保存”到他们的音乐库。
因此,基本模型“ song”具有song_id,title,songduration,artist,album之类的东西。
然后,有一个“ usersong”模型,其中包含许多行。每行只是一个user_id和一个song_id。当用户登录时,通过查询该表的user_id可以获取他们已保存的歌曲的列表。但是,我想获取song_id引用的完整“歌曲”行,而不必将信息存储在歌曲和用户歌曲中,也不必进行1000个单独的查询。
这里是“歌曲”迁移(为简单起见,简称:)
Schema::create('songs', function (Blueprint $table) {
$table->string('id', 32);
$table->string('title');
$table->float('length');
})
这是“用户歌曲”迁移:
Schema::create('usersongs', function (Blueprint $table) {
$table->integer('user_id')->unsigned(); // a koel reference
$table->string('song_id', 32);
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('song_id')->references('id')->on('songs')->onDelete('cascade');
});
这是上述模式的UserSong模型。使“ getByUserId”函数在单个查询中返回具有user_id的用户的所有“歌曲”的最佳方法是什么?
class UserSong extends Model
{
protected $guarded = [];
protected $table="usersongs";
public function getByUserId($user_id){
$this->where("user_id",$user_id)->get();
/// how do I get the song rows automatically in this function?
}
protected $fillable=["user_id","song_id"];
}
理想情况下,我会用另一个脚本来称呼它,
$songs=UserSong::getByUserId($someuserid);
答案 0 :(得分:2)
您可以使用范围和关系:
示例
//scope
public function scopeGetByUserId($query, $someuserid)
{
return $query->where('user_id', $someuserid);
}
//relationship
public function userSongs()
{
return $this->hasMany('App\Song', 'song_id');
}
使用:
$songs = UserSong::getByUserId($someuserid)->with('userSongs')->get();
答案 1 :(得分:1)
怎么使用Relationship Existence Query?
在您的歌曲模型中,您应该定义与用户的关系。
class Song extends Model
{
public function users()
{
return $this->belongsToMany(User::class)->using(UserSong::class);
}
}
然后,在您的控制器中,您可以编写:
MyAwesomeController
Song::whereHas('users', function ($query) use ($yourUserId) {
$query->where('id', $yourUserId);
})->get();
在那里,您将获得链接到您的用户的歌曲集。
顺便说一句,您的UserSong
应该扩展Illuminate\Database\Eloquent\Relations\Pivot
而不是Model
。
有关更多说明,您可以看一下Laravel的Many to Many Documentation
答案 2 :(得分:-1)
您可以使用它轻松快捷地加入