有时我们使用MySql Views来组织相关表,以便于搜索和排序。例如,如果您的帖子具有状态和来源。
Post
subject
body
source_id
status_id
Status
id
label
other_field
Source
id
label
other_field
View
create view read_only_posts as
SELECT statuses.label as status, sources.label as source, posts.*
from posts
left join statuses on statuses.id = posts.status_id
left join sources on sources.id = posts.source_id
然后我们有Post模型和一个额外的模型:
// Post.php
class Post extends Model
{
//
}
// ReadOnlyPost.php
class ReadOnlyPost extends Post
{
protected $table = 'read_only_posts';
}
这很好,因为现在您可以直接对Status或Source进行排序或过滤,而不是id的字符串。您还可以添加' other_field'。
但是我们有一个需要帮助的问题。如果你在帖子上有多态的多对多关系,我无法让它在只读版本上工作。例如,如果您有多态标签:
// Post.php Model
public function tags()
{
return $this->morphToMany(Tag::class, 'taggable');
}
问题是当您使用特定标记过滤帖子(使用只读模型)时,您会得到这样的SQL:
选择count(*)作为
read_only_posts
中存在的聚合(tags
上的taggables
内部加入tags
。id
= {{1 } {。taggables
其中taggable_id
。read_only_posts
=id
。taggables
和taggable_type
。taggables
=' read_only_posts& #39;和taggable_type
=' test')
正如您所看到的,问题是 label
。taggables
=' read_only_posts' 。
我找不到覆盖模型的变形类型的方法。 (我在laravel 5.4上,MorphClass已经不存在了)。变形图是一个关联数组,因此您无法执行此操作:
taggable_type
我的愚蠢修复是当我将标签附加到帖子时我还将它附加到ready_only_posts,这有点乱。
其他人使用Views只读模型吗?任何人都有更好的方法来覆盖特定模型的多对多多态类型?
答案 0 :(得分:3)
查看代码,我相信这可能有用。
// SocketThreadConn.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <WinSock.h>
#include <Windows.h>
#pragma comment(lib, "ws2_32.lib")
#define PR_RECORED_TIME 10*1000 // (ms)
BYTE* pByteCamData = NULL;
INT nHeight = 900;
INT nWidth = 1600;
INT nSpect = 3;
INT nSolution = nHeight * nWidth * nSpect;
VOID SendRecoredData(SOCKET socket2operation);
int _tmain(int argc, _TCHAR* argv[])
{
pByteCamData = new BYTE[nSolution]; // <-- use [], not ()!
//----------------------
// Initialize Winsock.
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"WSAStartup failed with error: %d\n", iResult);
delete[] pByteCamData;
return 1;
}
//----------------------
// Create a SOCKET for listening for
// incoming connection requests.
SOCKET ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListenSocket == INVALID_SOCKET) {
wprintf(L"socket failed with error: %d\n", WSAGetLastError());
WSACleanup();
delete[] pByteCamData;
return 1;
}
//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port for the socket that is being bound.
sockaddr_in service = {};
service.sin_family = AF_INET;
service.sin_addr.s_addr = INADDR_ANY; // inet_addr("127.0.0.1");
service.sin_port = htons(27015);
if (bind(ListenSocket, (SOCKADDR *) &service, sizeof(service)) == SOCKET_ERROR) {
wprintf(L"bind failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
delete[] pByteCamData;
return 1;
}
//----------------------
// Listen for incoming connection requests.
// on the created socket
if (listen(ListenSocket, 1) == SOCKET_ERROR) {
wprintf(L"listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
delete[] pByteCamData;
return 1;
}
//----------------------
// Accept the connection.
wprintf(L"Waiting for client to connect...\n");
SOCKET AcceptSocket = accept(ListenSocket, NULL, NULL);
if (AcceptSocket == INVALID_SOCKET) {
wprintf(L"accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
delete[] pByteCamData;
return 1;
}
wprintf(L"Client connected.\n");
SendRecoredData(AcceptSocket); // <-- logic fix!
// No longer need client socket
closesocket(AcceptSocket); // <-- CLOSE_WAIT fix!
// No longer need server socket
closesocket(ListenSocket);
WSACleanup();
delete[] pByteCamData;
return 0;
}
VOID SendRecoredData(SOCKET socket2operation)
{
INT nCountDown = 5;
INT nSentData, nNumToSend;
BYTE *pData;
do
{
if (nCountDown == 0)
{
nCountDown = 5;
pData = pByteCamData;
nNumToSend = nSolution;
while (nNumToSend > 0) <-- send() fix!
{
nSentData = send(socket2operation, (char*)pData, nNumToSend, 0);
if (SOCKET_ERROR == nSentData) {
wprintf(L"send failed with error: %d\n", WSAGetLastError());
return;
}
pData += nSentData;
nNumToSend -= nSentData;
}
wprintf(L"Sent Camera Data OK [%d] Bytes\n", nSolution);
}
Sleep(PR_RECORED_TIME);
--nCountDown;
}
while (TRUE);
}
理论上你应该在变形图中列出class ReadOnlyPost extends Posts
{
public function getMorphClass() {
return 'posts';
}
}
模型/表格,因为系统会根据命名为它自动生成“帖子”类型。