通過中間表,關聯多對多關係(via),實現一對一關聯
關聯一對多(hasmony)
操作步驟
要能排序
step3: 解決joinwith一對多關係之後分頁錯誤
end參考
環境:yii2.0
在做使用者列表展示的時候,需要展示子表的一些字段,並可以根據子表的字段進行排序,進行查詢。並且,關聯的多個表,其中乙個表(使用者標籤)是一對多的關係。
下面摘出具有代表性的關係表做一下說明,實際使用過程中多個一對一關係不做多次說明。
表模型:memberinfo
主鍵是memberinfo_id
, 外來鍵有memberinfo_account
(別問我為什麼不用id做主鍵,以前系統的設計就是如此)
目的:獲取使用者消費統計資料
使用者消費統計表:stat_member_consume
表模型:memberinfoconsume
關係是一對一:stat_member_consume
表的stat_member_consume_memberinfo_id
=memberinfo
表的memberinfo_id
關聯**:
memberinfo.php:
//使用者消費資訊
public
function
getmemberinfoconsume()
目的:獲取使用者會員卡的等級
會員卡資訊存在card表,使用者和會員卡的關係存在了memberinfo_card表。想要直接獲取card_level需要通過中間表關聯一下
會員卡表:card表
表字段是:
card_id 主鍵id
tag_name 會員卡名稱
card_level 會員卡等級
使用者會員卡表:memberinfo_card
三者之間的關係是
memberinfo表
memberinfo_card表
card表
memberinfo_account
memberinfo_card_memberinfo_account
memberinfo_card_card_id
card_id
關聯**:
memberinfo.php:
//關聯中間表使用者會員卡
public
function
getmemberinfocard()
//使用via
public
function
getcard()
已經了解via()
和viatable()
的讀者可以跳過下面這一小節。
via和viatable
官方說明:
△ 官方截圖
via() 和 viatable() 之間的區別是前者是根據現有的關聯名稱來指定連線表,而後者直接使用 連線表。目的:獲取使用者所有的標籤
標籤表tag,模型:tag
中間關係表:memeber_tag,模型:membertag,用於存放使用者和標籤的關係
三者之間的關係是
memberinfo表
memeber_tag表
tag表
memberinfo_account
member_tag_member_account
member_tag_tag_id
tag_id
關聯**:
memberinfo.php:
//使用者標籤
public
function
getmemberinfotags()
關聯**已經在上一章說明了。
關鍵是後面步驟
為什麼要有這一步?是因為子表的排序暫時沒有發現用memberconsume.stat_member_consume_order_sum
傳值進行排序的方式。前端呼叫介面的時候,通過傳sort引數來實現介面排序,用太長的名字也不太好。
於是,要使排序的**可用,需要把這些需要排序和搜尋的子表字段新增到主表的物件裡
你可以直接在searchmodel裡新增
public
$stat_member_consume_order_sum
不過更建議使用內建的函式去新增。
由於memberinfosearch 繼承了 memberinfo ,所以可以通過繼承attributes()
方法新增字段
memberinfosearch.php:
public
function
attributes()
在memberinfosearch中新增關聯查詢
memberinfosearch.php
public
function
search
($params
,$isverify
=null
)
在membersearch中新增過濾搜尋
仍然是search()方法中
memberinfosearch.php:
1
//在**裡面照著隊形新增這一句即可
3$query
->
andfilterwhere([
'like'
,'tag_name'
,$this
->
tag_name])
;
這裡發現和 yii關聯欄位並帶搜尋排序功能 這篇教程中不一樣的地方是,搜尋的欄位名不需要加關聯表的名字,直接用已經加過的關聯欄位名就可以成功。
上面**只是乙個例子,使用中根據你需要搜尋的子表字段進行新增即可,多乙個搜尋,就多加一條andfilterwhere
。
我在使用中發現如果要搜陣列,比如stat_member_consume_order_sum
的搜尋傳到後台是以$stat_member_consume_order_sum[0]$stat_member_consume_order_sum[1]的方式,這時不傳 andfilterwhere 會報錯,所以在外面多加了個判斷字段是否為陣列。
p.s. andfilterwhere() 可以在有值的時候進行搜尋過濾,沒有值的時候忽略這個where條件
繼續在search()方法中修改,activedataprovider類的sort屬性
memberinfosearch.php:
$dataprovider
=new
activedataprovider([
'query'
=>
$query
,//排序**在這裡
'sort'
=>
['attributes'
=>
['stat_member_consume_order_sum'
,'stat_member_consume_order_money_amount'
,'stat_member_consume_last_order_datetime'
,'finance_award'
,'card_level']]]);
也可以在例項化activedataprovider之後,用setsort()新增。
至此,前端傳sort引數(對應』sort』裡的名字)就可以進行排序啦
原本到上面2步就可以解決了,但是在列表顯示的時候發現分頁不對,明明指定了一頁顯示10條資料,可是第一頁只出來了4條,甚至有時候是3條、5條不等。
原因是yii 的joinwith,當出現一對多的時候,會出現這個問題。
在網上搜尋過後,有網友推薦 用with()
代替joinwith()
,不是不可以,我發現把一對多關係單獨用with之後,分頁錯亂確實解決了。
例子中的一對多關係是memberinfotags
$query
->
with([
'memberinfotags'])
;
但是引發另乙個問題,因為介面需求中,需要用標籤搜尋,用with()之後,搜尋memberinfotags裡的字段就失效了。
嘗試解決:仍然使用joinwith()
,然後->distinct(memberinfo_id)
然後yii報了乙個錯,大意是要把orderby的字段加到select裡,於是,加->addselect([把sort欄位都加進來])
。需要注意的是,addselect()
之前一定要有select()
才行
如有疑問或者更好的解決方案,歡迎和我溝通
yii2中gridview多表關聯顯示並可查詢
yii關聯欄位並帶搜尋排序功能
Yii關聯表字段查詢
yii的activerecord model裡有乙個search方法,可以用來搜尋 資料,但是今天在搜尋時,發現會用關聯表的字段來搜尋資料,查詢資料,找到了解決方法 比如article表與user表有關聯,需要在本表中用user.nickname欄位來搜尋資料 在model裡先定義乙個搜尋字段 pu...
關聯表查詢
1 imemoryrelationshipclassfactory fac mapcontext.createobject esrigeodatabase.memoryrelationshipclassfactory as imemoryrelationshipclassfactory irelat...
yii資料表關聯操作
首先在model中進行表關聯 public function relations 在增加和修改的頁面用下面的 來表示 textfield model s addon telephone array name hactiveform name model,addon telephone pattern...