Laravel 如何访问与where条件有很多关系的模型?
我使用关系的条件/约束创建了一个模型游戏,如下所示:Laravel 如何访问与where条件有很多关系的模型?,laravel,laravel-4,eloquent,Laravel,Laravel 4,Eloquent,我使用关系的条件/约束创建了一个模型游戏,如下所示: 类游戏扩展了口才{ //这里还有很多东西 //没有任何约束的关系…工作正常 公共活动视频(){ 返回$this->hasMany('Video'); } //导致“问题”,请参见下面的示例 公共功能可用\u视频(){ 返回$this->hasMany('Video')->where('available','=',1); } } 当以这样的方式使用它时: $game=game::with('available_videos')->查找(1)
类游戏扩展了口才{
//这里还有很多东西
//没有任何约束的关系…工作正常
公共活动视频(){
返回$this->hasMany('Video');
}
//导致“问题”,请参见下面的示例
公共功能可用\u视频(){
返回$this->hasMany('Video')->where('available','=',1);
}
}
当以这样的方式使用它时:
$game=game::with('available_videos')->查找(1);
$game->available_videos->count();
一切正常,因为角色是最终的集合
我的问题:
当我试图访问它而不急于加载时
$game=game::find(1);
$game->available_videos->count();
抛出一个异常,因为它表示“调用非对象上的成员函数count()”
使用
$game=game::find(1);
$game->load(“可用的_视频”);
$game->available_videos->count();
工作正常,但对我来说似乎相当复杂,因为如果不在关系中使用条件,我不需要加载相关模型
我错过什么了吗?我如何确保无需使用即时加载即可访问可用的_视频
对于任何感兴趣的人,我也在上发布了这个问题。我认为这是正确的方式:
class Game extends Eloquent {
// many more stuff here
// relation without any constraints ...works fine
public function videos() {
return $this->hasMany('Video');
}
// results in a "problem", se examples below
public function available_videos() {
return $this->videos()->where('available','=', 1);
}
}
然后你就必须
$game = Game::find(1);
var_dump( $game->available_videos()->get() );
以防其他人遇到同样的问题 请注意,关系必须是完全一致的。因此,在我的例子中,available_videos()应该是available videos() 您可以通过调查Laravel源轻松找到:
// Illuminate\Database\Eloquent\Model.php
...
/**
* Get an attribute from the model.
*
* @param string $key
* @return mixed
*/
public function getAttribute($key)
{
$inAttributes = array_key_exists($key, $this->attributes);
// If the key references an attribute, we can just go ahead and return the
// plain attribute value from the model. This allows every attribute to
// be dynamically accessed through the _get method without accessors.
if ($inAttributes || $this->hasGetMutator($key))
{
return $this->getAttributeValue($key);
}
// If the key already exists in the relationships array, it just means the
// relationship has already been loaded, so we'll just return it out of
// here because there is no need to query within the relations twice.
if (array_key_exists($key, $this->relations))
{
return $this->relations[$key];
}
// If the "attribute" exists as a method on the model, we will just assume
// it is a relationship and will load and return results from the query
// and hydrate the relationship's value on the "relationships" array.
$camelKey = camel_case($key);
if (method_exists($this, $camelKey))
{
return $this->getRelationshipFromMethod($key, $camelKey);
}
}
这也解释了我的代码在以前使用load()方法加载数据时工作的原因
无论如何,我的示例现在运行得非常好,$model->availableVideos总是返回一个集合。我认为这就是您要寻找的(Laravel 4,请参阅)
//对于v4某些版本,请降低
public function videos() {
$instance =$this->hasMany('Video');
$instance->getQuery()->where('available','=', 1);
return $instance
}
//v5
如果要对关系表应用条件,还可以使用其他解决方案。。这个解决方案在我这边起作用
public static function getAllAvailableVideos() {
$result = self::with(['videos' => function($q) {
$q->select('id', 'name');
$q->where('available', '=', 1);
}])
->get();
return $result;
}
模型(App\Post.php):
控制器(App\Http\Controllers\PostController.php):
刀片模板(posts.Blade.php):
通过将关联数组作为
Builder::with
方法中的第一个参数传递,我解决了类似的问题
假设您希望通过一些动态参数包含子关系,但不希望筛选父结果
Model.php
公共函数子项()
{
返回$this->hasMany(ChildModel::class);
}
然后,在另一个地方,当您的逻辑被放置时,您可以通过HasMany
类过滤关系。例如(与我的情况非常相似):
$search='Some search string';
$result=Model::query()->with(
[
'child'=>函数(有许多$query)使用($search){
$query->where('name','like',“%{$search}%”);
}
]
);
然后,您将过滤所有子结果,但父模型不会过滤。
感谢您的关注。在laravel中实现基于角色的用户管理的最佳方法是使用sentry软件包。所以试一下。正如我在上面的描述中所说,模型名称只是一个例子,我的问题与用户管理无关。我将编辑我的问题并发布我的真实wordl示例。感谢您的回复,您的示例非常有效,但在调用$game->available\u videos()->get()时,我的示例也非常有效。关键是,我想使用$game->available\u videos,因为我也可以使用$game->videos而不会遇到麻烦。据我所知,如果之前没有加载,Elount应该加载相关模型,还是我错了?将函数名更新为
availableVideos
。如果您只需要这些视频来返回可用的视频,您可以这样做:return$this->hasMany('Video')->where('available','=',1)代码>不,这绝对不是原因。您应该始终使用带下划线的函数名。
,因为在MVC中,应该始终有一个类似/controller/function\u name
的URL结构。如果您没有为函数设置正确的路由,您将在URL中获得驼峰大小写的函数名,这不利于SEO。@Vinet抱歉,不是。MVC与URL结构无关。php文件定义了从url到控制器的映射。更不用说这是在模型中,而不是在控制器中。它与URL绝对没有对应关系。好主意,但这是一样的,因为Relation在查询生成器上为您调用该方法是的,现在不需要调用getQuery。v5需要较低的版本,您可以这样做:return$this->hasMany('Video')->where('available','=',1)代码>为了让它更干净,这些设施突然从哪里来?这和答案还不太接近。你能解释一下你的答案吗?
public function outletAmenities()
{
return $this->hasMany(OutletAmenities::class,'outlet_id','id')
->join('amenity_master','amenity_icon_url','=','image_url')
->where('amenity_master.status',1)
->where('outlet_amenities.status',1);
}
public static function getAllAvailableVideos() {
$result = self::with(['videos' => function($q) {
$q->select('id', 'name');
$q->where('available', '=', 1);
}])
->get();
return $result;
}
/**
* Get all comments for this post.
*/
public function comments($published = false)
{
$comments = $this->hasMany('App\Comment');
if($published) $comments->where('published', 1);
return $comments;
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function post($id)
{
$post = Post::with('comments')
->find($id);
return view('posts')->with('post', $post);
}
{{-- Get all comments--}}
@foreach ($post->comments as $comment)
code...
@endforeach
{{-- Get only published comments--}}
@foreach ($post->comments(true)->get() as $comment)
code...
@endforeach
public function outletAmenities()
{
return $this->hasMany(OutletAmenities::class,'outlet_id','id')
->join('amenity_master','amenity_icon_url','=','image_url')
->where('amenity_master.status',1)
->where('outlet_amenities.status',1);
}