Tối ưu hóa câu truy vẫn trong laravel
public function getDevicesService(Request $request, $device)
{
$pageSize = _clamp($request->per_page, 20, 100) // clamp $pageSize, min: 20, max: 100 -> should add _clamp helper
$users = User::with('devices')->paginate($pageSize); // eager loading user devices
// Your logic
return $users;
}
Optimize code cho chủ thớt một tẹo trước. Cho mình hỏi TDevice và cái $item_device device có quan hệ như nào với nhau vậy?
Trong vòng for chủ thớt không query như kia sẽ dẫn tới n+1 query. Nên dùng eager loading giống cái devices mình viết ở trên nhé.
Multype-auth trong laravel
- Nếu chủ thớt chỉ muốn là giới hạn admin vs user thường ở một số trang thôi thì có thể dùng middleware của laravel cho trang cần phân quyền là được rồi chứ không cần phức tạp thêm đâu. Nếu đã có cơ sở để phân biệt admin, user rồi thì không phải thêm bảng gì hết nữa cả.
class AdminOnly
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$user = $request->user();
if (!$user || $user->isAdmin !== true) {
return abort(403, 'Permission Denied');
}
return $next($request);
}
}
Sau đó thì dùng middleware này khi khai báo route:
Route::get('/private-page', 'Controller@action', ['middleware' => 'admin']);
Route::group(['prefix' => '/admin', 'middleware' => 'admin'], function () {
Route::get('/dashboard', ...);
});
- Không thích dùng middleware như kia thì dùng Gate/Policy là chuẩn bài rồi

[SQL] Cho em hỏi về ráng khóa chính khóa ngoại trong sql
- Một field được set làm khóa chính cho table để định danh duy nhất cho một record, giá trị của field đấy sẽ không được trùng lặp. Nên thường là field đấy sẽ là Number và tự động tăng. Và thường là ID của record.
- Khóa ngoại: Dùng để thể hiện mỗi quan hệ giữa các thực thể trong hệ quản trị cơ sở dữ liệu quan hệ. Ví dụ như: Một student chỉ thuộc một lớp học, muốn biết student nào học lớp nào sau khi lưu vào database thì mình cần biểu diễn quan hệ này bằng cách lưu thêm
IDcủa lớp học(class_id)vào bảngStudents. Khi đó thì mỗi record sẽ có 1 fieldclass_idđể xác định, hay trong trường hợp này anh em hay truyền miệng nhau câu thần trú là lấy khóa chính làm khóa ngoại. Tùy vào mối quan hệ kiểu 1-n, n-n mà khóa ngoại sẽ được lưu ở những cách khác nhau nhé bạn.
Sử dụng khóa ngoại sẽ giúp bạn tiện truy vấn ở những câu truy vấn phức tạp trong thực tế và tạo ràng buộc quan hệ giữa các thực thế trong hệ quản trị cơ sở dữ liệu quan hệ. Chẳng hạn như bạn sẽ không thể thực hiện query để xóa Lớp học khi trong database, lớp học đã có học sinh (xác định thông qua khóa ngoại).
componentDidMount
Lần đầu chưa có dữ liệu thì bạn có thể đặt default value là null, nếu null thì sẽ chưa render component sử dụng data mà hiển thị một compomnent Loading thay thế, hoặc hiển thị placeholder như Skeleton của Ant Design chẳng hạn để web không bị lỗi khi chưa có dữ liệu.
Ngoài ra, nếu dùng Next.js thì bạn có thể fetchData trong getInitialProps, nó support promise nên bạn có thể fetch data ở đây xong rồi component mới render. Khi đó ở lần đầu tiên render thì data đã có trong props rồi và bạn không phải fetch data ở componentDidMount nữa.
Thư viện chuyển mã HTML thành text Trong react-native hoặc js
Mình thấy trên NPM có nhiều lib lắm nè bạn:
https://www.npmjs.com/search?q=html to text
Bạn xem cái nào nhẹ thì dùng cũng được.
Hỏi về series học angular trên viblo.
Viblo hiện tại đang chưa có search theo series. Bạn co thể vào trong trang này tham khảo, mình thấy có nhiều lắm, bạn thử vào xem sao nhé. https://viblo.asia/tags/angularjs/series
Deploy ứng dụng nodejs lên vps google bị lỗi 502
Việc lỗi 502 là do Cloudflare không lấy được response từ web server của bạn. Nguyên nhân thì có khá nhiều, mình thử list một vài case để bạn check thử:
- Web server cấu hình sai, tức bản thân cái web còn chưa chạy được trên server => Bạn ssh lên server rồi thử tạo một cái request tới localhost thử
curl http://localhost
-
Node app đang listen sai port. => Kiểm tra nếu app đang listen port 3000 thì cần tạo proxy bằng nginx hoặc apache2... để forward request từ port 80/443 về 3000
-
VPS chưa open port 80, 433 hoặc port 3000 => Cần check lại trong fireware của VPS trên Google Cloud
Hy vọng một vài case trên sẽ giúp ích được bạn.
Hỏi về việc dùng markdown để cho phép người dùng đăng bài
Lúc lưu contents vào database bạn lưu cả cú pháp Markdown thì lúc render ra client bạn phải thêm một bước render contents từ Markdown về thành HTML nữa nhé. Dùng express thì có thể sử dụng markdown-it để render:
// node.js, "classic" way:
var MarkdownIt = require('markdown-it'),
md = new MarkdownIt();
var result = md.render('# markdown-it rulezz!');
Laravel: Update data vào mảng cách tối ưu nhất
@thanhminh1998 Nếu lưu vào dữ liệu gửi lên vào một bảng thì sau bạn nhỉ? Mỗi lần app gửi dữ liệu lên server thì mình lưu thành một row mới trong database. VD:
| id | user_id | type | json_value | created_at |
|---|---|---|---|---|
| 1 | 1 | view_post_tracking | { "postID": 1, "title": "First post" } | 2020-02-21 04:00:00 |
| 2 | 1 | view_post_tracking | { "postID": 2, "title": "Sencond post" } | 2020-02-21 05:00:00 |
| 3 | 1 | view_post_tracking | { "postID": 3, "title": "Third post" } | 2020-02-21 06:00:00 |
| 4 | 1 | open_link_tracking | { "postID": 2, "title": "Second post" } | 2020-02-21 07:00:00 |
Lúc nào bạn cần dùng thì query tất cả các row trong database ra. 
SELECT logs.*
FROM logs
WHERE user_id = 1 AND type = 'view_post_tracking'
[VIBLO] TEAM VIBLO KHI NÀO RA CHỨC NĂNG GOM BÀI VIẾT VÀO CÁC SERIES?
Để tạo series bạn làm các bước sau theo hình nhé:

