我试图了解如何有效地使用Eloquent关系在模型中具有一些高级功能 . 我有一个包含2个表,“用户”和“订阅”的订阅应用程序 . 这是一个遗留系统,所以我不能以任何我想要的方式改变事物 .
Table users (model App\User)
id
email
active (0/1)
join_date
address etc
phone
Table subscriptions (model App\Subscription)
id
user_id
box_id (what the person is subscribed to get)
amount
用户被标记为活动或未激活 .
我想在Subscription模型上有一个静态方法,它将为我提供所有活动订阅 . 然后将该数据输入应用程序的其他部分 .
这是通过将订阅加入用户并基于 active
列进行过滤得出的 . 查询是这样的:
SELECT users.*, subscriptions.*
FROM subscriptions
JOIN users ON users.id = subscriptions.user_id
WHERE users.active = 1
订阅模型
class Subscription extends Model
{
public static function allActive()
{
// This works except it doesn't use the eloquent relationship
return static::where('users.active', 1)
->join('users', 'users.id', '=', 'subscriptions.user_id')
->select('users.*','subscriptions.*')
->get();
}
public function user()
{
return $this->belongsTo(User::class);
}
}
用户模型
class User extends Authenticatable
{
use Notifiable;
public function subscriptions()
{
return $this->hasMany(Subscription::class);
}
}
我会像这样使用它:
$subscriptions = \App\Subscription::allActive()->toArray();
print_r($subscriptions);
我有两个问题 .
-
如何重写
allActive
函数以使用我已定义的关系?任何解决方案都应该使用JOIN生成SQL . -
在返回的数据中,如何将列与两个单独的表分开,以便清楚数据来自哪个表?
1 回答
鉴于您已连接的关系,要从模型类中仅获取活动订阅,您必须这样做:
那就是在Laravel中使用
closures
,这是编写高级雄辩查询的一种有效方式 .在回调函数中,你将使用$
query
对象做很多事情,它基本上处理用户模型,因为你提到它是->whereHas
的第一个参数请注意,该变量必须具有与声明关系时使用的 EXACTLY 相同的名称
以上我想回答你的第一个问题,但强烈建议你在控制器文件中完成大部分逻辑
要回答问题2,当您执行
get()
时,它将返回Subscription
对象数组,以便根据您必须使用的列访问信息: