【问题标题】:Filter many-to-many relationsip - Laravel过滤多对多关系 - Laravel
【发布时间】:2015-12-22 19:57:51
【问题描述】:

我有一个约会网站,其数据库如下

country (list of all countries)
-------    
id
name

users (It contains all types of users - Super Admin, Fronend user)
-----

id
role_id
name
email
password
country_id
active


user_profile(contains further details of frontend users)
------------

id
user_id
gender_id
photo
status
screenname
headline
location
sign
...and 12 more columns specific to frontend users


gender(specific to genders option - Male, Female, Gay, Prefer Not To Say, etc)
------

id
name


looking_for (pivot between user and gender)
-----------
id
user_id
gender_id

looking_forusergender 之间的数据透视表。一个用户可以约会多个性别。例如。一位既喜欢与男性约会又喜欢与女性约会的女性。

user 具有 hasOneuser_profile

public function profileDetails(){
    return $this->hasOne('\App\UserProfile');
}

相反,user_profileuser 具有“belongsTo”关系

public function user(){
    return $this->belongsTo('\App\User');
}

user_profilegenderbelongsTo 关系,因为每个用户个人资料都有性别

public function gender(){
    return $this->belongsTo('\App\Gender');
}

usergender 通过looking_for 具有belongsToMany,因为用户可以将他的约会偏好设置为多种性别。

// User
public function lookingFor(){
    return $this->belongsToMany('\App\Gender', 'looking_for')->withTimestamps();
}

//Gender
public function lookedUpBy(){
    return $this->belongsToMany('\App\User', 'looking_for')->withTimestamps();
}

现在,我正在尝试创建搜索。

例如。一位女性希望与居住在美国的男性和女性约会。还必须考虑男性和女性(将显示在结果中)已将其looking_for 设置为女性。

首先,我试图获取所有将looking_for 偏好设置为女性的用户。

Gender::with('lookedUpBy')->find($genderIdOfSearchedUser);

如何进一步过滤?

编辑

我已将gender_id 移至users 表,因为它更适合那里。

我也有兴趣表

interests (1-on-1 Dating, Online Friends, Swingers etc)
---------
id
name

以及usersinterests 之间的数据透视表

interest_user
-------------
id
interest_id
user_id

因此,用户可以查找具有相似兴趣的多个性别。

比如说,一位女性希望与居住在美国的男性和女性约会,对 1-on-1 DatingOnline Friends 感兴趣

【问题讨论】:

  • 为什么性别是一个独立的实体?
  • 因为用户可以将其偏好设置为与多种性别约会。
  • 这只是我的意见,但我认为没有必要分开。每个用户只有一种性别,因此您可以将gender 放入您的用户表中。您可以添加interests 表或类似的东西?!检查en.wikipedia.org/wiki/Database_normalization
  • 我已经有一个interests 表。请查看更新后的问题。

标签: php mysql laravel eloquent many-to-many


【解决方案1】:

@Gordon 的答案会起作用,但您基本上是从数据库中提取所有数据并迭代对象集合,在程序内存中为您的答案挑剔,而不是利用为此类查询构建的数据库引擎。 我会使用 laravel whereHas 方法来查询多对多关系

//assuming you are in the User instance you are trying to search for
$user = User::first();
$userGenderPref = $user->lookingFor()->get()->lists('gender_id');
$userInterestedIn = $user->interestedIn()->get()->lists('interest_id');
$results = User::whereHas('lookingFor', function($query) use ($userPref){//looking for gender
      $query->whereIn('gender_id',$userPref);
})
->whereHas('interestedIn', function($query) use ($userInterestedIn){//interested in
      $query->whereIn('interest_id',$userInterestedIn);
})
->where('user_id','!=',$user->user_id)//this is added to filter out our current user
->where('country_id',$user->country_id) //same country code as the original user
->get();

上述代码将返回与您的用户具有相同偏好、性别和兴趣的用户列表,并且还将确保它与当前用户位于同一国家/地区。

【讨论】:

  • 您的意思是要查看belongToMany 感兴趣的用户关系并将国家代码添加到查询中?
  • 更新了我的答案。不得不发明利益关系函数(interestedIn
【解决方案2】:

Laravel 有很好的 collection filters ;)

试试这样的:

$collection = Gender::with('lookingFor')->each(function($gender) {

  // get the lookingFor names
  $looking_for = $gender->lookingFor()->lists('name');

  // check if your case has been met
  if(in_array('Female', $looking_for)) return $gender;
});

请注意,这是伪代码;)


附言。如果您想了解更多关于Laravel Collections 的信息,这里是我强烈推荐的free ebook

【讨论】:

    猜你喜欢
    • 2018-05-20
    • 1970-01-01
    • 2018-04-19
    • 2013-09-14
    • 2021-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多