Thực sự mình thấy vẫn mơ hồ về asynchronous (async-await) trong Javascript
1. Async/await cũng giống như promise, là non-blocking
Có lẽ là do câu chữ nên có thể làm bạn hơi khó hiểu. Mình nghĩ ý tác giả viết thế là vì một async function sẽ return một Promise nên khi các hàm khác dùng nó thì sẽ giống như là dùng Promise. Mình cho ví dụ:
const sayHello = async () => {
console.log('Hello')
}
// Example 1:
console.log(sayHello())
> Promise
// Example 2:
sayHello().then(() => {
console.log('Hi!')
})
Như vậy thì một async function sẽ chính là một Promise - tức nếu xét cả cái async function thì nó vẫn là một function bất đồng bộ. Tuy nhiên nội dung bên trong async function thì đúng như bạn đang nghĩ, qua từ khóa await, nó sẽ khiến cho code bên trong async function chạy từ trên xuống dưới như ý đồ bạn mong muốn. Tóm lại là chúng ta đang dùng bất đồng bộ để khử bất đồng bộ.
2. Async/await làm cho code bất đồng bộ nhìn và chạy gần giống như code đồng bộ.
Tác giả nói đúng đó bạn, bản chất thì cái code bên trong cái async function nó vẫn là code bất đồng bộ. Tuy nhiên cơ chế xử lý khác hơn một chút do trong ES6 có thêm một khái niệm gọi chung là Job Queue - một tầng phía trên của Event Loop Queue. Hiểu ngắn gọn thì trên ES6 implement thêm một cái Queue nữa để làm cho code trở nên chạy đồng bộ khi dùng async/await. Mình giải thích tới đây thôi bạn tìm hiểu thêm về Event Loop, Job Queue trên ES6 nhé.
Angularjs cached state sau khi compile assets
Thông thường khi build production thì mình hay config webpack để output ra các file kèm theo hash của content. Kiểu như này:
module.exports = {
//...
output: {
filename: '[name].[hash].bundle.js'
}
};
Khi đó tên của mỗi file sẽ có một cái mã hash:
- Nếu content của file đó ko sửa đổi -> hash vẫn sẽ giữ nguyên -> file được cache
- Nếu content của file bị sửa đổi -> hash của content sẽ thay đổi -> tên file khác với version trước -> hạn chế được việc bị cache.
Ngoài ra cũng có một cách khác mà mọi người hay dùng đó là thêm queryString vào các đường link load css, js kiểu như này:
https://viblo.asia/assets/style.css?ver=1.0.2-beta.10
Khi nối thêm version thay đổi thì đường link có query string mới nên cũng sẽ hạn chế được việc bị cache.
Cách chuyển blog wordpress vào trong một website khác ??
Mặc định thì Wordpress sẽ chạy với domain hoặc địa chỉ IP với root URL (/). Theo mình hiểu thì bạn đang muốn deploy web Wordpress của bạn sau path prefix là /blog. Bạn thử thêm 2 dòng config sau nữa xem sao:
define('WP_SITEURL', 'http://' . $_SERVER['HTTP_HOST'] . '/blog');
define('WP_HOME', 'http://' . $_SERVER['HTTP_HOST'] . '/blog');
Mình thấy bạn đang thêm prefix bằng cách để code trong sub folder là /var/www/html/blog. Đây cũng là một cách rất đơn giản, nếu dùng cách này thì bạn ko cần phải dùng .htaccess để rewrite lại URL nữa.
Tên công nghệ/ giải pháp dùng để listener sự kiện từ Backend trên Web Browser Client?
Về mặt technical thì gọi là Web Socket / Socket.io là đúng rồi đấy bạn. Bạn tham khỏa thêm comment của bác @johansirius ở phía bên dưới, mình thấy bác ý nói đúng rồi đấy:
Giải pháp phổ biến nhất là dùng Websocket, ứng dụng trên di động duy trì kênh kết nối đến backend, ngay khi hoàn thành đơn hàng, mobile sẽ phát một sự kiện và backend chuyển trang. Do là trang TMĐT lưu lượng rất lớn nên họ thường dùng Kafka hay RabbitMQ.
Theo đó thì bạn có một số technical để áp dụng vào hệ thống như:
- Web socket / socket.io
- Pusher
- Kafka
- RabbitMQ
Nếu website của bạn là website nhỏ thì bạn cứ socket.io mà dùng nhé.
Vài vấn đề về SSL
-
Free SSL, có thể dùng Cloudflare, ổn định rồi. Viblo cũng đang dùng SSL của Cloudflare kìa bạn
. Ngoài ra, có Let's Encrypt, cho mình Free SSL nhưng phải renew lại cerkey sau mỗi 3 tháng. Nếu dùng Cloudflare thì mình không phải quan tâm tới vấn đề renew vì Cloudflare lo cho mình. Còn nếu dùng Let's Encrypt thì có thể cài thêm Cerbot vào server. Đây là tool hỗ trợ tạo key từ Let's Encrypt, tự động renew, tự generate config với web server như Apache, Ngĩnx, HAProxy, Plesk. -
Về login với Facebook thì đúng là phải https mới chạy. Thường để test dưới local thì bạn dùng self-signed key. Tức là bạn tự generate key rồi dùng nó để enable https.
Tại sao máy mình nhận font, mà máy khác lại không nhận?
Máy không hiện đúng font có thế do hai nguyên nhân sau:
- Bạn đang config sai CSS dẫn tới là text không hiển thị đúng font bạn muốn
- Máy bạn không cài font đấy và website của bạn cũng không cung cấp do đó không hiển thị đúng font
Do máy khác thì bị nhưng máy bạn lại không bị nên mình nghĩ lỗi có thể do config sai CSS như ở giả thiết 1. Bạn thì thử kiểm tra F12 xem web có request được file font về chưa. Nếu chưa thì có thể là đường link: url('../fonts/UTM-Avo.ttf') thật sự không tồn tại. Mình suy đóán là do máy bạn đã cài font UTM Avo trực tiếp trong máy nên dù web không load được font theo CSS config nhưng sẽ fallback trực tiếp font từ local. Do máy khác không có cài nên sẽ bị lỗi.
Và cũng có khả năng cao là máy bạn không có cài font đó và website của bạn cũng không cung cấp font.
=> Giải pháp là bạn hãy chèn thêm font UTM Avo vào website nữa nhé! Font này không có trên Google Fonts nên có lẽ bạn thử tải font UTM Avo đã Việt hóa theo link này xem sao nhé: https://taimienphi.vn/download-utm-avo-35806
Sau khi tải về thì bạn hãy đưa vào website và thêm font-face theo mẫu giống ảnh đầu tiên trong câu hỏi của bạn:
@font-face {
font-family: "UTM Avo",
src: url('../fonts/UTM-Avo.ttf') format('ttf');
}
Hỏi về cách viết code trong editor giống editor của viblo
@duongricky Viblo đang sử dụng editor là SimpleMDE để hỗ trợ người dùng trong việc viết bài theo cú pháp markdown. Khi sử dụng markdown thì bạn có thể chèn code vào trong các code block theo cú pháp mặc định của markdown nhé.
Ngoài ra, bộ markdown render của Viblo cũng được public trên github tại repository https://github.com/viblo-asia/sdk-js. Bạn có thể sử dụng bộ render này kết hợp với SimpleMDE là sẽ có editor y hệt như Viblo và thừa hưởng toàn bộ syntax mà Viblo support bạn nhé.
Nhờ mọi người đánh giá giúp mình
Với những thông tin như kia thì mình nghĩ vẫn thật khó để đánh giá được việc bạn tìm hiểu và học được là ở mức độ nào. Thước đo chính xác có lẽ mình khuyên bạn nên mạnh dạn và tự tin vào kiến thức của mình rồi đi phỏng vấn ở một số công ty. Sau khi phỏng vấn thường người phỏng vấn về kỹ thuật sẽ hỏi lại bạn xem bạn có câu hỏi nào dành cho họ hay không. Bạn có thể trao đổi về khả năng của mình lúc này và sẽ có các thông tin khách quan hơn từ người trực tiếp phỏng vấn bạn. Đi phỏng vấn cũng như đi học, bạn sẽ biết được bạn còn thiếu hay yếu ở những mục nào để về rèn luyện thêm cho bản thân. Phỏng vấn thì chắc chắn có người pass người bị fail. Nó rất đỗi là bình thường nên cứ mạnh dạn lên bạn nhé.
đưa một dự án Laravel lên Hosting bị HTTP ERROR 500
Mình nghĩ chắc là trong code Laravel bị lỗi gì đó nên có response 500. Bạn kiểm tra thư mục storage/logs, bootstrap/cache xem đã có quyền ghi chưa?
Nếu có quyền ghi rồi thì bạn thử xem log lỗi của laravel trong file storage/logs/laravel.log thì sẽ biết nguyên nhân tại sao lỗi.
Nuxt js, có Cách nào để thêm Plugin only desktop ko mọi người?
Solution 1: Use CSS3
Có rất nhiều giải pháp nhé. Mình suggest bạn một cách rất đơn giản mà hữu ích chỉ với CSS mà không phải thêm plugin nhé.
Khi tích hợp Facebook Messenger, trong đoạn code embed Facebook đưa cho mình sẽ bao gồm một thẻ div#fb-root, được facebook dùng để embed chatbox vào bên trong đó. Bạn chỉ thêm style cho cái div#fb-root là được. Nếu bạn dùng cái lib kia thì chắc nó cũng sẽ render ra #fb-root hoặc nếu khác thì bạn làm tương tự nha.
VD: Muốn ẩn chatbox khi ở màn hình có độ rộng nhỏ hơn hoặc bằng 1023px, thêm đoạn code như sau:
@media screen and (max-width: 1023px) {
#fb-root {
display: none !important;
}
}
Ngoài ra, bạn có thể thêm javascript để lấy chiều rộng hiện tại của màn hình rồi thêm quyết định có render cái component messenger hay không.
Ưu điểm của việc dùng CSS:
- Dùng CSS3 nên thoải mái tùy biến theo độ phân giải màn hình
- Khi độ rộng màn hình thay đổi, xoay màn hình, thì CSS vẫn chạy tốt
Solution 2: Handle by JavaScript
@tuananhbfs Nếu bạn không muốn dùng CSS thì bạn có thể viết code JS như sau, cũng đơn giản và dễ hiểu:
- Cài thêm package
mobile-detectđể kiểm tra thiết bị có phải là mobile không
yarn add mobile-detect
- Viết plugin cho Nuxt.js
import Vue from 'vue'
import VueFbCustomerChat from 'vue-fb-customer-chat'
import MobileDetect from 'mobile-detect'
export default () => {
const mobileDetect = new MobileDetect(window.navigator.userAgent)
if (!mobileDetect.mobile()) {
Vue.use(VueFbCustomerChat, {
page_id: 'xxx',
theme_color: '#6a9e10',
locale: 'vi_VN',
})
}
}
- Kích hoạt plugin của bạn
export default {
...,
plugins: [
...,
{ src: '~/plugins/facebookMessenger', ssr: false },
]
}
Nhớ lưu ý là phải khải báo plugin với ssr: false nhé. Vì cái plugin này mình chỉ cần chạy dưới client thôi.





