<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="https://publishpress.com/"
	>

<channel>
	<title>Rails Archives - Tomoshare</title>
	<atom:link href="https://blog.tomosia.com.vn/tag/rails/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.tomosia.com.vn/tag/rails/</link>
	<description>Kênh chia sẻ kiến thức Tomosia Việt Nam</description>
	<lastBuildDate>Tue, 02 Jan 2024 07:49:20 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://blog.tomosia.com.vn/wp-content/uploads/2023/09/cropped-icon-32x32.png</url>
	<title>Rails Archives - Tomoshare</title>
	<link>https://blog.tomosia.com.vn/tag/rails/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Tối ưu hóa SEO với Sitemap</title>
		<link>https://blog.tomosia.com.vn/toi-uu-hoa-seo-voi-sitemap/</link>
					<comments>https://blog.tomosia.com.vn/toi-uu-hoa-seo-voi-sitemap/#comments</comments>
		
		<dc:creator><![CDATA[Le Van Ninh]]></dc:creator>
		<pubDate>Wed, 27 Dec 2023 04:31:22 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[sitemap]]></category>
		<category><![CDATA[seo]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=2898</guid>

					<description><![CDATA[<p>SEO (Search Engine Optimization) đóng vai trò quan trọng trong việc đưa trang web của bạn đến gần&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/toi-uu-hoa-seo-voi-sitemap/">Tối ưu hóa SEO với Sitemap</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>SEO (Search Engine Optimization) đóng vai trò quan trọng trong việc đưa trang web của bạn đến gần người dùng và công cụ tìm kiếm. Một công cụ hữu ích trong chiến lược SEO của bạn là sitemap.</p>



<h2 id="muc-dich-cua-sitemap" class="wp-block-heading">Mục đích của Sitemap</h2>



<ol class="wp-block-list">
<li><strong>Hiệu suất Indexing và SEO</strong><br>Giúp công cụ tìm kiếm hiểu rõ cấu trúc và nội dung của trang web. Điều này giúp tối ưu hóa hiệu suất indexing, đặc biệt là khi trang web có nhiều nội dung hoặc cấu trúc phức tạp.</li>



<li><strong>Ưu tiên Indexing</strong><br>Thông qua các thông tin như <code>lastmod</code> (thời điểm sửa đổi gần nhất), <code>changefreq</code> (tần suất thay đổi), và <code>priority</code> (độ ưu tiên), sitemap giúp bạn quyết định trang nào quan trọng hơn và nên được cập nhật thường xuyên hơn.</li>



<li><strong>Hỗ trợ trải nghiệm người dùng</strong><br>Sitemap không chỉ hỗ trợ công cụ tìm kiếm mà còn cải thiện trải nghiệm người dùng bằng cách cung cấp các liên kết dẫn đến các trang quan trọng.</li>



<li><strong>Điều hướng Crawl</strong> <strong>bổ sung</strong><br>Đối với các trang web có cấu trúc phức tạp, sitemap giúp điều hướng crawl bổ sung, đặc biệt là đối với các trang được tạo ra bằng JavaScript.</li>
</ol>



<h2 id="su-dung-sitemap-trong-ror" class="wp-block-heading">Sử dụng Sitemap trong ROR</h2>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">YAML</span><span role="button" tabindex="0" data-code="# Gemfile

gem 'sitemap_generator'" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #7B7F8B"># Gemfile</span></span>
<span class="line"></span>
<span class="line"><span style="color: #E7EE98">gem &#39;sitemap_generator&#39;</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Ruby</span><span role="button" tabindex="0" data-code="# config/sitemap.rb

require 'rubygems'
require 'sitemap_generator'

SitemapGenerator::Sitemap.default_host = 'https://yourdomain.com'
SitemapGenerator::Sitemap.create do
  add '/', changefreq: 'daily', priority: 1.0
  add '/page', changefreq: 'weekly', priority: 0.8
  # Thêm các trang khác và thông tin
end

# ping công cụ tìm kiếm google và bing để thông báo về sự thay đổi của sitemap
SitemapGenerator::Sitemap.ping_search_engines" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #7B7F8B"># config/sitemap.rb</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">require</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">rubygems</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F286C4">require</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">sitemap_generator</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #97E1F1; font-style: italic">SitemapGenerator</span><span style="color: #F286C4">::</span><span style="color: #97E1F1; font-style: italic">Sitemap</span><span style="color: #F6F6F4">.default_host </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">https://yourdomain.com</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #97E1F1; font-style: italic">SitemapGenerator</span><span style="color: #F286C4">::</span><span style="color: #97E1F1; font-style: italic">Sitemap</span><span style="color: #F6F6F4">.create </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">  add </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">/</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, changefreq</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">daily</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, priority</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">1.0</span></span>
<span class="line"><span style="color: #F6F6F4">  add </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">/page</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, changefreq</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">weekly</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, priority</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">0.8</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #7B7F8B"># Thêm các trang khác và thông tin</span></span>
<span class="line"><span style="color: #F286C4">end</span></span>
<span class="line"></span>
<span class="line"><span style="color: #7B7F8B"># ping công cụ tìm kiếm google và bing để thông báo về sự thay đổi của sitemap</span></span>
<span class="line"><span style="color: #97E1F1; font-style: italic">SitemapGenerator</span><span style="color: #F286C4">::</span><span style="color: #97E1F1; font-style: italic">Sitemap</span><span style="color: #F6F6F4">.ping_search_engines</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Zsh</span><span role="button" tabindex="0" data-code="# Tạo file sitemap.xml

rake sitemap:create #=&gt; public/sitemap.xml" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #7B7F8B"># Tạo file sitemap.xml</span></span>
<span class="line"></span>
<span class="line"><span style="color: #62E884">rake</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">sitemap:create</span><span style="color: #F6F6F4"> </span><span style="color: #7B7F8B">#=&gt; public/sitemap.xml</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">YAML</span><span role="button" tabindex="0" data-code="# public/robots.txt

Sitemap: https://yourdomain/sitemap.xml" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #7B7F8B"># public/robots.txt</span></span>
<span class="line"></span>
<span class="line"><span style="color: #97E1F1">Sitemap</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">https://yourdomain/sitemap.xml</span></span></code></pre></div>



<h2 id="luu-y-khi-tao-sitemap" class="wp-block-heading">Lưu ý khi tạo Sitemap</h2>



<ul class="wp-block-list">
<li>Phân chia công việc tạo sitemap thành các nhiệm vụ nhỏ để giảm gánh nặng hệ thống.</li>



<li>Xác định các tiêu chí để chỉ tạo sitemap cho những trang quan trọng nhất, giảm độ lớn của sitemap.</li>



<li>Tối ưu cơ sở dữ liệu để đảm bảo tìm kiếm và truy xuất dữ liệu một cách hiệu quả.</li>



<li>Theo dõi quá trình tạo sitemap và lưu lại log để giám sát và điều chỉnh khi cần thiết.</li>



<li>Nên tạo sitemap vào những thời điểm ít người truy cập nhất để giảm tác động đến hiệu suất hệ thống và người dùng.</li>
</ul>



<h2 id="ket-luan" class="wp-block-heading">Kết luận</h2>



<p>Sitemap là chìa khóa quan trọng cho chiến lược SEO và hiệu suất web. Bằng cách đặt độ ưu tiên và tuân thủ lưu ý quan trọng, sitemap không chỉ tối ưu hóa hiệu suất hệ thống mà còn định hình một chiến lược SEO thành công.</p>



<p>Cảm ơn bạn đã đọc.</p>
<p>The post <a href="https://blog.tomosia.com.vn/toi-uu-hoa-seo-voi-sitemap/">Tối ưu hóa SEO với Sitemap</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/toi-uu-hoa-seo-voi-sitemap/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Setup slack notifications in Rails</title>
		<link>https://blog.tomosia.com.vn/setup-slack-notifications-in-rails/</link>
					<comments>https://blog.tomosia.com.vn/setup-slack-notifications-in-rails/#comments</comments>
		
		<dc:creator><![CDATA[NST]]></dc:creator>
		<pubDate>Tue, 26 Dec 2023 02:05:13 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby On Rails]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=2766</guid>

					<description><![CDATA[<p>Slack là một phần mềm Worksplace sử dụng thông dụng rộng rãi. Tuy nhiên, ta có thể sử&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/setup-slack-notifications-in-rails/">Setup slack notifications in Rails</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="900" height="182" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/12/6423429367ad4157dea8a421_DUd_u8MT6t1xMJ6uXhHyllmQmHzK6KTyp1c5Xfxk8jmfvnrc-MEkdKAryNdNMD_WJQ5N67JxAVcq5JjFg7Oovf4f3SfthtgdBmmR-wyJETHD1twRYCObfA6aJUzu0xTSR2MB3zCX.png" alt="" class="wp-image-2778" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/12/6423429367ad4157dea8a421_DUd_u8MT6t1xMJ6uXhHyllmQmHzK6KTyp1c5Xfxk8jmfvnrc-MEkdKAryNdNMD_WJQ5N67JxAVcq5JjFg7Oovf4f3SfthtgdBmmR-wyJETHD1twRYCObfA6aJUzu0xTSR2MB3zCX.png 900w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/6423429367ad4157dea8a421_DUd_u8MT6t1xMJ6uXhHyllmQmHzK6KTyp1c5Xfxk8jmfvnrc-MEkdKAryNdNMD_WJQ5N67JxAVcq5JjFg7Oovf4f3SfthtgdBmmR-wyJETHD1twRYCObfA6aJUzu0xTSR2MB3zCX-300x61.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/6423429367ad4157dea8a421_DUd_u8MT6t1xMJ6uXhHyllmQmHzK6KTyp1c5Xfxk8jmfvnrc-MEkdKAryNdNMD_WJQ5N67JxAVcq5JjFg7Oovf4f3SfthtgdBmmR-wyJETHD1twRYCObfA6aJUzu0xTSR2MB3zCX-768x155.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/6423429367ad4157dea8a421_DUd_u8MT6t1xMJ6uXhHyllmQmHzK6KTyp1c5Xfxk8jmfvnrc-MEkdKAryNdNMD_WJQ5N67JxAVcq5JjFg7Oovf4f3SfthtgdBmmR-wyJETHD1twRYCObfA6aJUzu0xTSR2MB3zCX-380x77.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/6423429367ad4157dea8a421_DUd_u8MT6t1xMJ6uXhHyllmQmHzK6KTyp1c5Xfxk8jmfvnrc-MEkdKAryNdNMD_WJQ5N67JxAVcq5JjFg7Oovf4f3SfthtgdBmmR-wyJETHD1twRYCObfA6aJUzu0xTSR2MB3zCX-800x162.png 800w" sizes="(max-width: 900px) 100vw, 900px" /></figure>



<p>Slack là một phần mềm <strong>Worksplace</strong> sử dụng thông dụng rộng rãi. Tuy nhiên, ta có thể sử dụng slack để theo dõi và giám sát hệ thống, gửi tin nhắn tự động.</p>



<p>Sau đây, mình sẽ hướng dẫn mọi người cách để gửi thông báo, tin nhắn … đến slack trong rails app, nó làm cho Rails Application của bạn có thể trở nên năng động và hiệu quả hơn.</p>



<h3 id="setup-slack" class="wp-block-heading"><strong>Setup Slack</strong>:</h3>



<p>Đầu tiên, bạn phải có 1 Worksplace, 1 channel nào đó rồi nhé.</p>



<ul class="wp-block-list">
<li>Bạn cần tạo một App Slack từ <a href="https://api.slack.com/apps">https://api.slack.com/apps</a>, chọn <strong>Create an app →</strong> <strong>From Scratch (điền tên và chọn workspace)</strong></li>
</ul>



<figure class="wp-block-image size-full"><img decoding="async" width="736" height="816" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-20.17.47-1.png" alt="" class="wp-image-2772" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-20.17.47-1.png 736w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-20.17.47-1-271x300.png 271w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-20.17.47-1-380x421.png 380w" sizes="(max-width: 736px) 100vw, 736px" /></figure>



<ul class="wp-block-list">
<li>Chọn tab <strong>Incoming Webhooks</strong> bạn sẽ có: 
<ul class="wp-block-list">
<li><strong>Webhook URL</strong></li>



<li><strong>Channel</strong></li>
</ul>
</li>
</ul>



<figure class="wp-block-image size-full"><img decoding="async" width="1015" height="668" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-20.19.11.png" alt="" class="wp-image-2773" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-20.19.11.png 1015w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-20.19.11-300x197.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-20.19.11-768x505.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-20.19.11-380x250.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-20.19.11-800x527.png 800w" sizes="(max-width: 1015px) 100vw, 1015px" /></figure>



<h3 id="setup-rails" class="wp-block-heading"><strong>Setup Rails:</strong></h3>



<p>Đầu tiên, bạn tự thêm gem vào trong <strong>Gemfile</strong> và <strong>Bundle</strong> nhé.</p>



<h5 id="1-su-dung-slack-notifier" class="wp-block-heading">1. Sử dụng <code>slack-notifier</code></h5>



<ul class="wp-block-list">
<li><code>gem "slack-notifier"</code> <a href="https://github.com/slack-notifier/slack-notifier">https://github.com/slack-notifier/slack-notifier</a></li>



<li>Tạo 1 module <strong>SlackNotifier</strong> để tiện cho việc gọi khi cần.
<ul class="wp-block-list">
<li><strong>ENV[&#8216;SLACK_WEBHOOK_URL&#8217;], ENV[&#8216;SLACK_CHANNEL_SLACK&#8217;]</strong> bạn lấy ở bên trên.</li>



<li><strong>ENV[&#8216;SLACK_USERNAME_SLACK&#8217;]</strong> bạn đặt tự do.</li>
</ul>
</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:17.3125px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Ruby</span><span role="button" tabindex="0" data-code="#config/initializers create slack_notifier.rb

module SlackNotifier
  CLIENT = Slack::Notifier.new(
    ENV['SLACK_WEBHOOK_URL'],
    channel: ENV['SLACK_CHANNEL_SLACK'],
    username: ENV['SLACK_USERNAME_SLACK']
  )
end

SlackNotifier::CLIENT.ping &quot;Hello Everybody!&quot;
SlackNotifier::CLIENT.ping &quot;TEST SLACK NOTIFICATION&quot;
" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #7B7F8B">#config/initializers create slack_notifier.rb</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">module</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">SlackNotifier</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #BF9EEE">CLIENT</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">Slack</span><span style="color: #F286C4">::</span><span style="color: #97E1F1; font-style: italic">Notifier</span><span style="color: #F6F6F4">.</span><span style="color: #F286C4">new</span><span style="color: #F6F6F4">(</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #BF9EEE">ENV</span><span style="color: #F6F6F4">[</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">SLACK_WEBHOOK_URL</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">],</span></span>
<span class="line"><span style="color: #F6F6F4">    channel</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">ENV</span><span style="color: #F6F6F4">[</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">SLACK_CHANNEL_SLACK</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">],</span></span>
<span class="line"><span style="color: #F6F6F4">    username</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">ENV</span><span style="color: #F6F6F4">[</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">SLACK_USERNAME_SLACK</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">]</span></span>
<span class="line"><span style="color: #F6F6F4">  )</span></span>
<span class="line"><span style="color: #F286C4">end</span></span>
<span class="line"></span>
<span class="line"><span style="color: #97E1F1; font-style: italic">SlackNotifier</span><span style="color: #F286C4">::</span><span style="color: #97E1F1; font-style: italic">CLIENT</span><span style="color: #F6F6F4">.ping </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">Hello Everybody!</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #97E1F1; font-style: italic">SlackNotifier</span><span style="color: #F286C4">::</span><span style="color: #97E1F1; font-style: italic">CLIENT</span><span style="color: #F6F6F4">.ping </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">TEST SLACK NOTIFICATION</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"></span></code></pre></div>



<ul class="wp-block-list">
<li>Kết quả</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="576" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-20.34.40-1024x576.png" alt="" class="wp-image-2774" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-20.34.40-1024x576.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-20.34.40-300x169.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-20.34.40-768x432.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-20.34.40-1536x864.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-20.34.40-2048x1152.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-20.34.40-380x214.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-20.34.40-800x450.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-20.34.40-1160x653.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-20.34.40.png 2072w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Ngoài ra, bạn có thể custom nhiều hơn nữa,<strong> <em>xem thêm</em></strong> <strong><em>tại</em></strong> <a href="https://github.com/slack-notifier/slack-notifier">https://github.com/slack-notifier/slack-notifier</a></li>
</ul>



<h5 id="2-su-dung-exception-notification" class="wp-block-heading">2. Sử dụng exception-notification</h5>



<ul class="wp-block-list">
<li>Gem này sẽ tự động gửi exception về slack của bạn khi Rails App xảy exception. Nó giúp việc giám sát hệ thống, giúp bạn nhanh chóng kiểm tra, sửa chữa kịp thời.</li>



<li><code>gem exception_notification</code><a href=" https://github.com/smartinez87/exception_notification"> </a><a href="https://github.com/smartinez87/exception_notification">https://github.com/smartinez87/exception_notification</a></li>



<li><strong>Nếu ở production</strong>: <em>config/environments/production.rb</em></li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.65625px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Ruby</span><span role="button" tabindex="0" data-code="#config/environments/development.rb

Rails.application.config.middleware.use ExceptionNotification::Rack, slack: {
  webhook_url: ENV['SLACK_WEBHOOK_URL'],
  channel: ENV['SLACK_CHANNEL_NAME']
	}

" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #7B7F8B">#config/environments/development.rb</span></span>
<span class="line"></span>
<span class="line"><span style="color: #97E1F1; font-style: italic">Rails</span><span style="color: #F6F6F4">.application.config.middleware.use </span><span style="color: #97E1F1; font-style: italic">ExceptionNotification</span><span style="color: #F286C4">::</span><span style="color: #BF9EEE">Rack</span><span style="color: #F6F6F4">, slack</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">  webhook_url</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">ENV</span><span style="color: #F6F6F4">[</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">SLACK_WEBHOOK_URL</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">],</span></span>
<span class="line"><span style="color: #F6F6F4">  channel</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">ENV</span><span style="color: #F6F6F4">[</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">SLACK_CHANNEL_NAME</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">]</span></span>
<span class="line"><span style="color: #F6F6F4">	}</span></span>
<span class="line"></span>
<span class="line"></span></code></pre></div>



<ul class="wp-block-list">
<li>Đặt ở nơi bạn muốn push notify nhé.</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:17.3125px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Ruby</span><span role="button" tabindex="0" data-code="rescue_from StandardError do |e|
  ExceptionNotifier.notify_exception(e, 
		data: {
			# custom message ... 
			messages: e.messages
			date: Date.current
		}
	)
end
" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F6F6F4">rescue_from </span><span style="color: #BF9EEE">StandardError</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">do</span><span style="color: #F6F6F4"> |e|</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #97E1F1; font-style: italic">ExceptionNotifier</span><span style="color: #F6F6F4">.notify_exception(e, </span></span>
<span class="line"><span style="color: #F6F6F4">		data</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">			</span><span style="color: #7B7F8B"># custom message ... </span></span>
<span class="line"><span style="color: #F6F6F4">			messages</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> e.messages</span></span>
<span class="line"><span style="color: #F6F6F4">			date</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">Date</span><span style="color: #F6F6F4">.current</span></span>
<span class="line"><span style="color: #F6F6F4">		}</span></span>
<span class="line"><span style="color: #F6F6F4">	)</span></span>
<span class="line"><span style="color: #F286C4">end</span></span>
<span class="line"></span></code></pre></div>



<ul class="wp-block-list">
<li>Kết quả</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="732" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-22.55.23-1024x732.png" alt="" class="wp-image-2775" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-22.55.23-1024x732.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-22.55.23-300x215.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-22.55.23-768x549.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-22.55.23-1536x1098.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-22.55.23-2048x1465.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-22.55.23-380x272.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-22.55.23-800x572.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-22.55.23-1160x830.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-20-at-22.55.23.png 2078w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Ngoài ra, bạn có thể custom nhiều hơn nữa, <strong>x<em>em thêm tại</em></strong> <a href="https://github.com/smartinez87/exception_notification">https://github.com/smartinez87/exception_notification</a></li>
</ul>



<p>Hi vọng bài viết sẽ giúp ích được mọi người.</p>



<p>Cảm ơn mọi người.</p>



<p></p>
<p>The post <a href="https://blog.tomosia.com.vn/setup-slack-notifications-in-rails/">Setup slack notifications in Rails</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/setup-slack-notifications-in-rails/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>An Introduction to the ViewComponent Gem</title>
		<link>https://blog.tomosia.com.vn/an-introduction-to-the-viewcomponent-gem/</link>
					<comments>https://blog.tomosia.com.vn/an-introduction-to-the-viewcomponent-gem/#comments</comments>
		
		<dc:creator><![CDATA[tung nguyen]]></dc:creator>
		<pubDate>Tue, 14 Nov 2023 09:57:07 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby On Rails]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=1404</guid>

					<description><![CDATA[<p>Được truyền cảm hứng từ React, ViewComponent là các đối tượng Ruby được sử dụng để xây dựng&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/an-introduction-to-the-viewcomponent-gem/">An Introduction to the ViewComponent Gem</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Được truyền cảm hứng từ React, ViewComponent là các đối tượng Ruby được sử dụng để xây dựng đánh dấu cho việc hiển thị các view. ViewComponent là một framework cho việc xây dựng các thành phần view có thể tái sử dụng, kiểm thử và đóng gói trong Rails. Thông thường, các view có thể tái sử dụng được tạo trong Rails bằng cách sử dụng partials (đoạn mã HTML tái sử dụng) và sau đó được hiển thị trong các view khác khi cần, nhưng với sự giới thiệu của ViewComponent gem, partials có thể được thay thế bằng các thành phần view, vì chúng cung cấp nhiều lợi ích hơn. Hãy tìm hiểu về những lợi ích này.</p>



<p><strong>Khi nào và tại sao nên sử dụng view component</strong>?</p>



<p>Như đã nêu trước đó, các thành phần view là có thể tái sử dụng và có thể kiểm thử. Do đó, chúng có thể được áp dụng khi một view cần được tái sử dụng hoặc có lợi từ việc được kiểm thử trực tiếp. Một số lợi ích của các thành phần view, như đã nêu trong tài liệu của chúng, bao gồm các điểm sau:<br></p>



<ul class="wp-block-list">
<li>Chúng nhanh gấp đôi (khoảng 10 lần) so với partials.</li>



<li>là các đối tượng Ruby, do đó, phương thức khởi tạo của chúng rõ ràng xác định những gì cần thiết để hiển thị một view. Điều này có nghĩa là chúng dễ hiểu hơn và có thể tái sử dụng trong nhiều view khác nhau. Hơn nữa, các tiêu chuẩn chất lượng mã Ruby có thể được áp dụng, giúp giảm rủi ro của lỗi.</li>



<li>có thể được kiểm thử đơn vị, trong khi các view truyền thống của Rails yêu cầu kiểm thử tích hợp, cũng bao gồm việc thực hiện routing và controller ngoài việc hiển thị view.</li>
</ul>



<p><strong>Triển khai viewcomponent</strong></p>



<p>Các ViewComponent là các lớp con của <span style="color: red">ViewComponent::Base</span> và được đặt trong thư mục app/components. Tên của chúng kết thúc bằng &#8211; Component và nên được đặt theo cái mà chúng hiển thị chứ không phải cái mà chúng nhận. Chúng ta có thể tạo một view component bằng cách thủ công hoặc thông qua trình tạo component, nhưng trước tiên chúng ta cần thêm gem vào file gemfile và chạy lệnh bundle install.</p>



<pre class="wp-block-code"><code>gem "view_component"</code></pre>



<p>Để sử dụng trình tạo, chạy lệnh sau đây:</p>



<pre class="wp-block-code"><code>rails generate component &lt;Component name&gt; &lt;arguments needed for initialization&gt;</code></pre>



<p>Ví dụ, nếu chúng ta muốn tạo một component để hiển thị danh sách các khóa học trong lớp có sẵn trên một nền tảng học tập, chúng ta có thể sử dụng lệnh sau đây:</p>



<pre class="wp-block-code"><code>rails g component Course course</code></pre>



<p>Chúng ta đang truyền đối số&nbsp;<code>course</code>&nbsp;vào lệnh này vì chúng ta sẽ khởi tạo đối tượng Ruby này với khóa học mà chúng ta mong muốn nó hiển thị, và chúng ta đã đặt tên là&nbsp;<code>Course</code>&nbsp;vì nó hiển thị một khóa học.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="635" height="119" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-3.png" alt="" class="wp-image-1797" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-3.png 635w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-3-300x56.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-3-380x71.png 380w" sizes="auto, (max-width: 635px) 100vw, 635px" /></figure>



<p>Như chúng ta có thể thấy ở trên, component và file html tương ứng được tạo trong thư mục app/components, cùng với một file test</p>



<p>ViewComponent bao gồm các bộ tạo mẫu cho các công cụ mẫu erb, haml và slim, nhưng sẽ mặc định theo công cụ mẫu được chỉ định trong config.generators.template_engine. Tuy nhiên, bạn có thể chỉ định công cụ mẫu mong muốn bằng cách sử dụng các câu lệnh sau:</p>



<pre class="wp-block-code"><code>rails generate component Course course --template-engine &lt;your template engine&gt;</code></pre>



<p>Tiếp theo, chúng ta sẽ tạo model&nbsp;<code>Course</code>&nbsp;và một số khóa học để hiển thị.</p>



<pre class="wp-block-code"><code>rails g model Course title:string price:decimal location:string
rails db:migrate
</code></pre>



<p>Tạo hai khóa học mẫu:</p>



<pre class="wp-block-code"><code>Course.create(title: 'The Art of Learning', price: 125.00, location: 'Denmark')
Course.create(title: 'Organizing your Time', price: 55.00, location: 'London')</code></pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="204" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-5-1024x204.png" alt="" class="wp-image-1799" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-5-1024x204.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-5-300x60.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-5-768x153.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-5-1536x306.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-5-380x76.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-5-800x159.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-5-1160x231.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-5.png 1844w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Tệp&nbsp;<code>course_component.rb</code>&nbsp;được tạo ra với phương thức&nbsp;<code>initialize</code>&nbsp; được hiển thị dưới đây.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="686" height="307" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-4.png" alt="" class="wp-image-1798" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-4.png 686w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-4-300x134.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-4-380x170.png 380w" sizes="auto, (max-width: 686px) 100vw, 686px" /></figure>



<p>Tiếp theo là tạo controller và routes</p>



<pre class="wp-block-code"><code>rails g controller Courses index</code></pre>



<p>chỉnh sửa root của trang</p>



<pre class="wp-block-code"><code>root 'courses#index'</code></pre>



<p>Tạo giao diện, viêc tạo giao diện được thiện hiện ở file <code>course_component.html.erb</code>. mà chúng ta đã gen ở trước đó.<code><br></code></p>



<pre class="wp-block-code"><code><code>&lt;div&gt;
  &lt;h2&gt;&lt;%= @course.title %&gt;&lt;/h2&gt;
  &lt;h4&gt;&lt;%=  number_to_currency(@course.price, :unit =&gt; "€") %&gt;&lt;/h4&gt;
  &lt;h4&gt;&lt;%= @course.location %&gt;&lt;/h4&gt;
&lt;/div&gt;</code></code></pre>



<p>ở view, chúng ta hiển thị tiêu đề khóa học, giá và địa điểm sử dụng biến&nbsp;<code>@course</code>, đã được định nghĩa trong phương thức&nbsp;<code>initialize</code>&nbsp;của&nbsp;<code>CourseComponent</code>. Điều này tương tự khi tạo một biến trong một method ở controller và sau đó nó sẽ có sẵn trong một giao diện.</p>



<p>để biết cách controller hoạt động thì chuyển đến trang <em>index.html.erb</em> với method index tương ứng ở controller. ở đây chúng ta sẽ render component</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="756" height="141" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-6.png" alt="" class="wp-image-1800" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-6.png 756w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-6-300x56.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-6-380x71.png 380w" sizes="auto, (max-width: 756px) 100vw, 756px" /></figure>



<p>Như đã thấy ở trên, chúng ta render new instance của&nbsp;<code>CourseComponent</code>&nbsp;bằng cách khởi tạo courseComponent với khóa học mà chúng ta muốn nó hiển thị trong giao diện index course. Khóa học này trở thành biến&nbsp;<code>@course</code>&nbsp;được cung cấp cho tệp&nbsp;<code>course_component.html.erb</code>.</p>



<p>Chúng ta có thể render trực tiếp ở controller như sau</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="752" height="222" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-7.png" alt="" class="wp-image-1801" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-7.png 752w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-7-300x89.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-7-380x112.png 380w" sizes="auto, (max-width: 752px) 100vw, 752px" /></figure>



<p>Nội dung bổ sung cũng có thể được truyền vào component theo một trong những cách sau đây:</p>



<pre class="wp-block-code"><code>&lt;%= render(CourseComponent.new(course: Course.find(1))) do %&gt;
  container
&lt;% end %&gt;
&lt;%= render(CourseComponent.new(course: Course.find(1)).with_content("container")) %&gt;</code></pre>



<p>Trong file component, chúng ta có thể include nội dung ở bất kỳ đâu mà chúng ta muốn. Trong trường hợp này, chúng ta sẽ thêm content như một class bằng cách chỉnh sửa thẻ div như sau:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="900" height="293" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-8.png" alt="" class="wp-image-1812" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-8.png 900w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-8-300x98.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-8-768x250.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-8-380x124.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-8-800x260.png 800w" sizes="auto, (max-width: 900px) 100vw, 900px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="491" height="128" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-9.png" alt="" class="wp-image-1813" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-9.png 491w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-9-300x78.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-9-380x99.png 380w" sizes="auto, (max-width: 491px) 100vw, 491px" /></figure>



<p><strong>Render a Collection</strong></p>



<p>Nếu chúng ta muốn hiển thị toàn bộ danh sách các khóa học, ViewComponent cung cấp một cách rất đơn giản để làm điều này bằng cách sử dụng method with_collection. Thay vì khởi tạo component bằng cách sử dụng .new, nó được khởi tạo bằng cách sử dụng .with_collection, và collection được truyền vào như một biến</p>



<pre class="wp-block-code"><code>CourseComponent.with_collection(Course.all)</code></pre>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="576" height="282" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-11.png" alt="" class="wp-image-1815" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-11.png 576w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-11-300x147.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-11-380x186.png 380w" sizes="auto, (max-width: 576px) 100vw, 576px" /></figure>



<p>&nbsp;thẻ&nbsp;<code>with_collection_parameter</code>&nbsp;có sẵn trong trường hợp chúng ta muốn đặt tên khác cho bộ sưu tập.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="631" height="316" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-12.png" alt="" class="wp-image-1816" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-12.png 631w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-12-300x150.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-12-380x190.png 380w" sizes="auto, (max-width: 631px) 100vw, 631px" /></figure>



<p>Trong trường hợp trên, tham số của khóa học đã được đặt tên là &#8220;item&#8221;. Do đó, trong tệp xem tương ứng, &#8220;@course&#8221; sẽ được thay thế bằng &#8220;@item&#8221; để được kết quả tương tự.</p>



<p>Các tham số bổ sung cũng có thể được thêm vào collection. Các tham số này sẽ được hiển thị cho mỗi mục trong collection. Hãy thêm văn bản &#8220;Buy Me&#8221; vào mỗi mục thông qua phương thức này.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="868" height="127" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-13.png" alt="" class="wp-image-1818" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-13.png 868w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-13-300x44.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-13-768x112.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-13-380x56.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-13-800x117.png 800w" sizes="auto, (max-width: 868px) 100vw, 868px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="804" height="311" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-14.png" alt="" class="wp-image-1819" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-14.png 804w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-14-300x116.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-14-768x297.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-14-380x147.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-14-800x309.png 800w" sizes="auto, (max-width: 804px) 100vw, 804px" /></figure>



<p>thêm @noitce vào file course_component.html.erb</p>



<pre class="wp-block-code"><code>&lt;p&gt;&lt;a href='#'&gt; &lt;%= @notice %&gt; &lt;/a&gt;&lt;/p&gt;</code></pre>



<p>Cuối cùng, trong tùy chọn&nbsp;<code>collections</code>, chúng ta có một biến đếm (<code>counter variable</code>) có thể được kích hoạt để đánh số các mục. Để kích hoạt biến đếm này, chúng ta cần thêm &#8220;_counter&#8221; vào tham số của bộ sưu tập và làm cho nó có sẵn trong các tệp xem thông qua phương thức&nbsp;<code>initialize</code>.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="658" height="298" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-15.png" alt="" class="wp-image-1820" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-15.png 658w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-15-300x136.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-15-380x172.png 380w" sizes="auto, (max-width: 658px) 100vw, 658px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="437" height="369" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-16.png" alt="" class="wp-image-1821" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-16.png 437w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-16-300x253.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-16-380x321.png 380w" sizes="auto, (max-width: 437px) 100vw, 437px" /></figure>



<p>Xem bài viết đầy đủ tại đây: https://www.honeybadger.io/blog/ruby-view-components/</p>



<p>Thank you!!! </p>



<p></p>



<p></p>



<p></p>



<p></p>



<p></p>



<p></p>



<p></p>



<p></p>



<p></p>



<p></p>



<p></p>



<p></p>



<p></p>
<p>The post <a href="https://blog.tomosia.com.vn/an-introduction-to-the-viewcomponent-gem/">An Introduction to the ViewComponent Gem</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/an-introduction-to-the-viewcomponent-gem/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
		<item>
		<title>Rails 7.1 đã cho phép ErrorReporter để handle error classes.</title>
		<link>https://blog.tomosia.com.vn/don-gian-hoa-xu-ly-rescue-trong-rails-7-1/</link>
					<comments>https://blog.tomosia.com.vn/don-gian-hoa-xu-ly-rescue-trong-rails-7-1/#comments</comments>
		
		<dc:creator><![CDATA[Nguyen Anh]]></dc:creator>
		<pubDate>Wed, 08 Nov 2023 06:19:54 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Rails7.1]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=1773</guid>

					<description><![CDATA[<p>ErrorReporter was added to Rails in version 7.0. It was introduced as a way to provide a more consistent and standardized way to handle errors in the Rails applications.</p>
<p>The post <a href="https://blog.tomosia.com.vn/don-gian-hoa-xu-ly-rescue-trong-rails-7-1/">Rails 7.1 đã cho phép ErrorReporter để handle error classes.</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p></p>



<p><strong>Before Rails 7.1</strong></p>



<pre class="wp-block-code"><code># to handle a single error
begin
  code_that_raises_exception
rescue ArgumentError =&gt; e
  puts e.message
end   

# to handle multiple errors
exceptions = &#91;ArgumentError, StandarError]

begin
  code_that_raises_argument_error
  code_that_raises_standard_error
rescue *exceptions =&gt; e
  puts "Error: #{e.message} occurred."
end</code></pre>



<p><strong>In Rails 7.1</strong></p>



<pre class="wp-block-code"><code>@post = Post.new(params&#91;:post])

Rails.error.handle(ActiveRecord::Errors, StandardError) do
  @post.save!
end</code></pre>



<p><em><a href="https://github.com/rails/rails/pull/46299">PR of the update</a></em></p>
<p>The post <a href="https://blog.tomosia.com.vn/don-gian-hoa-xu-ly-rescue-trong-rails-7-1/">Rails 7.1 đã cho phép ErrorReporter để handle error classes.</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/don-gian-hoa-xu-ly-rescue-trong-rails-7-1/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Nâng bao nhiêu pool connect database là phù hợp</title>
		<link>https://blog.tomosia.com.vn/nang-bao-nhieu-pool-connect-database-la-phu-hop/</link>
					<comments>https://blog.tomosia.com.vn/nang-bao-nhieu-pool-connect-database-la-phu-hop/#comments</comments>
		
		<dc:creator><![CDATA[Minh Tang]]></dc:creator>
		<pubDate>Tue, 07 Nov 2023 16:33:24 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Kinh nghiệm]]></category>
		<category><![CDATA[Rails]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=1768</guid>

					<description><![CDATA[<p>Trong bài viết này chúng ta sẽ tìm hiểu về sự quan trọng của việc tối ưu hóa kết nối database và tìm cách đảm bảo rằng bạn đang sử dụng số lượng pool kết nối đúng đắn, tiết kiệm tài nguyên và đảm bảo hiệu suất hệ thống.</p>
<p>The post <a href="https://blog.tomosia.com.vn/nang-bao-nhieu-pool-connect-database-la-phu-hop/">Nâng bao nhiêu pool connect database là phù hợp</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h3 id="1-max_connection-database-hien-tai-la-bao-nhieu" class="wp-block-heading">1. Max_connection database hiện tại là bao nhiêu?</h3>



<p>Giả sử ta sử dụng Database MySQL AWS thuộc dòng db.t2.large (2CPU &#8211; 8GB RAM). Để biết số lượng max_connection có 2 cách:</p>



<ul class="wp-block-list">
<li>Cách 1: Thực hiện truy vấn&nbsp;<code>SHOW GLOBAL VARIABLES LIKE 'max_connections';</code></li>



<li>Cách 2: Dùng công thức <code>max_connections = DBInstanceClassMemory/12582880</code>
<ul class="wp-block-list">
<li>Ram 8G ⇒ 8000000000 bytes / 12582880 = 635 pools</li>
</ul>
</li>
</ul>



<h3 id="2-nang-bao-nhieu-pool-la-hop-ly" class="wp-block-heading">2. Nâng bao nhiêu pool là hợp lý?</h3>



<p>Giả sử ta có 3 con servers. Mỗi server chạy 4 workers. Mỗi worker chạy 16 threads.</p>



<p>Mỗi thread là 1 connection đến database.</p>



<p>Suy ra ta có tổng số threads trên 1 server ⇒&nbsp;<code>16 threads * 4 workers = 64 pools/server</code></p>



<p>Ta có 3 servers ⇒&nbsp;<code>64 pools * 3 servers = 192 pools</code>&nbsp;⇒ Số pool tổng cộng là 192 pools</p>



<p><strong>Cho nên chỉ số&nbsp;<code>max_connection</code>&nbsp;&gt;&nbsp;<code>tổng số pools</code></strong></p>



<p>Với database ở trên thì sẽ đáp ứng được. Nếu DB của bạn yếu thì các bạn cần phải điều chỉnh lại số lượng threads cho phù hợp. Miễn sao khi tổng các server lại nó phải bé hơn số max_connection</p>



<p><strong>Lưu ý:</strong> Đó là ta mới tính cho những server đang golive, ngoài ra còn có những server khác như background chẳng hạn, hoặc khi ứng dụng được Scale-up server thì củng phải được tính vào. Tốt nhất là ta nên chừa số lượng còn lại ít nhất phải được 25 pools (Còn tuỳ vào thực tế server của bạn như thế nào mà tính cho hợp lý)</p>



<p>Nếu server bạn mạnh, bạn dùng nhiều threads thì đồng nghĩa với việc bạn phải nâng Database lên cho phù hợp. Chứ không thể server mạnh mà Database yếu thì không thể đáp ứng được.</p>
<p>The post <a href="https://blog.tomosia.com.vn/nang-bao-nhieu-pool-connect-database-la-phu-hop/">Nâng bao nhiêu pool connect database là phù hợp</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/nang-bao-nhieu-pool-connect-database-la-phu-hop/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Ngrok And Using Ngrok for Rails Application</title>
		<link>https://blog.tomosia.com.vn/ngrok-and-using-ngrok-for-rails-application/</link>
					<comments>https://blog.tomosia.com.vn/ngrok-and-using-ngrok-for-rails-application/#comments</comments>
		
		<dc:creator><![CDATA[Hổ Nguyễn]]></dc:creator>
		<pubDate>Tue, 31 Oct 2023 02:07:03 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[ngrok]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=1588</guid>

					<description><![CDATA[<p>Ngrok là gì? Install Ngrok: Trên MacOS, sử dụng HomeBrew: Trên Linux, sử dụng Apt: Trên Windows, sử&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/ngrok-and-using-ngrok-for-rails-application/">Ngrok And Using Ngrok for Rails Application</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 id="ngrok-la-gi" class="wp-block-heading has-medium-font-size"><strong>Ngrok là gì?</strong></h2>



<ul class="wp-block-list">
<li>Ngrok là một ứng dụng cho phép bạn truy cập từ bên ngoài internet đến hệ thống nội bộ (localhost) thông qua đường hầm an toàn được mã hoá mà ai cũng có thể truy cập được thông qua custom domain của Ngrok.</li>
</ul>



<ul class="wp-block-list">
<li>Trong một ngày đẹp trời khách hàng đang cần một demo gấp mà chưa kịp xây dựng môi trường staging để kiểm thử sản phẩm, việc sử dụng Ngrok là một giải pháp tuyệt vời để giải quyết vấn đề này. </li>



<li>Bạn có thể chạy ứng dụng của mình trên máy tính cá nhân và sử dụng Ngrok để tạo ra một đường link truy cập từ xa. Khách hàng có thể truy cập vào sản phẩm của bạn ngay lập tức, mà không cần phải chờ đợi xây dựng môi trường staging. Điều này giúp tiết kiệm thời gian và giúp bạn đáp ứng nhanh chóng yêu cầu của khách hàng.</li>
</ul>



<h2 id="install-ngrok" class="wp-block-heading has-medium-font-size" style="font-style:normal;font-weight:500"><strong>Install Ngrok</strong>:</h2>



<p>Trên MacOS, sử dụng HomeBrew:</p>



<pre class="wp-block-code"><code><code>brew install ngrok/ngrok/ngrok</code></code></pre>



<p>Trên Linux, sử dụng Apt:</p>



<pre class="wp-block-code"><code>  $ sudo tee /etc/apt/trusted.gpg.d/ngrok.asc &gt;/dev/null &amp;&amp; \\
  $ echo "deb &lt;https://ngrok-agent.s3.amazonaws.com&gt; buster main" | \\
  $ sudo tee /etc/apt/sources.list.d/ngrok.list &amp;&amp; \\
  $ sudo apt update &amp;&amp; sudo apt install ngrok\\
</code></pre>



<p>Trên Windows, sử dụng&nbsp;<a href="https://chocolatey.org/">Chocolatey</a>:</p>



<pre class="wp-block-code"><code><code>choco install ngrok</code></code></pre>



<p><strong>Unzip to install:</strong> Trên Linux hoặc Mac OS X, bạn có thể giải nén ngrok từ terminal bằng lệnh sau. Trên Windows, chỉ cần nhấp đúp vào ngrok.zip để giải nén nó.</p>



<pre class="wp-block-code"><code>$ unzip /path/to/ngrok.zip</code></pre>



<p><strong>Tạo tài khoản trên <a href="https://dashboard.ngrok.com/">ngrok dashboard</a>:</strong></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="582" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.22.20-PM-2-1024x582.png" alt="" class="wp-image-1594" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.22.20-PM-2-1024x582.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.22.20-PM-2-300x170.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.22.20-PM-2-768x436.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.22.20-PM-2-1536x873.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.22.20-PM-2-2048x1163.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.22.20-PM-2-380x216.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.22.20-PM-2-800x454.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.22.20-PM-2-1160x659.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.22.20-PM-2.png 2880w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p><strong>Kết nối với tài khoản của bạn:</strong> </p>



<p>Ở đây, chúng ta sẽ cần authtoken từ bước trước. Authtoken là điều mà agent sử dụng để đăng nhập vào tài khoản của bạn khi tạo một đường hầm. Chạy dòng lệnh sau trong dòng lệnh.</p>



<pre class="wp-block-code"><code><code>ngrok config add-authtoken TOKEN</code></code></pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="582" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.27.27-PM-2-1024x582.png" alt="" class="wp-image-1597" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.27.27-PM-2-1024x582.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.27.27-PM-2-300x171.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.27.27-PM-2-768x437.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.27.27-PM-2-1536x874.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.27.27-PM-2-2048x1165.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.27.27-PM-2-380x216.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.27.27-PM-2-800x455.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.27.27-PM-2-1160x660.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.27.27-PM-2.png 2880w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p><strong>Config Ngrok trong Rails development enviroment</strong>: </p>



<ul class="wp-block-list">
<li>Trong ứng dụng của bạn, bạn sẽ có một file <code>config/environments/development.rb</code>. Tệp này cho Rails biết cách cấu hình môi trường phát triển.</li>



<li> <span style="font-size: revert; color: initial; font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, &quot;Helvetica Neue&quot;, Arial, &quot;Noto Sans&quot;, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;, &quot;Noto Color Emoji&quot;;">Ở đây chúng ta sẽ cần thêm một dòng: </span></li>
</ul>



<pre class="wp-block-code"><code><code style="color: initial;">config.hosts &lt;&lt; /.*\\.ngrok-free.app/</code></code></pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="762" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.33.33-PM-1-1024x762.png" alt="" class="wp-image-1596" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.33.33-PM-1-1024x762.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.33.33-PM-1-300x223.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.33.33-PM-1-768x572.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.33.33-PM-1-1536x1143.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.33.33-PM-1-2048x1524.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.33.33-PM-1-380x283.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.33.33-PM-1-800x595.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.33.33-PM-1-1160x863.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-25-at-3.33.33-PM-1.png 2252w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Bây giờ chúng ta có thể chạy máy chủ rails của chúng ta: <code>rails s</code> Và connect đến locahost thông qua ngrok bằng câu lệnh sau: <code>ngrok http &lt;port&gt;</code>  </p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="624" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-26-at-9.27.42-AM-1024x624.png" alt="" class="wp-image-1599" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-26-at-9.27.42-AM-1024x624.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-26-at-9.27.42-AM-300x183.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-26-at-9.27.42-AM-768x468.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-26-at-9.27.42-AM-1536x935.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-26-at-9.27.42-AM-2048x1247.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-26-at-9.27.42-AM-380x231.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-26-at-9.27.42-AM-800x487.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-26-at-9.27.42-AM-1160x706.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-26-at-9.27.42-AM.png 2880w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<pre class="wp-block-preformatted">Lưu ý: Thay <code>&lt;port&gt;</code> bằng địa chỉ localhost mà bạn đã cấu hình trong backend. Rails mặc định là 3000, nhưng bạn nên sử dụng bất cứ cái nào bạn muốn.</pre>



<p>Như vậy là bạn đã connect thành công và có thể truy cập đến địa chỉ của ngrok <code>https://9b7c-118-69-55-83.ngrok-free.app</code> để test ở trình duyệt như sau:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="640" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-26-at-9.28.14-AM-1024x640.png" alt="" class="wp-image-1600" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-26-at-9.28.14-AM-1024x640.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-26-at-9.28.14-AM-300x188.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-26-at-9.28.14-AM-768x480.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-26-at-9.28.14-AM-1536x961.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-26-at-9.28.14-AM-2048x1281.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-26-at-9.28.14-AM-380x238.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-26-at-9.28.14-AM-800x500.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-26-at-9.28.14-AM-1160x725.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screenshot-2023-10-26-at-9.28.14-AM.png 2696w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p><em>Cảm ơn bạn đã đọc bài viết này về tính năng&nbsp;<code>ngrok</code> và cách sử dụng trong rails&nbsp;. Hy vọng rằng bạn đã tìm thấy thông tin hữu ích và có thêm kiến thức về cách sử dụng tính năng này để tạo ra đường hầm kết nối từ localhost đến internet trong ứng dụng của mình</em>. Cảm ơn các bạn đã ủng hộ.</p>
<p>The post <a href="https://blog.tomosia.com.vn/ngrok-and-using-ngrok-for-rails-application/">Ngrok And Using Ngrok for Rails Application</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/ngrok-and-using-ngrok-for-rails-application/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Tìm hiểu find_each, find_in_batches và in_batches</title>
		<link>https://blog.tomosia.com.vn/tim-hieu-find_each-find_in_batches-va-in_batches/</link>
					<comments>https://blog.tomosia.com.vn/tim-hieu-find_each-find_in_batches-va-in_batches/#comments</comments>
		
		<dc:creator><![CDATA[Vu Nguyen Duy]]></dc:creator>
		<pubDate>Tue, 31 Oct 2023 02:03:24 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Rails7.1]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=1614</guid>

					<description><![CDATA[<p>Khi làm việc với dữ liệu lớn trong ứng dụng Ruby on Rails, việc truy vấn và xử&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/tim-hieu-find_each-find_in_batches-va-in_batches/">Tìm hiểu find_each, find_in_batches và in_batches</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Khi làm việc với dữ liệu lớn trong ứng dụng Ruby on Rails, việc truy vấn và xử lý hàng loạt dữ liệu có thể trở nên phức tạp. Để giải quyết vấn đề này, Rails cung cấp các phương thức quan trọng: <code>find_each</code>, <code>find_in_batches</code>, <code>in_batches</code>. Trong bài viết này, chúng ta sẽ tìm hiểu về cách sử dụng chúng.</p>



<h2 id="1-find_each" class="wp-block-heading"><strong>1.find_each:</strong></h2>



<ul class="wp-block-list">
<li><code>find_each</code> là một phương thức mạnh mẽ giúp bạn truy vấn và xử lý hàng loạt dữ liệu một cách hiệu quả. Thay vì lấy toàn bộ kết quả truy vấn vào bộ nhớ và xử lý cùng một lúc, <code>find_each</code> cho phép bạn truy vấn từng phần dữ liệu nhỏ, tiết kiệm tài nguyên hệ thống.</li>



<li>Ví dụ sử dụng <code>find_each</code>:<br></li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#F8F8F2;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#efefe1">Ruby</span><span role="button" tabindex="0" data-code="User.find_each(batch_size: 1000) do |user|
  # Xử lý dữ liệu của user
end" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #8BE9FD; font-style: italic">User</span><span style="color: #F8F8F2">.find_each(batch_size</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> </span><span style="color: #BD93F9">1000</span><span style="color: #F8F8F2">) </span><span style="color: #FF79C6">do</span><span style="color: #F8F8F2"> |user|</span></span>
<span class="line"><span style="color: #F8F8F2">  </span><span style="color: #6272A4"># Xử lý dữ liệu của user</span></span>
<span class="line"><span style="color: #FF79C6">end</span></span></code></pre></div>



<p>Trong ví dụ trên, <code>batch_size</code> xác định số lượng bản ghi được truy vấn và xử lý trong mỗi lần lặp. Điều này giúp giảm áp lực lên bộ nhớ và tăng hiệu suất xử lý.<br></p>



<h2 id="2-find_in_batches" class="wp-block-heading">2. <strong>find_in_batches:</strong></h2>



<ul class="wp-block-list">
<li><code>find_in_batches</code> là một phương thức tương tự như <code>find_each</code>, nhưng thay vì lặp qua từng bản ghi, nó trả về từng batch (nhóm) bản ghi mà bạn có thể xử lý một cách đồng thời.</li>



<li>Ví dụ sử dụng <code>find_in_batches</code>:</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#F8F8F2;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#efefe1">Ruby</span><span role="button" tabindex="0" data-code="User.find_in_batches(batch_size: 200) do |users|
  users.each do |user|
    # Xử lý dữ liệu của user
  end
end" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #8BE9FD; font-style: italic">User</span><span style="color: #F8F8F2">.find_in_batches(batch_size</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> </span><span style="color: #BD93F9">200</span><span style="color: #F8F8F2">) </span><span style="color: #FF79C6">do</span><span style="color: #F8F8F2"> |users|</span></span>
<span class="line"><span style="color: #F8F8F2">  users.each </span><span style="color: #FF79C6">do</span><span style="color: #F8F8F2"> |user|</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #6272A4"># Xử lý dữ liệu của user</span></span>
<span class="line"><span style="color: #F8F8F2">  </span><span style="color: #FF79C6">end</span></span>
<span class="line"><span style="color: #FF79C6">end</span></span></code></pre></div>



<ul class="wp-block-list">
<li>Những option được sử dụng trong find_each và find_in_batches
<ul class="wp-block-list">
<li><code>batch_size:</code> là kích thước chỉ định của batch. Mặc định là 1000.</li>



<li><code>start: </code>Chỉ định primary_key bắt đầu trong batch, ví dụ bạn muốn lấy từ id = 5000, thì batch của bạn sẽ bắt đầu từ 5000</li>



<li><code>finish:</code> Chỉ định giá trị primary_key để kết thúc, như ở option :start là chọn vị trị bắt đầu thì :finish sẽ là vị trị kết thúc của batch.</li>
</ul>
</li>
</ul>



<h2 id="3-in_batches-trong-rails-7-1" class="wp-block-heading"><strong>3. in_batches trong rails 7.1</strong></h2>



<ul class="wp-block-list">
<li>Các bạn có thể thấy lợi ích của việc sử dụng find_each và find_in_batches ở trên, nhưng nó có hạn chế, việc sắp xếp các record chỉ dựa vào id của bảng và theo mặc định tăng dần, chúng ta không thể sắp xếp theo các trường khác. Thật may mắn trong ở phiên bản  rails 7.1 chúng ta có in_batches cho phép chúng ta sắp xếp theo các column mong muốn.</li>



<li>Ví dụ, nếu bạn muốn sắp xếp các bản ghi theo cột&nbsp;<code>created_at</code>, bạn có thể sử dụng&nbsp;<code>in_batches</code>&nbsp;như sau:</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#F8F8F2;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#efefe1">Ruby</span><span role="button" tabindex="0" data-code="User.in_batches(of: 1000, order: :created_at) do |batch|
  batch.each do |user|
    # Do something with each user
  end
end
" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #8BE9FD; font-style: italic">User</span><span style="color: #F8F8F2">.in_batches(of</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> </span><span style="color: #BD93F9">1000</span><span style="color: #F8F8F2">, order</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> </span><span style="color: #BD93F9">:created_at</span><span style="color: #F8F8F2">) </span><span style="color: #FF79C6">do</span><span style="color: #F8F8F2"> |batch|</span></span>
<span class="line"><span style="color: #F8F8F2">  batch.each </span><span style="color: #FF79C6">do</span><span style="color: #F8F8F2"> |user|</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #6272A4"># Do something with each user</span></span>
<span class="line"><span style="color: #F8F8F2">  </span><span style="color: #FF79C6">end</span></span>
<span class="line"><span style="color: #FF79C6">end</span></span>
<span class="line"></span></code></pre></div>



<ul class="wp-block-list">
<li>Các option hỗ trợ trong in_batches:
<ul class="wp-block-list">
<li><code>of:</code> Số lượng bản ghi tối đa trong mỗi batch.&nbsp;Giá trị mặc định là 1000</li>



<li><code>start:</code> Giá trị khóa chính của bản ghi đầu tiên trong batch.&nbsp;Giá trị mặc định là&nbsp;<code>nil</code>.</li>



<li><code>finish:</code> Giá trị khóa chính của bản ghi cuối cùng trong batch.&nbsp;Giá trị mặc định là&nbsp;<code>nil.</code></li>



<li><code>order:</code> Cột sắp xếp các bản ghi trong batch. Giá trị mặc định là&nbsp;<code>nil</code>.<br></li>
</ul>
</li>
</ul>



<p><strong>NOTE: một vài lưu ý khi sử dụng in_batches:</strong><br></p>



<ul class="wp-block-list">
<li>Nếu bạn không chỉ định cột sắp xếp,&nbsp;<code>in_batches</code>&nbsp;sẽ sắp xếp các bản ghi theo khóa chính của chúng.</li>



<li>Nếu bạn chỉ định cột sắp xếp, hãy đảm bảo rằng cột đó đã được đánh index để tối ưu hóa hiệu suất.</li>



<li>Nếu bạn muốn thực hiện các thao tác cập nhật hoặc xóa trên các bản ghi, hãy đảm bảo rằng bạn đã sử dụng&nbsp;<code>update_all</code>&nbsp;hoặc&nbsp;<code>delete_all</code>&nbsp;để tránh lỗi(áp dụng cho cả find_in_batches), ví dụ: <br></li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#F8F8F2;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#efefe1">Ruby</span><span role="button" tabindex="0" data-code="User.in_batches.each do |batch|
  batch.update_all('age = age + 5')
  batch.where('age &gt; 25').update_all(is_married: true)
  batch.where('age &lt;= 25').delete_all
end" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #8BE9FD; font-style: italic">User</span><span style="color: #F8F8F2">.in_batches.each </span><span style="color: #FF79C6">do</span><span style="color: #F8F8F2"> |batch|</span></span>
<span class="line"><span style="color: #F8F8F2">  batch.update_all(</span><span style="color: #E9F284">&#39;</span><span style="color: #F1FA8C">age = age + 5</span><span style="color: #E9F284">&#39;</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">  batch.where(</span><span style="color: #E9F284">&#39;</span><span style="color: #F1FA8C">age &gt; 25</span><span style="color: #E9F284">&#39;</span><span style="color: #F8F8F2">).update_all(is_married</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> </span><span style="color: #BD93F9">true</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">  batch.where(</span><span style="color: #E9F284">&#39;</span><span style="color: #F1FA8C">age &lt;= 25</span><span style="color: #E9F284">&#39;</span><span style="color: #F8F8F2">).delete_all</span></span>
<span class="line"><span style="color: #FF79C6">end</span></span></code></pre></div>



<p></p>



<p></p>



<div class="wp-block-cover is-light"><span aria-hidden="true" class="wp-block-cover__background has-cyan-bluish-gray-background-color has-background-dim-100 has-background-dim"></span><div class="wp-block-cover__inner-container is-layout-constrained wp-block-cover-is-layout-constrained">
<p class="has-text-align-center has-medium-font-size">Hi vọng bài viết có thể giúp ích cho các bạn. Chúc các bạn luôn tìm được niềm vui khi coding. 😀</p>
</div></div>
<p>The post <a href="https://blog.tomosia.com.vn/tim-hieu-find_each-find_in_batches-va-in_batches/">Tìm hiểu find_each, find_in_batches và in_batches</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/tim-hieu-find_each-find_in_batches-va-in_batches/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>Giải quyết N+1 trong rails</title>
		<link>https://blog.tomosia.com.vn/giai-quyet-n1-trong-rails/</link>
					<comments>https://blog.tomosia.com.vn/giai-quyet-n1-trong-rails/#comments</comments>
		
		<dc:creator><![CDATA[Le Van Ninh]]></dc:creator>
		<pubDate>Wed, 25 Oct 2023 04:32:30 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Sql]]></category>
		<category><![CDATA[Rails]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=1480</guid>

					<description><![CDATA[<p>N+1 là gì? N+1 query là một vấn đề hiệu suất phổ biến trong các ứng dụng Ruby&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/giai-quyet-n1-trong-rails/">Giải quyết N+1 trong rails</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 id="n1-la-gi" class="wp-block-heading">N+1 là gì?</h2>



<p>N+1 query là một vấn đề hiệu suất phổ biến trong các ứng dụng Ruby on Rails. Nó xảy ra khi bạn truy vấn một bảng để lấy dữ liệu, sau đó truy vấn bảng khác để lấy dữ liệu bổ sung cho mỗi đối tượng trong bảng đầu tiên.</p>



<p>Ví dụ: Bạn có bảng <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">posts</mark> và bảng <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">comments</mark></p>



<pre class="wp-block-code has-f-8-f-8-f-2-color has-text-color has-875-rem-font-size"><code>class Post &lt; ActiveRecord::Base 
  has_many :comments
end

class Comment &lt; ActiveRecord::Base
  belongs_to :post
end</code></pre>



<p>Bạn muốn lấy danh sách tất cả các bài đăng cùng với danh sách tất cả các bình luận của chúng, bạn có thể viết mã như sau:</p>



<pre class="wp-block-code"><code>@posts = Post.limit(5) 
@posts.each do |post| 
  @post.comments
end
# Total: 6 query 
# 1 query cho post 
# 5 query cho mỗi lần each</code></pre>



<p>Đoạn code này sẽ tạo ra hai truy vấn SQL: <br>Một truy vấn để lấy tất cả các bài đăng, và một truy vấn cho mỗi bài đăng để lấy tất cả các bình luận của nó. Điều này có thể dẫn đến hiệu suất kém, đặc biệt nếu bạn có nhiều bài đăng hoặc bình luận.</p>



<h2 id="cach-giai-quyet-n1" class="wp-block-heading">Cách giải quyết N+1</h2>



<p><strong>1. Sử dụng <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">includes</mark> hoặc <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">eager_load</mark></strong></p>



<p>Phương thức includes hoặc eager_load cho phép bạn tải trước dữ liệu từ relation khi bạn truy cập từ một bảng.</p>



<p>Ví dụ:</p>



<pre class="wp-block-code"><code>@posts = Post.includes(:comments) # Total: 1 query
@posts = Post.eager_load(:comments) # Total: 1 query</code></pre>



<p><strong>2. Sử dụng <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">preload</mark></strong></p>



<p><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">preload</mark> là một phương pháp giúp giảm thiểu vấn đề n+1 query trong Rails. Khi bạn sử dụng preload, Rails sẽ thực hiện hai truy vấn riêng biệt: một truy vấn để lấy tất cả các dữ liệu cần thiết và một truy vấn để lấy dữ liệu liên quan. Sau đó, Rails sẽ kết hợp dữ liệu từ hai truy vấn này mà không cần thực hiện thêm bất kỳ truy vấn nào nữa, giảm thiểu số lần truy vấn đến cơ sở dữ liệu.</p>



<p>Ví dụ:</p>



<pre class="wp-block-code"><code>@posts = Post.preload(:comments)
@posts = Post.preload(:comments).where(published: true)

@posts = Post.all
ActiveRecord::Associations::Preloader.new.preload(@posts, :comments)</code></pre>



<p><strong>3. Sử dụng <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">joins</mark></strong></p>



<p>Sử dụng joins để kết hợp các bảng và truy vấn dữ liệu cùng một lúc. Điều này giúp tránh việc thực hiện nhiều truy vấn riêng lẻ.</p>



<p>Ví dụ:</p>



<pre class="wp-block-code"><code>@posts = Post.joins(:comments).select('posts.*, comments.body') # rails 6
@posts = Post.joins(:comments)
             .select(posts: {}, comments: &#91;:body]) # rails 7</code></pre>



<p><strong>4. Sử dụng <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">pluck</mark> hoặc <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">select</mark></strong></p>



<p>Thay vì lấy toàn bộ đối tượng, sử dụng pluck hoặc select để chỉ lấy những cột dữ liệu cần thiết.</p>



<p>Ví dụ:</p>



<pre class="wp-block-code"><code># Sử dụng pluck
@post_ids = Post.where(created_at: 1.week.ago..).pluck(:id)
@comments = Post.joins(:comments)
                .where(created_at: 1.week.ago..)
		.pluck('comments.id', 'comments.body')

# Sử dụng select
@comments = Comment.select(:id, :body).where(id: @post_ids)
@posts = Post.joins(:comments).select('posts.*, comments.body') # rails 6
@posts = Post.joins(:comments)
             .select(posts: {}, comments: &#91;:body]) # rails 7</code></pre>



<p><strong>5. Sử dụng <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">scope</mark></strong></p>



<p>Khi bạn muốn sử dụng preload với một phạm vi (scope) trong Rails, bạn có thể kết hợp preload với phạm vi đó để tối ưu hóa truy vấn dữ liệu của mình.</p>



<p>Ví dụ:</p>



<pre class="wp-block-code"><code>class Post &lt; ActiveRecord::Base 
  has_many :comments

  scope :published, -&gt; { where(published: true) }
end

@posts = Post.eager_load(:comments).published
@posts = Post.published.preload(:comments)

@posts_pushlished = Post.published
ActiveRecord::Associations::Preloader.new.preload(
  @posts_pushlished,
  :comments
)

@posts = Post.published.includes(:comments)
@posts = Post.published.joins(:comments)</code></pre>



<h2 id="ket-luan" class="wp-block-heading">Kết luận</h2>



<p>Bằng cách sử dụng các phương pháp như <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">includes</mark>, <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">eager_load</mark>, <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">preload</mark>, <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">joins</mark>, <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">pluck</mark>, và <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">select</mark>, bạn có thể giải quyết vấn đề N+1 query trong Rails một cách hiệu quả. Điều này không chỉ cải thiện hiệu suất ứng dụng của bạn mà còn giúp tối ưu hóa truy vấn cơ sở dữ liệu và tăng tốc độ tải trang.</p>



<h5 id="" class="wp-block-heading"><br></h5>
<p>The post <a href="https://blog.tomosia.com.vn/giai-quyet-n1-trong-rails/">Giải quyết N+1 trong rails</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/giai-quyet-n1-trong-rails/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>Rails 7.1: Mở Rộng khả Năng bảo mật với generates_token_for và signed_id</title>
		<link>https://blog.tomosia.com.vn/rails-7-1-mo-rong-kha-nang-bao-mat-voi-generates_token_for-va-signed_id/</link>
					<comments>https://blog.tomosia.com.vn/rails-7-1-mo-rong-kha-nang-bao-mat-voi-generates_token_for-va-signed_id/#comments</comments>
		
		<dc:creator><![CDATA[Minh Tang]]></dc:creator>
		<pubDate>Tue, 24 Oct 2023 17:05:43 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Rails7.1]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=1491</guid>

					<description><![CDATA[<p>Việc tạo ra những token đặc biệt, an toàn và có thể chứa thông tin về mục đích&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/rails-7-1-mo-rong-kha-nang-bao-mat-voi-generates_token_for-va-signed_id/">Rails 7.1: Mở Rộng khả Năng bảo mật với generates_token_for và signed_id</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Việc tạo ra những token đặc biệt, an toàn và có thể chứa thông tin về mục đích sử dụng cũng như thời gian hết hạn của token rất hữu ích trong một số tình huống cụ thể. Bạn có thể tạo ra một token duy nhất cho các mục đích cụ thể như <strong>authenticate access_token, reset email</strong> hoặc <strong>reset password</strong>, sau đó gán chúng vào địa chỉ URL của ứng dụng của bạn và gửi cho người dùng qua email.</p>



<h2 id="su-dung-activerecordsignedid" class="wp-block-heading">Sử dụng ActiveRecord:SignedId</h2>



<p>Từ bây giờ bạn có thể sử dụng API <code>ActiveRecord::SignedId</code> để tạo ra các token có thời hạn. Và bạn có thể dùng ActiveRecord để tìm bản ghi sử dụng signed id tương ứng</p>



<p>Hãy xem xét một tình huống trong đó chúng ta muốn gửi một liên kết đặt lại mật khẩu cho người dùng. Nếu bạn muốn tạo ra một token duy nhất có hiệu lực trong vòng 1 ngày.</p>



<pre class="wp-block-code"><code>user = User.first
signed_id = user.signed_id(expires_in: 1.day, purpose: :password_reset)

# Output signed_id
# eyJfcmFpbHMiOnsiZGF0YSI6ODg3LCJleHAiOiIyMDIzLTEwLTI1VDE2OjM2OjI4LjY1MloiLCJwdXIiOiJ1c2VyL3Bhc3N3b3JkX3Jlc2V0In19--4b1bde069dad4fa959fc111dbb401fac724cd43ab7aea772841fc90d87e42354
</code></pre>



<p>Mã <code>signed_id</code> trên sẽ có thời hạn 1 ngày và mục đích (purpose) chúng ta có thể ghi bất kỳ thứ gì củng được. Sau đó để tìm lại record từ signed_id trên thì làm như sau:</p>



<pre class="wp-block-code"><code>User.find_signed(signed_id, purpose: :password_reset)

# Output
# &lt;User:0x000000010ed60a38
</code></pre>



<p>Vì ở trên khi signed_id ta có điền purpose thì khi find chúng ta củng phải truyền lại purpose. Trường hợp không đúng thì kết quả sẽ trả về <code>nil</code>, còn khi hết hạn sẽ raise lỗi</p>



<h2 id="su-dung-activerecordbasegenerates_token_for" class="wp-block-heading">Sử dụng ActiveRecord::Base::generates_token_for</h2>



<pre class="wp-block-code"><code>class User &lt; ActiveRecord::Base
  has_secure_password

  generates_token_for :password_reset, expires_in: 1.day do
    BCrypt::Password.new(password_digest).salt&#91;-10..]
  end
end
</code></pre>



<p>Khởi tạo token</p>



<pre class="wp-block-code"><code>user = User.first
token = user.generate_token_for(:password_reset)

# Output
# eyJfcmFpbHMiOnsiZGF0YSI6Wzg4Nywid3FxLlhwdWJjLiJdLCJleHAiOiIyMDIzLTEwLTI0VDE2OjU0OjA5LjU0MloiLCJwdXIiOiJVc2VyXG5wYXNzd29yZF9yZXNldFxuNjAifX0=--8430fc9ee974752f075c78c6d...

</code></pre>



<p>Tìm record từ token đã tạo ở trên</p>



<pre class="wp-block-code"><code>User.find_by_token_for(:password_reset, token)
# Output:
# &lt;User:0x000000010ed60a38
</code></pre>



<p><code>generates_token_for</code> hoạt động tương tự như <code>signed_id</code>. Trong khi <code>signed_id</code> sử dụng model ID làm dữ liệu đầu vào, thì <code>generates_token_for</code> sử dụng sự kết hợp giữa model ID và giá trị được trả về bởi block. Block này nên tham chiếu tới một thuộc tính liên quan đến mục đích của token (Ở đây là <code>password_digest</code>). Khi thuộc tính này (password_digest) được cập nhật, dữ liệu đầu vào cũng được cập nhật và từ đó làm vô hiệu hóa token cũ.</p>



<p>Trong ví dụ trên, sự kết hợp dữ liệu đầu vào sẽ là model ID và 10 ký tự cuối cùng của Bycrypt Password</p>



<p>Khi bạn cập nhật mật khẩu, thì <code>password_digest</code> sẽ thay đổi và do đó token bị vô hiệu hóa sau lần cập nhật đầu tiên của mật khẩu. Điều này khiến cho token chỉ có thể được sử dụng một lần.</p>



<p>Trước đây với bài toán <code>reset password</code> hay <code>reset email</code> thông thường ta sẽ tạo ra 2 cột để lưu trữ (reset_email_token và reset_email_token_expired). Bây giờ sẽ không cần nửa bởi vì đã có <code>generates_token_for</code></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><em>Cảm ơn bạn đã đọc bài viết này về tính năng <code>generates_token_for</code> và <code>signed_id</code> trong Rails 7.1. Hy vọng rằng bạn đã tìm thấy thông tin hữu ích và có thêm kiến thức về cách sử dụng tính năng này để tạo ra các token đặc biệt và an toàn trong ứng dụng của mình. Nếu bạn có bất kỳ câu hỏi hoặc góp ý nào, đừng ngần ngại chia sẻ. Chúng tôi luôn đánh giá phản hồi từ độc giả. Hãy tiếp tục theo dõi và chia sẻ kiến thức về lĩnh vực phát triển ứng dụng web. Cảm ơn bạn đã ủng hộ!</em></p>
<p>The post <a href="https://blog.tomosia.com.vn/rails-7-1-mo-rong-kha-nang-bao-mat-voi-generates_token_for-va-signed_id/">Rails 7.1: Mở Rộng khả Năng bảo mật với generates_token_for và signed_id</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/rails-7-1-mo-rong-kha-nang-bao-mat-voi-generates_token_for-va-signed_id/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Length, Size, and Count in Ruby and Rails: Khi nào nên sử dụng chúng?</title>
		<link>https://blog.tomosia.com.vn/length-size-and-count-in-ruby-and-rails-khi-nao-nen-su-dung-chung/</link>
					<comments>https://blog.tomosia.com.vn/length-size-and-count-in-ruby-and-rails-khi-nao-nen-su-dung-chung/#comments</comments>
		
		<dc:creator><![CDATA[Thuan Nguyen Van]]></dc:creator>
		<pubDate>Thu, 19 Oct 2023 01:39:02 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Rails]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=1353</guid>

					<description><![CDATA[<p>Tương tự Ruby thì trong Rails cung cấp cho chúng ta nhiều cách để làm một hành động&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/length-size-and-count-in-ruby-and-rails-khi-nao-nen-su-dung-chung/">Length, Size, and Count in Ruby and Rails: Khi nào nên sử dụng chúng?</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Tương tự Ruby thì trong Rails cung cấp cho chúng ta nhiều cách để làm một hành động tương tự nhau. Ví dụ rõ ràng nhất là bài toán <strong>tìm số phần tử trong một Collection</strong>. Bạn có thể sử dụng các method <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">length</mark>, <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">size</mark> và <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">count</mark> để thực hiện việc này.</p>



<p>Tuy nhiên, bạn cảm thấy khó hiểu vì sao lại có tận 3 method và chúng khác nhau như thế nào? Khi nào nên sử dụng chúng hoặc lựa chọn chúng có ảnh hưởng đến <strong>performance</strong> của dự án hay không? Bài đăng này sẽ khám phá sự khác biệt của chúng.</p>



<p>Hãy bắt đầu với cái nhìn tổng quan về các phương thức này trong Array của Ruby. Sau đó chúng ta sẽ chuyển sang Rails.</p>



<h2 id="ruby" class="wp-block-heading">Ruby</h2>



<h3 id="1-length" class="wp-block-heading">1. Length</h3>



<p>Đây là phương thức đơn giản nhất và thân thuộc nhất trong 3 loại. Bạn có thể thấy chúng trong bất kì dự án nào bạn làm.<br><br>Method <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">length</mark> nó trả về số lượng phần tử trong một mảng.</p>



<p>Cú pháp rất đơn giản phải không nào?</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#F8F8F2;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#efefe1">Ruby</span><span role="button" tabindex="0" data-code="numbers = [1,2,3,4,5,6]

numbers.length # =&gt; 6" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F8F8F2">numbers </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> [</span><span style="color: #BD93F9">1</span><span style="color: #F8F8F2">,</span><span style="color: #BD93F9">2</span><span style="color: #F8F8F2">,</span><span style="color: #BD93F9">3</span><span style="color: #F8F8F2">,</span><span style="color: #BD93F9">4</span><span style="color: #F8F8F2">,</span><span style="color: #BD93F9">5</span><span style="color: #F8F8F2">,</span><span style="color: #BD93F9">6</span><span style="color: #F8F8F2">]</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F8F8F2">numbers.length </span><span style="color: #6272A4"># =&gt; 6</span></span></code></pre></div>



<h3 id="2-size" class="wp-block-heading">2. Size</h3>



<p>Size thực chất là alias của <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">length</mark>. Cách nó thực thi giống như <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">length</mark> vậy.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#F8F8F2;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#efefe1">Ruby</span><span role="button" tabindex="0" data-code="rubynumbers = [1,2,3,4,5,6]

numbers.size # =&gt; 6" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F8F8F2">rubynumbers </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> [</span><span style="color: #BD93F9">1</span><span style="color: #F8F8F2">,</span><span style="color: #BD93F9">2</span><span style="color: #F8F8F2">,</span><span style="color: #BD93F9">3</span><span style="color: #F8F8F2">,</span><span style="color: #BD93F9">4</span><span style="color: #F8F8F2">,</span><span style="color: #BD93F9">5</span><span style="color: #F8F8F2">,</span><span style="color: #BD93F9">6</span><span style="color: #F8F8F2">]</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F8F8F2">numbers.size </span><span style="color: #6272A4"># =&gt; 6</span></span></code></pre></div>



<p>Vậy thì khi nào sẽ sử dụng <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">length</mark> và <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">size</mark>? Đó là sử dụng tuỳ theo ngữ cảnh mà bạn đang gặp phải.<br><br>Ví dụ: Nếu tôi có một mảng <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">class_room</mark> chứa một nhóm các học sinh, tôi sẽ sử dụng <strong>class_room.size</strong> thay vì <strong>class_room.length</strong>. Mặc khác, nếu tôi sử lý một mảng các numbers, tôi sẽ sử dụng method <code>length</code>.</p>



<h3 id="3-count" class="wp-block-heading">3. Count</h3>



<p>Phương thức này thường được sử dụng để đếm số phần tử được chỉ định trong Array. Sử dụng chúng khi bạn cần tìm một phần tử phù hợp với một tiêu chí nào đó. Có 4 trường hợp sử dụng phương pháp này.<br><br><strong>3.1</strong> <strong>Nếu như không có argument và không có block, trả về số lượng tất cả các phần tử</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#F8F8F2;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#efefe1">Ruby</span><span role="button" tabindex="0" data-code="[10, 20, 30].count # =&gt; 3

[].count # =&gt; 0" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F8F8F2">[</span><span style="color: #BD93F9">10</span><span style="color: #F8F8F2">, </span><span style="color: #BD93F9">20</span><span style="color: #F8F8F2">, </span><span style="color: #BD93F9">30</span><span style="color: #F8F8F2">].count </span><span style="color: #6272A4"># =&gt; 3</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F8F8F2">[].count </span><span style="color: #6272A4"># =&gt; 0</span></span></code></pre></div>



<p><br><strong>3.2</strong> <strong>Khi có argument, trả về argument được cung cấp</strong><br></p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#F8F8F2;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#efefe1">Ruby</span><span role="button" tabindex="0" data-code="[0, 5, 10, 0.0].count(0) # =&gt; 2

[0, 1, 2].count(3) # =&gt; 0" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F8F8F2">[</span><span style="color: #BD93F9">0</span><span style="color: #F8F8F2">, </span><span style="color: #BD93F9">5</span><span style="color: #F8F8F2">, </span><span style="color: #BD93F9">10</span><span style="color: #F8F8F2">, </span><span style="color: #BD93F9">0.0</span><span style="color: #F8F8F2">].count(</span><span style="color: #BD93F9">0</span><span style="color: #F8F8F2">) </span><span style="color: #6272A4"># =&gt; 2</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F8F8F2">[</span><span style="color: #BD93F9">0</span><span style="color: #F8F8F2">, </span><span style="color: #BD93F9">1</span><span style="color: #F8F8F2">, </span><span style="color: #BD93F9">2</span><span style="color: #F8F8F2">].count(</span><span style="color: #BD93F9">3</span><span style="color: #F8F8F2">) </span><span style="color: #6272A4"># =&gt; 0</span></span></code></pre></div>



<p><br><strong>3.3</strong> <strong>Khi có block nhưng lại không có argument</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#F8F8F2;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#efefe1">Ruby</span><span role="button" tabindex="0" data-code="[0, 5, 10, 15].count { |e| e &gt; 5 } # =&gt; 2" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F8F8F2">[</span><span style="color: #BD93F9">0</span><span style="color: #F8F8F2">, </span><span style="color: #BD93F9">5</span><span style="color: #F8F8F2">, </span><span style="color: #BD93F9">10</span><span style="color: #F8F8F2">, </span><span style="color: #BD93F9">15</span><span style="color: #F8F8F2">].count { |e| e </span><span style="color: #FF79C6">&gt;</span><span style="color: #F8F8F2"> </span><span style="color: #BD93F9">5</span><span style="color: #F8F8F2"> } </span><span style="color: #6272A4"># =&gt; 2</span></span></code></pre></div>



<p><br><strong>3.4</strong> <strong>Nếu vừa có cả block và argument, nó bỏ qua block và trả về các đối số thoả điều kiện</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#F8F8F2;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#efefe1">Ruby</span><span role="button" tabindex="0" data-code="[0, 1, 2, 3].count(2) { |e| e = 0 } # =&gt; 1" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F8F8F2">[</span><span style="color: #BD93F9">0</span><span style="color: #F8F8F2">, </span><span style="color: #BD93F9">1</span><span style="color: #F8F8F2">, </span><span style="color: #BD93F9">2</span><span style="color: #F8F8F2">, </span><span style="color: #BD93F9">3</span><span style="color: #F8F8F2">].count(</span><span style="color: #BD93F9">2</span><span style="color: #F8F8F2">) { |e| e </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> </span><span style="color: #BD93F9">0</span><span style="color: #F8F8F2"> } </span><span style="color: #6272A4"># =&gt; 1</span></span></code></pre></div>



<p>Nhưng phương thức này sẽ trả ra một WARNING như bên dưới:</p>



<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" width="379" height="60" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-22.09.48.png" alt="" class="wp-image-1371" style="aspect-ratio:6.316666666666666;width:679px;height:auto" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-22.09.48.png 379w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-22.09.48-300x47.png 300w" sizes="auto, (max-width: 379px) 100vw, 379px" /></figure>



<h2 id="ruby-on-rails" class="wp-block-heading">Ruby On Rails</h2>



<p>Chúng ta sẽ lấy ví dụ từ lớp <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">ActiveRecord::Associations::CollectionProxy</mark> được kế thừa từ lớp  <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">ActiveRecord::Relation</mark>.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#F8F8F2;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#efefe1">Ruby</span><span role="button" tabindex="0" data-code="class Company &lt; ActiveRecord::Base
  has_many :company_members
end

company = Company.first
company_members = company.company_members

# CompanyMember::ActiveRecord_Associations_CollectionProxy
company_members.class " style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #FF79C6">class</span><span style="color: #F8F8F2"> </span><span style="color: #8BE9FD">Company</span><span style="color: #F8F8F2"> </span><span style="color: #FF79C6">&lt;</span><span style="color: #F8F8F2"> </span><span style="color: #8BE9FD; font-style: italic">ActiveRecord::Base</span></span>
<span class="line"><span style="color: #F8F8F2">  has_many </span><span style="color: #BD93F9">:company_members</span></span>
<span class="line"><span style="color: #FF79C6">end</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F8F8F2">company </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> </span><span style="color: #8BE9FD; font-style: italic">Company</span><span style="color: #F8F8F2">.first</span></span>
<span class="line"><span style="color: #F8F8F2">company_members </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> company.company_members</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6272A4"># CompanyMember::ActiveRecord_Associations_CollectionProxy</span></span>
<span class="line"><span style="color: #F8F8F2">company_members.class </span></span></code></pre></div>



<p>Ở ví dụ trên, <strong>comments</strong> là một <strong>Collection Proxy</strong>, bây giờ hãy tìm hiểu cách các phương thức này hoạt động trên <strong>Collection Proxy</strong>.</p>



<h3 id="1-size" class="wp-block-heading">1. Size</h3>



<p>Nếu collection chưa được query, thì phương thức <strong>size</strong> sẽ thực thi câu lệnh <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">SELECT COUNT(*)</mark>. Ngược lại thì chúng sẽ gọi <strong>collection.size</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#F8F8F2;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#efefe1">Ruby</span><span role="button" tabindex="0" data-code="Company.all.size
# SELECT &quot;companies&quot;.* FROM &quot;companies&quot;" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #8BE9FD; font-style: italic">Company</span><span style="color: #F8F8F2">.all.size</span></span>
<span class="line"><span style="color: #6272A4"># SELECT &quot;companies&quot;.* FROM &quot;companies&quot;</span></span></code></pre></div>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="701" height="398" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-55.png" alt="" class="wp-image-1373" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-55.png 701w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-55-300x170.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-55-380x216.png 380w" sizes="auto, (max-width: 701px) 100vw, 701px" /></figure>



<h3 id="2-length" class="wp-block-heading">2. Length</h3>



<p>Trả về size cua <strong>Collection</strong> bằng cách call method <strong>size</strong>.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#F8F8F2;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#efefe1">Ruby</span><span role="button" tabindex="0" data-code="Company.all.length
# SELECT &quot;companies&quot;.* FROM &quot;companies&quot;" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #8BE9FD; font-style: italic">Company</span><span style="color: #F8F8F2">.all.length</span></span>
<span class="line"><span style="color: #6272A4"># SELECT &quot;companies&quot;.* FROM &quot;companies&quot;</span></span></code></pre></div>



<p>Điều đó có nghĩa thì nếu <strong>collection</strong> đã được loaded thì method <strong>size</strong> và <strong>length</strong> tương đương nhau</p>



<p class="has-medium-font-size"><strong>Vậy khi nào nên dùng <code>size</code> vs <code>length</code>?</strong></p>



<p>Khi Collection đã được loaded thì method size và length đều như nhau.</p>



<p>Còn nếu collection không được load từ database:</p>



<ul class="wp-block-list">
<li>Nếu bạn cần vẫn cần records bất cứ lúc nào thì hãy sử dụng method <strong>length</strong>. Điều này sẽ giảm đi một truy vấn, vì Rails sẽ sử dụng các bản ghi được lưu trong bộ nhớ cache cho truy vấn sau đó.</li>



<li>Nếu bạn không cần records thì sử dụng method <strong>size</strong> sẽ hiệu quả hơn. Method này sẽ thực hiện một truy vấn COUNT SQL để lấy số lượng trực tiếp từ cơ sở dữ liệu, mà không cần tải các bản ghi vào bộ nhớ.</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="127" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-22.51.05-1024x127.png" alt="" class="wp-image-1380" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-22.51.05-1024x127.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-22.51.05-300x37.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-22.51.05-768x95.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-22.51.05-380x47.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-22.51.05-800x99.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-22.51.05-1160x144.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-22.51.05.png 1336w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h3 id="3-count-2" class="wp-block-heading">3. Count</h3>



<p>Tương tự như method <strong>count</strong> của Ruby, method <strong>count</strong> trong Rails đếm tất cả các bản ghi trong một tập hợp thỏa mãn một điều kiện cho trước. Có 2 trường hợp sử dụng:</p>



<ul class="wp-block-list">
<li>Khi không có block, trả về số lượng tất cả records trong table</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#F8F8F2;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#efefe1">Ruby</span><span role="button" tabindex="0" data-code="companies = Company.all

# SELECT COUNT(*) FROM &quot;companies&quot;
companies.count" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F8F8F2">companies </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> </span><span style="color: #8BE9FD; font-style: italic">Company</span><span style="color: #F8F8F2">.all</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6272A4"># SELECT COUNT(*) FROM &quot;companies&quot;</span></span>
<span class="line"><span style="color: #F8F8F2">companies.count</span></span></code></pre></div>



<ul class="wp-block-list">
<li>Khi có block, method <strong>count</strong> trong Rails gọi <strong>block</strong> với mỗi phần tử trong tập hợp và trả về số lượng phần tử mà khối trả về giá trị đúng (truthy).</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#F8F8F2;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#efefe1">Ruby</span><span role="button" tabindex="0" data-code="Company.all.count { |company| company.charge_firstname.include?('Be') }" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #8BE9FD; font-style: italic">Company</span><span style="color: #F8F8F2">.all.count { |company| company.charge_firstname.include?(</span><span style="color: #E9F284">&#39;</span><span style="color: #F1FA8C">Be</span><span style="color: #E9F284">&#39;</span><span style="color: #F8F8F2">) }</span></span></code></pre></div>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="844" height="61" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-23.06.06.png" alt="" class="wp-image-1381" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-23.06.06.png 844w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-23.06.06-300x22.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-23.06.06-768x56.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-23.06.06-380x27.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-23.06.06-800x58.png 800w" sizes="auto, (max-width: 844px) 100vw, 844px" /></figure>



<h2 id="ket" class="wp-block-heading">KẾT</h2>



<p>Hy vọng rằng bạn đã thấy bài viết này hữu ích và bạn đã học được điều gì đó mới. 😀</p>
<p>The post <a href="https://blog.tomosia.com.vn/length-size-and-count-in-ruby-and-rails-khi-nao-nen-su-dung-chung/">Length, Size, and Count in Ruby and Rails: Khi nào nên sử dụng chúng?</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/length-size-and-count-in-ruby-and-rails-khi-nao-nen-su-dung-chung/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
	</channel>
</rss>
