我正在创建一个新闻源系统,你很容易猜到,这超出了我的技能。
请善待我,让我走上正轨,或者提供一些我可以继续做的事情。
我有几百个事件(模型名称是 Event1,表“事件”)
我还有一个数据透视表,用户可以在其中分配任何事件的重要性(值 0、1、2、3)
数据透视表user_attitudes(Model Userattitude)的相关列是id
, item_type
, item_id
, importance
, attitude
, creator_id
一个例子三记录是:
456 - 事件 - 678 - 2 - 4
457 - 事件 - 690 - 3 - 15
458 - 事件 - 690 - 1 - 4
459 - 参与者 - 45 - 1 - 4
简单英语:事件#690 的总聚合重要性为“4”,而事件#678 的总聚合重要性为“2”。
因此,在我的排名中,#690 事件应该被列为第一。
只是为了查看更大的图片:用户 #4 还将参与者 #45 评为重要性 = 1。
该表为许多模型提供服务 - 上面的例子包括两个 - 只是为了更好地展示我所拥有的东西。
我需要的:
也许这样的事情会是一个答案:
$q->where('creator_id', '=', Auth::user()->id);
相关代码:
由于我并没有真正掌握合并的关系,我可能无法展示提供帮助所需的一切 - 在评论中要求更多代码。
楷模:
Event1(表“事件”):
public function importances()
{
return $this->morphMany('Userattitude', 'item');
}
public function user_importance($user)
{
return $this->morphMany('Userattitude', 'item')->where('creator_id', ($user ? $user->id : NULL))->first();
}
用户:(表 'users' - 标准用户表)
public function importances()
{
return $this->hasMany('Userattitude', 'creator_id');
}
在模型 Userattitude (不同于User,表名'user_attitudes')
public function events()
{
return $this->morphTo('item')->where('item_type', 'event');
}
public function event()
{
return $this->belongsTo ('Event1', 'item_id');
}
回复@lucas 的问题:
问题 1。
表名“项目”让我感到困惑,因为在我的项目中,“项目”是事件(模型 Event1)、参与者(模型实体)和其他对象。
在我掌握你提供的知识之前,我们可以坚持我的名字吗?
它还包含名为 态度 的列,用于将特定项目列入黑名单。
例如,“实体”类型的项目(多个事件的可能参与者)可以由用户进行两轮投票:
- 由用户设置的重要性(我们现在正在这样做,可用的值为0、1、2、3)
- 通过 态度 用户朝向(可能的值 (-1, 0, 1)
这样的解决方案允许我计算每个项目的业力。例如 -1 x 3 = -3(可能的最坏业力值),而 1 x 2 = 2(中等正业力)。
因此,我无法使用 用户 方法进行查询。对我来说还是太困惑了,抱歉。我们偏离了我最初的心理形象。
考虑这个查询:
$events = Event1::has('users', '<', 1)->get();
如果在 Event1 我声明
public function users()
{
return $this->morphToMany('User', 'item', null, null, 'creator_id');
}
注意:user是标准的 users表,存放用户名、密码和邮箱
我收到此错误:
[2014-12-28 05:02:48] production.ERROR: FATAL DATABASE ERROR: 500 = SQLSTATE[42S02]: Base table or view not found: 1146 Table 'niepoz_niepozwalam.items' doesn't exist (SQL: select * from `Events` where (select count(*) from `users` inner join `items` on `users`.`id` = `items`.`creator_id` where `items`.`item_id` = `Events`.`id` and `items`.`item_type` = Event1) >= 1) [] []
如果我将方法定义更改为
public function users()
{
return $this->morphToMany('Userattitude', 'item', null, null, 'creator_id');
}
注意:Userattitude 是我存储用户判断的模型(表名是'user_attitudes')。该表包含“重要性”和“态度”列。
我犯了同样的错误。
如果我将方法更改为
public function users()
{
return $this->morphToMany('User', 'Userattitudes', null, null, 'creator_id');
}
我明白了:
[2014-12-28 05:08:28] production.ERROR: FATAL DATABASE ERROR: 500 = SQLSTATE[42S22]: Column not found: 1054 Unknown column 'user_attitudes.Userattitudes_id' in 'where clause' (SQL: select * from
Events
where (select count(*) from users
inner join user_attitudes
on users
.id
= user_attitudes
.creator_id
where user_attitudes
.Userattitudes_id
= Events
.id
and user_attitudes
) [1] = Event >可能的解决方案:
名为“items”的“user_attitudes”表别名。
我可以创建一个具有所需名称的 View 。
我做到了,但现在查询没有结果。
问题 2
我应该将creator_id 重命名为user_id - 还是保留两列并在其中保留重复的信息? creator_id 遵循约定,我用它来创建记录......如何解决这个难题?
问题 3。
据我了解,如果我想获得与用户相关的前 5 项事件列表,
我需要在代码中添加另一行,将搜索范围缩小到由特定登录用户创建的记录:
Auth::user()->id)
代码如下所示:
都具有重要性 0
$events = Event1::whereHas('users', function($q){
$q->where('importance', 0);
$q->where('creator_id', '=', Auth::user()->id);
})->get();
对?
问题 5:
好的,我现在可以输出这样的查询:
$rank_entities = Entity::leftJoin('user_attitudes', function($q){
$q->on('entity_id', '=', 'entities.id');
$q->where('item_type', '=', 'entity');
})
->selectRaw('entities.*, SUM(user_attitudes.importance) AS importance')
->groupBy('entities.id')
->orderBy('importance', 'desc')
->take(6)
->get();
在 foreach 循环中,我可以使用以下代码显示总重要性计数:
{{$e->importance or '-'}}
但是我如何显示替代查询的计数:来自另一列的值的总和,命名态度,可以在这个 SEPARATE 查询中计算:
换句话说,在我的 @foreach 循环中,我需要同时显示 $e->importance 和计算出的 SUM(user_attitudes.attitude) AS karma ,现在可以通过以下查询接收:
$rank_entities = Entity::leftJoin('userattitudes', function($q){
$q->on('entity_id', '=', 'entities.id');
$q->where('item_type', '=', 'entity');
})
->selectRaw('entities.*, SUM(userattitudes.karma) AS karma')
->groupBy('entities.id')
->orderBy('karma', 'desc')
->take(5)
->get();
我的解决方案是在“实体”表中创建一些额外的列:
- karma_negative
- karma_positive
每次有人投票时存储/更新投票总数。
最佳答案
首先,让我们谈谈设置。我不完全确定你的工作方式和是否有效,但我在我的测试实例上创建了它并且它有效,所以我建议你相应地改变你的:
数据库
事件
这是一个简单的(你可能已经有了这样的
用户
我不确定在你的例子中是否是
Userattitude
但我不这么认为...项目
这是重要的一点。数据透视表。名称可以不同,但为了简单起见并遵循约定,它应该是多态关系的复数(在您的情况下
item => items
)user_id
。这将简化关系声明)楷模
我认为您必须阅读 docs再次。你宣布了几个奇怪的关系。这是我如何做到的:
事件1
默认情况下,Laravel 使用类名(
get_class($object)
)作为 ..._type
的值数据库中的列。要更改您需要定义 $morphClass
在你的模型中。class Event1 extends Eloquent {
protected $table = 'events';
protected $morphClass = 'event';
public function users()
{
return $this->morphToMany('User', 'item', null, null, 'creator_id');
}
}
用户
class User extends Eloquent implements UserInterface, RemindableInterface {
// ... default laravel stuff ...
public function events(){
return $this->morphedByMany('Event1', 'item', null, null, 'creator_id');
}
}
查询
好了,现在我们可以开始了。第一个附加信息。我尽可能使用 Eloquent 关系。在所有查询中
join()
使用关系会变慢,因为某些事情(例如计数或计算最大值)必须在查询后在 PHP 中完成。 MySQL 在这些方面做得很好(也是性能方面的)。总值(value)前 5 名
$events = Event1::leftJoin('items', function($q){
$q->on('item_id', '=', 'events.id');
$q->where('item_type', '=', 'event');
})
->selectRaw('events.*, SUM(items.importance) AS importance')
->groupBy('events.id')
->orderBy('importance', 'desc')
->take(5)
->get();
票数超过 0 的前 5 名
$events = Event1::leftJoin('items', function($q){
$q->on('item_id', '=', 'events.id');
$q->where('item_type', '=', 'event');
$q->where('importance', '>', 0);
})
->selectRaw('events.*, COUNT(items.id) AS importance')
->groupBy('events.id')
->orderBy('importance', 'desc')
->take(5)
->get();
都具有重要性 0
$events = Event1::whereHas('users', function($q){
$q->where('importance', 0);
})->get();
所有没有任何投票
$events = Event1::has('users', '<', 1)->get();
全部获得 1+ 票
$events = Event1::has('users')->get();
全部按票数排序
$events = Event1::leftJoin('items', function($q){
$q->on('item_id', '=', 'events.id');
$q->where('item_type', '=', 'event');
})
->selectRaw('events.*, COUNT(items.id) AS count')
->groupBy('events.id')
->orderBy('count', 'desc')
->get();
最新 5 无票
如果您使用 Eloquents 时间戳
created_at
:$events = Event1::has('users', '<', 1)->latest()->take(5)->get();
如果您不是(按最大 ID 排序):
$events = Event1::has('users', '<', 1)->latest('id')->take(5)->get();
无票随机5
$events = Event1::has('users', '<', 1)->orderByRaw('RAND()')->take(5)->get();
我没有故意对查询添加任何解释。如果您想了解更多有关特定内容或需要帮助的信息,请发表评论
关于laravel 4 关系 - 如何显示用户投票记录的前 5 名排名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27653323/