<?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>Ruby Archives - Tomoshare</title>
	<atom:link href="https://blog.tomosia.com.vn/tag/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.tomosia.com.vn/tag/ruby/</link>
	<description>Kênh chia sẻ kiến thức Tomosia Việt Nam</description>
	<lastBuildDate>Fri, 26 Jan 2024 04:33:44 +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>Ruby Archives - Tomoshare</title>
	<link>https://blog.tomosia.com.vn/tag/ruby/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>[Rails Tips] Rails 7.1 &#8211; ActiveRecord::QueryMethods#select has added support for hash values</title>
		<link>https://blog.tomosia.com.vn/rails-tips-rails-7-1-activerecordquerymethodsselect-has-added-support-for-hash-values/</link>
					<comments>https://blog.tomosia.com.vn/rails-tips-rails-7-1-activerecordquerymethodsselect-has-added-support-for-hash-values/#comments</comments>
		
		<dc:creator><![CDATA[Thuan Nguyen Van]]></dc:creator>
		<pubDate>Thu, 18 Jan 2024 01:45:59 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[Ruby On Rails]]></category>
		<category><![CDATA[Rails7.1]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=3011</guid>

					<description><![CDATA[<p>Trong bản cập nhật mới nhất của, Rails 7.1 đã cho phép chúng ta query select theo giá&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/rails-tips-rails-7-1-activerecordquerymethodsselect-has-added-support-for-hash-values/">[Rails Tips] Rails 7.1 &#8211; ActiveRecord::QueryMethods#select has added support for hash values</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Trong bản cập nhật mới nhất của, Rails 7.1 đã cho phép chúng ta query <strong>select</strong> theo giá trị hash chứ không cần phải sử dụng <strong>raw SQL</strong> nữa.</p>



<p>💎 Improvements:<br>1️⃣ New support query với giá trị <strong>Hash</strong><br>2️⃣ Chúng ta không cần phải dùng truy vấn <strong>raw version</strong> nữa</p>



<p>💎 Bonus:<br>1️⃣ Cú pháp mới cũng support chúng ta sử dụng <strong>alias</strong><br>2️⃣ Sử dụng tương tự cho ActiveRecord#reselect</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:#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="# Before Rails 7.1

Post.joins(:comments)
    .select(
      &quot;posts.id as post_id, posts.title as post_title,
      comments.id as comment_id, comments.body as comment_body&quot;
    )
    
Post.joins(:comments).select(:id, :title, &quot;comments.body&quot;)

# After Rails 7.1

Post.joins(:comments)
    .select(
      posts: { id: :post_id, title: :post_title },
      comments: { id: :comments_id, body: :comment_body }
    )
    
Post.joins(:comments).select(:id, :title, comments: [:body] )" 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"># Before Rails 7.1</span></span>
<span class="line"></span>
<span class="line"><span style="color: #97E1F1; font-style: italic">Post</span><span style="color: #F6F6F4">.joins(</span><span style="color: #BF9EEE">:comments</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">    .</span><span style="color: #97E1F1">select</span><span style="color: #F6F6F4">(</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">posts.id as post_id, posts.title as post_title,</span></span>
<span class="line"><span style="color: #E7EE98">      comments.id as comment_id, comments.body as comment_body</span><span style="color: #DEE492">&quot;</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: #97E1F1; font-style: italic">Post</span><span style="color: #F6F6F4">.joins(</span><span style="color: #BF9EEE">:comments</span><span style="color: #F6F6F4">).</span><span style="color: #97E1F1">select</span><span style="color: #F6F6F4">(</span><span style="color: #BF9EEE">:id</span><span style="color: #F6F6F4">, </span><span style="color: #BF9EEE">:title</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">comments.body</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #7B7F8B"># After Rails 7.1</span></span>
<span class="line"></span>
<span class="line"><span style="color: #97E1F1; font-style: italic">Post</span><span style="color: #F6F6F4">.joins(</span><span style="color: #BF9EEE">:comments</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">    .</span><span style="color: #97E1F1">select</span><span style="color: #F6F6F4">(</span></span>
<span class="line"><span style="color: #F6F6F4">      posts</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> { id</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">:post_id</span><span style="color: #F6F6F4">, title</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">:post_title</span><span style="color: #F6F6F4"> },</span></span>
<span class="line"><span style="color: #F6F6F4">      comments</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> { id</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">:comments_id</span><span style="color: #F6F6F4">, body</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">:comment_body</span><span style="color: #F6F6F4"> }</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: #97E1F1; font-style: italic">Post</span><span style="color: #F6F6F4">.joins(</span><span style="color: #BF9EEE">:comments</span><span style="color: #F6F6F4">).</span><span style="color: #97E1F1">select</span><span style="color: #F6F6F4">(</span><span style="color: #BF9EEE">:id</span><span style="color: #F6F6F4">, </span><span style="color: #BF9EEE">:title</span><span style="color: #F6F6F4">, comments</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> [</span><span style="color: #BF9EEE">:body</span><span style="color: #F6F6F4">] )</span></span></code></pre></div>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="956" height="551" src="http://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2024-01-02-at-14.42.49.png" alt="" class="wp-image-3016" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2024-01-02-at-14.42.49.png 956w, https://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2024-01-02-at-14.42.49-300x173.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2024-01-02-at-14.42.49-768x443.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2024-01-02-at-14.42.49-380x219.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2024-01-02-at-14.42.49-800x461.png 800w" sizes="(max-width: 956px) 100vw, 956px" /></figure>
<p>The post <a href="https://blog.tomosia.com.vn/rails-tips-rails-7-1-activerecordquerymethodsselect-has-added-support-for-hash-values/">[Rails Tips] Rails 7.1 &#8211; ActiveRecord::QueryMethods#select has added support for hash values</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/rails-tips-rails-7-1-activerecordquerymethodsselect-has-added-support-for-hash-values/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
		<item>
		<title>What&#8217;s new in Ruby 3.3.0</title>
		<link>https://blog.tomosia.com.vn/ruby-3-3-0/</link>
					<comments>https://blog.tomosia.com.vn/ruby-3-3-0/#comments</comments>
		
		<dc:creator><![CDATA[Dang Van Luan]]></dc:creator>
		<pubDate>Tue, 26 Dec 2023 01:57:49 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=2726</guid>

					<description><![CDATA[<p>Là một developer có niềm đam mê sâu sắc với Ruby thì chúng ta đều biết vào Giáng&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/ruby-3-3-0/">What&#8217;s new in Ruby 3.3.0</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Là một developer có niềm đam mê sâu sắc với Ruby thì chúng ta đều biết vào Giáng sinh hằng năm, Ruby core team sẽ release version Ruby mới. Và năm nay cũng không ngoại lệ, chúng ta sẽ đón chờ phiên bản Ruby 3.3 vào tuần tới.</p>



<p>Mặc dù không có nhiều thay đổi lớn về các tính năng ngôn ngữ như các phiên bản trước, nhưng trong phiên bản này, trọng tâm chính là hiệu suất và trải nghiệm phát triển. Dưới đây là một số điểm nổi bật của phiên bản này:</p>



<h3 id="yjit" class="wp-block-heading">YJIT</h3>



<p>YJIT, trình biên dịch JIT của Ruby, đã có những cải tiến đáng kể trong vài năm qua. Trong năm nay, nó tiếp tục trở nên <a href="https://railsatscale.com/2023-12-04-ruby-3-3-s-yjit-faster-while-using-less-memory/">nhanh hơn, đồng thời tiêu thụ ít bộ nhớ hơn.</a></p>



<p>Các công ty như <a href="https://dev.37signals.com/yjit-is-fast/">Basecamp</a> và <a href="https://railsatscale.com/2023-09-18-ruby-3-3-s-yjit-runs-shopify-s-production-code-15-faster/">Shopify</a> đã sử dụng phiên bản xem trước của 3.3 trong môi trường production và đã thấy sự cải thiện khoảng 15% trong thời gian phản hồi trung bình so với phiên bản 3.3.0 không có YJIT. <br>Thực tế, YJIT đã rất hiệu quả trong việc tăng tốc ứng dụng Rails và nó sẽ được kích hoạt mặc định trên ứng dụng Rails mới nếu sử dụng Ruby 3.3.</p>



<p>Một phương thức mới, RubyVM::YJIT.enable đã được giới thiệu, cho phép bạn kích hoạt YJIT khi đang chạy. Điều này có thể hữu ích nếu bạn muốn tải ứng dụng nhanh chóng và sau đó kích hoạt YJIT sau khi nó đã khởi động. Đây chính là cách Rails sử dụng để kích hoạt JIT trong một bộ khởi tạo.</p>



<h3 id="rjit" class="wp-block-heading">RJIT</h3>



<p>Một trình biên dịch JIT thử nghiệm có tên là RJIT đã được giới thiệu. Được viết bằng Ruby thuần, nó thay thế MJIT, một JIT thay thế khác đã có sẵn trong Ruby 3.2. RJIT sử dụng nhiều bộ nhớ hơn so với YJIT và chỉ tồn tại cho mục đích thử nghiệm. Trong môi trường sản xuất, vẫn nên sử dụng YJIT.</p>



<h3 id="irb" class="wp-block-heading">IRB</h3>



<p>Từ khi biết đến Ruby, pry là công cụ gỡ lỗi ưa thích của mình, mình đã chuyển sang sử dụng IRB gần đây, sau khi biết tới <a href="http://blog.tomosia.com.vn/debug-trong-ruby-ma-khong-can-dung-thu-vien/">bài viết này</a>. Trong phiên bản này, IRB và integration của nó với gem debug đã được cải thiện đến mức pry và byebug không còn cần thiết cho việc gỡ lỗi mã nguồn của bạn.</p>



<h3 id="range" class="wp-block-heading">Range</h3>



<h4 id="rails-rangeoverlapsrange" class="wp-block-heading"><em>Rails Range#overlaps?(range)</em></h4>



<p>So sánh hai phạm vi và xem liệu chúng có trùng lặp với nhau không. <code>overlap?</code> trả về <code>true</code> nếu hai phạm vi trùng nhau nếu không thì trả về <code>false</code>.</p>



<pre class="wp-block-code"><code>(3..8).overlaps?(8..10) # => true
(2..43).overlaps?(3..5) # => true
(1..5).overlaps?(7..9) # => false

('a'..'z').overlaps?('c'..'d') # => true

(1.day.from_now..5.days.from_now).overlaps?(5.days.from_now..10.days.from_now) # => false
(1.day.from_now.to_date..5.days.from_now.to_date).overlaps?(5.days.from_now.to_date..10.days.from_now.to_date) # => true

(3...8).overlaps?(8...9) # => false
(3...8).overlaps?(7...9) # => true

# works similarly for open ranges.
(3..).overlaps?(...3) # => false</code></pre>



<h4 id="ruby-3-3" class="wp-block-heading"><em>Ruby &lt; 3.3</em></h4>



<p>Không giống như Rails, Ruby không có phương thức nào để so sánh hai phạm vi và kiểm tra chúng có trùng nhau hay không.</p>



<p>Trước Ruby 3.3, nếu chúng ta muốn kiểm tra sự trùng lặp, chúng ta cần sử dụng phương thức <code>cover</code>, nó sẽ trả về true nếu hai phạm vi trùng nhau.</p>



<pre class="wp-block-code"><code><em># Check if range1 covers any value in range2 or vice versa</em>
range1 = (3..8)
range2 = (8..10)
range1.cover?(range2.first) || range2.cover?(range1.first) <em># =&gt; true</em>

range1 = ('a'..'z')
range2 = ('c'..'d')
range1.cover?(range2.first) || range2.cover?(range1.first) <em># =&gt; true</em>

range1 = (1.day.from_now..5.days.from_now)
range2 = (5.days.from_now..10.days.from_now)
range1.cover?(range2.first) || range2.cover?(range1.first) <em># =&gt; false</em>

range1 = (1.day.from_now.to_date..5.days.from_now.to_date)
range2 = (5.days.from_now.to_date..10.days.from_now.to_date)
range1.cover?(range2.first) || range2.cover?(range1.first) <em># =&gt; true</em></code></pre>



<h4 id="ruby-3-3-2" class="wp-block-heading"><em>Ruby 3.3</em></h4>



<p>Ruby 3.3 giới thiệu phương thức <code>Range#overlap?(range)</code>. Giống như Rails, chúng ta có thể sử dụng <code>overlap?</code> để so sánh hai phạm vi và xem chúng có trùng lặp với nhau không.</p>



<ul class="wp-block-list">
<li>Nó trả về true nếu hai phạm vi trùng nhau nếu không thì trả về sai.</li>



<li>Nó sẽ raise TypeError nếu argument không phải kiểu range</li>
</ul>



<pre class="wp-block-code"><code>range1 = (3..8)
range2 = (8..10)
range1.overlap?(range2) # => true

range1 = ('a'..'z')
range2 = ('c'..'d')
range1.overlap?(range2) # => true

range1 = (1.day.from_now..5.days.from_now)
range2 = (5.days.from_now..10.days.from_now)
range1.overlap?(range2) # => false

range1 = (1.day.from_now.to_date..5.days.from_now.to_date)
range2 = (5.days.from_now.to_date..10.days.from_now.to_date)
range1.overlap?(range2) # => true

(3..).overlap?(...3) # => false

(3..8).overlap?(3) # => TypeError, argument must be Range</code></pre>



<h3 id="tham-khao" class="wp-block-heading"><br>Tham khảo</h3>



<p><br>https://www.ruby-lang.org/en/news/2023/12/11/ruby-3-3-0-rc1-released/<br>https://railsatscale.com/2023-09-18-ruby-3-3-s-yjit-runs-shopify-s-production-code-15-faster/<br>https://railsatscale.com/2023-12-04-ruby-3-3-s-yjit-faster-while-using-less-memory/<br><br></p>
<p>The post <a href="https://blog.tomosia.com.vn/ruby-3-3-0/">What&#8217;s new in Ruby 3.3.0</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/ruby-3-3-0/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
		<item>
		<title>Hiểu thêm về JSON trong Ruby</title>
		<link>https://blog.tomosia.com.vn/hieu-them-ve-json-trong-ruby/</link>
					<comments>https://blog.tomosia.com.vn/hieu-them-ve-json-trong-ruby/#comments</comments>
		
		<dc:creator><![CDATA[Thâm Davies]]></dc:creator>
		<pubDate>Mon, 11 Dec 2023 09:28:45 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[json in ruby]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=2531</guid>

					<description><![CDATA[<p>Trong bài này mình muốn chia sẻ một vài thứ hay ho trong method JSON.parse trong Ruby. Let’s&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/hieu-them-ve-json-trong-ruby/">Hiểu thêm về JSON trong Ruby</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Trong bài này mình muốn chia sẻ một vài thứ hay ho trong method <code>JSON.parse</code> trong Ruby. Let’s jump in 👇</p>



<p>Trong Ruby, phương thức <code>JSON.parse</code> dùng để parse chuỗi JSON và chuyển đổi nó thành cấu trúc dữ liệu của Ruby, thường là hash hay array. Chúng ta cũng có thể truyền hai tham số là: <code>object_class</code> và <code>symbolize_names</code>.</p>



<ul class="wp-block-list">
<li>object_class: cho phép bạn chỉ định lớp sẽ được sử dụng để khởi tạo đối tượng cho JSON.</li>



<li>symbolize_names: nếu bạn truyền tham số <code>symbolize_names</code> với giá trị là true thì key của object sau khi parse là symbol chứ không phải string như mặc định</li>
</ul>



<figure class="wp-block-image size-large"><img decoding="async" src="https://i.imgur.com/4hv0Gym.png" alt=""/></figure>



<p>Link code: <a href="https://gist.github.com/thamdavies/2780c45d214546caf8b1d83fb6c70e53">Gist</a></p>



<p>Bài viết gốc: <a href="https://www.thamdavies.com/blog/hieu-them-ve-json-trong-ruby">thamdavies.com</a></p>



<p>That’s it. Happy coding 💯</p>
<p>The post <a href="https://blog.tomosia.com.vn/hieu-them-ve-json-trong-ruby/">Hiểu thêm về JSON trong Ruby</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/hieu-them-ve-json-trong-ruby/feed/</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
			</item>
		<item>
		<title>Ruby 3.0 đã chính thức hỗ trợ Pattern Matching</title>
		<link>https://blog.tomosia.com.vn/ruby-3-0-da-chinh-thuc-ho-tro-pattern-matching/</link>
					<comments>https://blog.tomosia.com.vn/ruby-3-0-da-chinh-thuc-ho-tro-pattern-matching/#comments</comments>
		
		<dc:creator><![CDATA[Minh Tang]]></dc:creator>
		<pubDate>Mon, 11 Dec 2023 02:25:03 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=2508</guid>

					<description><![CDATA[<p>Pattern Matching trong Ruby cho phép giải cấu trúc dữ liệu một cách ngắn gọn, giúp dễ dàng&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/ruby-3-0-da-chinh-thuc-ho-tro-pattern-matching/">Ruby 3.0 đã chính thức hỗ trợ Pattern Matching</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Pattern Matching trong Ruby cho phép giải cấu trúc dữ liệu một cách ngắn gọn, giúp dễ dàng gán giá trị cho các biến với cú pháp rõ ràng. Pattern matching là một tính năng đã được giới thiệu trong Ruby 2.7. Từ Ruby 3.0 trở đi, nó không còn là một tính năng thử nghiệm nữa và chúng ta có thể bắt đầu sử dụng nó một cách chính thức.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Warning Ruby 2.7: Pattern matching is experimental, and the behavior may change in future versions of Ruby!</p>
</blockquote>



<h2 id="pattern-matching-la-gi" class="wp-block-heading">Pattern Matching là gì?</h2>



<p>Pattern matching là một tính năng cho phép bạn so sánh và hiểu cấu trúc dữ liệu. Điều này được thực hiện bằng cách kiểm tra cách thông tin được tổ chức và gán các phần tương ứng cho các biến cục bộ để sử dụng sau này.</p>



<p>Pattern Matching được hỗ trợ thông qua cú pháp <strong>case / in</strong>. Quan trọng là không nhầm lẫn với <strong>case / when</strong> và không kết hợp chúng. Nếu không có sự phù hợp với bất kỳ biểu thức nào và không có định nghĩa <code>else</code>, thì một ngoại lệ <code>NoMatchingPatternError</code> sẽ được raise</p>



<pre class="wp-block-code"><code>case &lt;expression&gt;
in &lt;pattern1&gt;
  # ...
in &lt;pattern2&gt;
  # ...
else
  # ...
end
</code></pre>



<p>Pattern có thể là:</p>



<ul class="wp-block-list">
<li><strong>Value</strong>: Any Ruby object (compared with the === operator, as in ‘when’).</li>



<li><strong>Array</strong>: Array pattern:&nbsp;<strong><code>[&lt;subpattern&gt;, &lt;subpattern&gt;, &lt;subpattern&gt;, &lt;subpattern&gt;, ...]</code></strong>.</li>



<li><strong>Find</strong>: Search pattern:&nbsp;<strong><code>[*variable, &lt;subpattern&gt;, &lt;subpattern&gt;, &lt;subpattern&gt;, &lt;subpattern&gt;, ..., *variable]</code></strong>.</li>



<li><strong>Hash</strong>: Hash pattern:&nbsp;<strong><code>{key: &lt;subpattern&gt;, key: &lt;subpattern&gt;, ...}</code></strong>.</li>



<li><strong>Alternative</strong>: Pattern combination with&nbsp;<strong><code>|</code></strong>&nbsp;(vertical bar).</li>



<li><strong>Variable capture</strong>:&nbsp;<strong><code>&lt;pattern&gt; =&gt; variable</code></strong>&nbsp;or&nbsp;<strong><code>variable</code></strong>.</li>
</ul>



<h2 id="dinh-nghia-pattern-matching" class="wp-block-heading">Định nghĩa Pattern Matching</h2>



<pre class="wp-block-code"><code># Define a method that uses pattern matching with case/in
def process_data(data)
  case data
  in { type: "number", value: Integer =&gt; num }
    puts "Received a number: #{num}"
  in { type: "string", value: String =&gt; str }
    puts "Received a string: #{str}"
  in { type: "array", value: Array =&gt; arr }
    puts "Received an array: #{arr}"
  in { type: "hash", value: Hash =&gt; hash }
    puts "Received a hash: #{hash}"
  else
    puts "Received something else."
  end
end

# Test the method with different data structures
process_data({ type: "number", value: 42 })               # Output: Received a number: 42
process_data({ type: "string", value: "Hello, Ruby!" })   # Output: Received a string: Hello, Ruby!
process_data({ type: "array", value: &#91;1, 2, 3] })         # Output: Received an array: &#91;1, 2, 3]
process_data({ type: "hash", value: { key: "value" } })   # Output: Received a hash: {:key=&gt;"value"}
process_data({ type: "unknown", value: "unknown data" })  # Output: Received something else.
</code></pre>



<h3 id="deconstruct-va-deconstruct_keys" class="wp-block-heading">Deconstruct và Deconstruct_keys</h3>



<p>Đây là hai phương thức đặc biệt trong pattern matching: <code>deconstruct</code>, được gọi khi đánh giá trên một <strong>Array</strong>, và <code>deconstruct_keys</code> được gọi khi đánh giá trên một <strong>Hash</strong>. Hãy xem một ví dụ:</p>



<pre class="wp-block-code"><code>class Coordinates
  attr_accessor :x, :y

  def initialize(x, y)
    @x = x
    @y = y
  end

  def deconstruct
    &#91;@x, @y]
  end

  def deconstruct_key
    {x: @x, y: @y}
  end
end
</code></pre>



<p>Khi một thể hiện của lớp Coordinate được đánh giá trên một Array</p>



<pre class="wp-block-code"><code>c = Coordinates.new(32,50)

case c
in &#91;a,b]
  p a #=&gt; 32
  p b #=&gt; 50
end
</code></pre>



<p>Khi một thể hiện của lớp Coordinate được đánh giá trên một Hash</p>



<pre class="wp-block-code"><code>case c
in {x:, y:}
  p x #=&gt; 32
  p y #=&gt; 50
end
</code></pre>



<p>Nếu class không có 2 methods trên thì sẽ báo lỗi</p>



<pre class="wp-block-code"><code>#&lt;Coordinate:0x000000010d27fb10 @x=32, @y=50&gt;: #&lt;Coordinate:0x000000010d27fb10 @x=32, @y=50&gt; does not respond to #deconstruct (NoMatchingPatternError)
</code></pre>



<p>Tham khảo thêm tại: <a href="https://docs.ruby-lang.org/en/master/syntax/pattern_matching_rdoc.html">https://docs.ruby-lang.org/en/master/syntax/pattern_matching_rdoc.html</a></p>
<p>The post <a href="https://blog.tomosia.com.vn/ruby-3-0-da-chinh-thuc-ho-tro-pattern-matching/">Ruby 3.0 đã chính thức hỗ trợ Pattern Matching</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/ruby-3-0-da-chinh-thuc-ho-tro-pattern-matching/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Hiểu hơn về method Uniq trong Ruby</title>
		<link>https://blog.tomosia.com.vn/hieu-hon-ve-method-uniq-trong-ruby/</link>
					<comments>https://blog.tomosia.com.vn/hieu-hon-ve-method-uniq-trong-ruby/#comments</comments>
		
		<dc:creator><![CDATA[NST]]></dc:creator>
		<pubDate>Wed, 29 Nov 2023 04:04:56 +0000</pubDate>
				<category><![CDATA[Kinh nghiệm]]></category>
		<category><![CDATA[Ruby]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=2007</guid>

					<description><![CDATA[<p>Hầu như tất cả mọi người đã biết method uniq được sử dụng với mục đích để xoá&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/hieu-hon-ve-method-uniq-trong-ruby/">Hiểu hơn về method Uniq trong Ruby</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Hầu như tất cả mọi người đã biết method <strong>uniq</strong> được sử dụng với mục đích để xoá những phần tử trùng nhau trong 1 array.</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:#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">Ruby</span><span role="button" tabindex="0" data-code="n = [1,1,1,2,3,4,5]
n.uniq
# [1,2,3,4,5]" 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">n </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> [</span><span style="color: #BF9EEE">1</span><span style="color: #F6F6F4">,</span><span style="color: #BF9EEE">1</span><span style="color: #F6F6F4">,</span><span style="color: #BF9EEE">1</span><span style="color: #F6F6F4">,</span><span style="color: #BF9EEE">2</span><span style="color: #F6F6F4">,</span><span style="color: #BF9EEE">3</span><span style="color: #F6F6F4">,</span><span style="color: #BF9EEE">4</span><span style="color: #F6F6F4">,</span><span style="color: #BF9EEE">5</span><span style="color: #F6F6F4">]</span></span>
<span class="line"><span style="color: #F6F6F4">n.uniq</span></span>
<span class="line"><span style="color: #7B7F8B"># [1,2,3,4,5]</span></span></code></pre></div>



<p>Tuy nhiên, đối với những mảng phức tạp hơn, hoặc <strong>uniq</strong> theo điều kiện cụ thể thì mọi người sẽ đa số sẽ sử dụng <strong>loop in loop</strong> hoặc thử bất cứ thứ gì mọi người tìm được trên <em><strong>Stack Overflow</strong></em> thay vì vào document để tìm giải pháp. Mình cũng như thế và hầu như là đều như thế =))</p>



<figure class="wp-block-image size-full"><img decoding="async" width="640" height="537" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/aa.png" alt="" class="wp-image-2008" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/aa.png 640w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/aa-300x252.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/aa-380x319.png 380w" sizes="(max-width: 640px) 100vw, 640px" /></figure>



<p>Vào một ngày đẹp trời và KH thay đổi spec muốn mình uniq những users có cùng score và local. Sau tỉ tỉ vòng lặp và vô số lần nghi ngờ thì mình lại vào document và tìm được giải pháp có thể giải quyết vấn đề của mình. =))</p>



<p>Chắc mình cũng sẽ dần dần thay đổi mindset ở trên vì mình cảm thấy như thế sẽ tốt hơn với mình =))</p>



<p>Lan man quá lâu rồi chúng ta quay lại phần chính nha.</p>



<p>Nhiều người chưa biết rằng <strong>uniq</strong> có thể được sử dụng như 1 block, do đó bạn có sử dụng <strong>uniq</strong> nâng cao hơn.</p>



<p><strong>Uniq With Multiple Conditions</strong></p>



<ul class="wp-block-list">
<li>Có thể sử dụng nhiều điều kiện đối với 1 mảng hash!</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: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="users = [{name: 'a1', score: 1, local: 'danang'}, 
					{name: 'a2', score: 1, local: 'danang'},
					{name: 'a3', score: 1, local: 'danang'},
					{name: 'a4', score: 2, local: 'hanoi'},
					{name: 'a5', score: 2, local: 'hanoi'},
					{name: 'a6', score: 3, local: 'hanoi'}
				]

users.uniq { |user| [user[:score], user[:local]] }

#OUTPUT:
[{:name=&gt;&quot;a1&quot;, :score=&gt;1, :local=&gt;&quot;danang&quot;},
 {:name=&gt;&quot;a4&quot;, :score=&gt;2, :local=&gt;&quot;hanoi&quot;},
 {:name=&gt;&quot;a6&quot;, :score=&gt;3, :local=&gt;&quot;hanoi&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: #F6F6F4">users </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> [{name</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">a1</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, score</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">1</span><span style="color: #F6F6F4">, local</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">danang</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">}, </span></span>
<span class="line"><span style="color: #F6F6F4">					{name</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">a2</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, score</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">1</span><span style="color: #F6F6F4">, local</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">danang</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">},</span></span>
<span class="line"><span style="color: #F6F6F4">					{name</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">a3</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, score</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">1</span><span style="color: #F6F6F4">, local</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">danang</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">},</span></span>
<span class="line"><span style="color: #F6F6F4">					{name</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">a4</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, score</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">2</span><span style="color: #F6F6F4">, local</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">hanoi</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">},</span></span>
<span class="line"><span style="color: #F6F6F4">					{name</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">a5</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, score</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">2</span><span style="color: #F6F6F4">, local</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">hanoi</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">},</span></span>
<span class="line"><span style="color: #F6F6F4">					{name</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">a6</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, score</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">3</span><span style="color: #F6F6F4">, local</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">hanoi</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 style="color: #F6F6F4">users.uniq { |user| [user[</span><span style="color: #BF9EEE">:score</span><span style="color: #F6F6F4">], user[</span><span style="color: #BF9EEE">:local</span><span style="color: #F6F6F4">]] }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #7B7F8B">#OUTPUT:</span></span>
<span class="line"><span style="color: #F6F6F4">[{</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4">name</span><span style="color: #F286C4">=&gt;</span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">a1</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">, </span><span style="color: #F286C4">:</span><span style="color: #F6F6F4">score</span><span style="color: #F286C4">=&gt;</span><span style="color: #BF9EEE">1</span><span style="color: #F6F6F4">, </span><span style="color: #F286C4">:</span><span style="color: #F6F6F4">local</span><span style="color: #F286C4">=&gt;</span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">danang</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">},</span></span>
<span class="line"><span style="color: #F6F6F4"> {</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4">name</span><span style="color: #F286C4">=&gt;</span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">a4</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">, </span><span style="color: #F286C4">:</span><span style="color: #F6F6F4">score</span><span style="color: #F286C4">=&gt;</span><span style="color: #BF9EEE">2</span><span style="color: #F6F6F4">, </span><span style="color: #F286C4">:</span><span style="color: #F6F6F4">local</span><span style="color: #F286C4">=&gt;</span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">hanoi</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">},</span></span>
<span class="line"><span style="color: #F6F6F4"> {</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4">name</span><span style="color: #F286C4">=&gt;</span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">a6</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">, </span><span style="color: #F286C4">:</span><span style="color: #F6F6F4">score</span><span style="color: #F286C4">=&gt;</span><span style="color: #BF9EEE">3</span><span style="color: #F6F6F4">, </span><span style="color: #F286C4">:</span><span style="color: #F6F6F4">local</span><span style="color: #F286C4">=&gt;</span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">hanoi</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">}]</span></span></code></pre></div>



<p><strong>Uniq Method With A Block</strong></p>



<ul class="wp-block-list">
<li>Bạn có thể đặt mọi thứ mà bạn nghĩ nó có thể dùng làm rules khi <strong>uniq.</strong></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.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">Ruby</span><span role="button" tabindex="0" data-code="fruits = %w(orange apple banana)
# 'Orange' and 'Apple' **length of 6 characters**

fruits.uniq(&amp;:size)
# [&quot;orange&quot;, &quot;apple&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: #F6F6F4">fruits </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">%</span><span style="color: #F6F6F4">w(orange apple banana)</span></span>
<span class="line"><span style="color: #7B7F8B"># &#39;Orange&#39; and &#39;Apple&#39; **length of 6 characters**</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">fruits.uniq(</span><span style="color: #F286C4">&amp;</span><span style="color: #BF9EEE">:size</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #7B7F8B"># [&quot;orange&quot;, &quot;apple&quot;]</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">Ruby</span><span role="button" tabindex="0" data-code="objects = [1, 2, &quot;a&quot;, &quot;b&quot;, :c, :d]
# 1, 2 -&gt; Integer; 'a', 'b'-&gt; String; :c, :d -&gt; Symbol
 
objects.uniq(&amp;:class)
#[1, &quot;a&quot;, :c]
" 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">objects </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> [</span><span style="color: #BF9EEE">1</span><span style="color: #F6F6F4">, </span><span style="color: #BF9EEE">2</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">a</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">b</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">, </span><span style="color: #BF9EEE">:c</span><span style="color: #F6F6F4">, </span><span style="color: #BF9EEE">:d</span><span style="color: #F6F6F4">]</span></span>
<span class="line"><span style="color: #7B7F8B"># 1, 2 -&gt; Integer; &#39;a&#39;, &#39;b&#39;-&gt; String; :c, :d -&gt; Symbol</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">objects.uniq(</span><span style="color: #F286C4">&amp;</span><span style="color: #BF9EEE">:class</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #7B7F8B">#[1, &quot;a&quot;, :c]</span></span>
<span class="line"></span></code></pre></div>



<p>Qua bài viết, mình hi vọng có thể giúp bạn giải quyết được những vấn đề của bản thân trong tương lai.</p>



<p>Cảm ơn vì đã đọc!</p>



<p>Sources: <a href="https://www.rubyguides.com/2019/08/ruby-uniq-method/">https://www.rubyguides.com/2019/08/ruby-uniq-method/</a></p>
<p>The post <a href="https://blog.tomosia.com.vn/hieu-hon-ve-method-uniq-trong-ruby/">Hiểu hơn về method Uniq trong Ruby</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/hieu-hon-ve-method-uniq-trong-ruby/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
		<item>
		<title>Building a GraphQL API in Rails</title>
		<link>https://blog.tomosia.com.vn/building-a-graphql-api-in-rails/</link>
					<comments>https://blog.tomosia.com.vn/building-a-graphql-api-in-rails/#comments</comments>
		
		<dc:creator><![CDATA[Hổ Nguyễn]]></dc:creator>
		<pubDate>Wed, 29 Nov 2023 02:55:14 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby On Rails]]></category>
		<category><![CDATA[GraphQL]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=2050</guid>

					<description><![CDATA[<p>Trong thế giới phát triển web, API (Giao diện Lập trình Ứng dụng) đóng vai trò quan trọng&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/building-a-graphql-api-in-rails/">Building a GraphQL API in Rails</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Trong thế giới phát triển web, API (Giao diện Lập trình Ứng dụng) đóng vai trò quan trọng trong việc kích thích sự giao tiếp giữa các hệ thống phần mềm khác nhau. GraphQL, một ngôn ngữ truy vấn dành cho API, đã thu hút sự chú ý lớn với tính linh hoạt và hiệu suất cao trong việc truy xuất dữ liệu.</p>



<p>Trong bài đăng blog này, chúng ta sẽ khám phá quá trình xây dựng một GraphQL API trong Ruby on Rails, một framework mạnh mẽ và thân thiện với nhà phát triển.</p>



<h2 id="graphql-la-gi" class="wp-block-heading">GraphQL là gì?</h2>



<p>GraphQL là một ngôn ngữ truy vấn dành cho API và là một runtime để thực hiện những truy vấn đó đối với dữ liệu của bạn. Khác với các API REST truyền thống, nơi máy khách có kiểm soát hạn chế về dữ liệu mà nó nhận được, GraphQL cho phép máy khách yêu cầu chỉ những dữ liệu cần thiết. Điều này dẫn đến quá trình truy xuất dữ liệu hiệu quả và chính xác hơn.</p>



<h2 id="thiet-lap-du-an-rails" class="wp-block-heading">Thiết Lập Dự Án Rails</h2>



<p>Trước khi đào sâu vào GraphQL, hãy thiết lập một dự án Rails mới. Mở terminal và chạy các lệnh sau:</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:#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">Bash</span><span role="button" tabindex="0" data-code="rails new graphql_api 
cd graphql_api" 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: #62E884">rails</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">new</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">graphql_api</span><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #97E1F1">cd</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">graphql_api</span></span></code></pre></div>



<h2 id="them-dependencies" class="wp-block-heading">Thêm Dependencies</h2>



<p>Để tích hợp GraphQL vào dự án Rails của bạn, bạn sẽ cần thêm một số gems vào Gemfile. Mở Gemfile và bao gồm các dòng sau:</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:#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">Ruby</span><span role="button" tabindex="0" data-code="# Gemfile 

gem 'graphql' 
gem 'graphiql-rails', group: :development" 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: #F6F6F4">gem </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">graphql</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">gem </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">graphiql-rails</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, group</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">:development</span></span></code></pre></div>



<p>Chạy <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color"><code>bundle install</code> </mark>để cài đặt các gems này.</p>



<h2 id="tao-schema-graphql" class="wp-block-heading">Tạo Schema GraphQL</h2>



<p>Trong GraphQL, schema xác định các loại và các hoạt động có thể thực hiện trên dữ liệu của bạn. Hãy tạo một schema đơn giản cho ứng dụng blog. Chạy lệnh sau để tạo một schema GraphQL mới:</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:#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">Bash</span><span role="button" tabindex="0" data-code="rails generate graphql:install" 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: #62E884">rails</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">generate</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">graphql:install</span></span></code></pre></div>



<p>Lệnh này sẽ tạo một thư mục <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">graphql</mark></code> trong thư mục dự án của bạn, chứa một tệp schema cơ bản (<code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">app/graphql/types/query_type.rb</mark></code>). Tùy chỉnh tệp này để xác định schema GraphQL của bạn.</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:#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="# app/graphql/types/query_type.rb 

module Types 
  class QueryType &lt; Types::BaseObject 
    field :posts, [Types::PostType], null: false 
    
    def posts 
      Post.all
    end 
  end 
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: #7B7F8B"># app/graphql/types/query_type.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">Types</span><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">QueryType</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">&lt;</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">Types::BaseObject</span><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    field </span><span style="color: #BF9EEE">:posts</span><span style="color: #F6F6F4">, [</span><span style="color: #97E1F1; font-style: italic">Types</span><span style="color: #F286C4">::</span><span style="color: #BF9EEE">PostType</span><span style="color: #F6F6F4">], null</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">false</span><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">def</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">posts</span><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #97E1F1; font-style: italic">Post</span><span style="color: #F6F6F4">.all</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">end</span><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #F286C4">end</span><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F286C4">end</span></span></code></pre></div>



<h2 id="dinh-nghia-cac-loai" class="wp-block-heading">Định Nghĩa Các Loại</h2>



<p>Trong ví dụ này, chúng ta đã tạo một trường <code><strong>posts</strong></code> trả về một mảng các đối tượng <code><strong>Post</strong></code>. Bạn cũng cần xác định <code><strong>PostType</strong></code>.</p>



<ul class="wp-block-list">
<li>Đừng quên là hãy chạy lệnh <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">rails generate model Post title:string content:text</mark> và <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">rails db:migrate</mark> để tạo ra bảng <strong>Post</strong> trước</li>
</ul>



<p>Tạo một tệp mới <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">app/graphql/types/post_type.rb</mark></code>:</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:#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">Ruby</span><span role="button" tabindex="0" data-code="# app/graphql/types/post_type.rb 

module Types 
  class PostType &lt; Types::BaseObject 
    field :id, ID, null: false 
    field :title, String, null: false 
    field :content, String, null: false 
  end 
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: #7B7F8B"># app/graphql/types/post_type.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">Types</span><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">PostType</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">&lt;</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">Types::BaseObject</span><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    field </span><span style="color: #BF9EEE">:id</span><span style="color: #F6F6F4">, </span><span style="color: #BF9EEE">ID</span><span style="color: #F6F6F4">, null</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">false</span><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    field </span><span style="color: #BF9EEE">:title</span><span style="color: #F6F6F4">, </span><span style="color: #BF9EEE">String</span><span style="color: #F6F6F4">, null</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">false</span><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    field </span><span style="color: #BF9EEE">:content</span><span style="color: #F6F6F4">, </span><span style="color: #BF9EEE">String</span><span style="color: #F6F6F4">, null</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">false</span><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #F286C4">end</span><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F286C4">end</span></span></code></pre></div>



<p>Tệp này xác định cấu trúc của một loại <code><strong>Post</strong></code> với các trường <code><strong>id</strong></code>, <code><strong>title</strong></code>, và <code><strong>content</strong></code>.</p>



<h2 id="kiem-thu-voi-graphiql" class="wp-block-heading">Kiểm Thử với GraphiQL</h2>



<p>GraphiQL là một công cụ đồ họa tương tác trực tuyến dành cho GraphQL giúp đơn giản hóa quá trình kiểm thử các truy vấn GraphQL của bạn. Để kích hoạt GraphiQL, mở tệp <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">config/routes.rb</mark></code> và thêm các dòng sau:</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:#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">Ruby</span><span role="button" tabindex="0" data-code="# config/routes.rb 

if Rails.env.development? 
  mount GraphiQL::Rails::Engine, at: &quot;/graphiql&quot;, graphql_path: &quot;/graphql&quot; end 
  
post &quot;/graphql&quot;, to: &quot;graphql#execute&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/routes.rb </span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">if</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">Rails</span><span style="color: #F6F6F4">.env.development? </span></span>
<span class="line"><span style="color: #F6F6F4">  mount </span><span style="color: #97E1F1; font-style: italic">GraphiQL</span><span style="color: #F286C4">::</span><span style="color: #97E1F1; font-style: italic">Rails</span><span style="color: #F286C4">::</span><span style="color: #BF9EEE">Engine</span><span style="color: #F6F6F4">, at</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">/graphiql</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">, graphql_path</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">/graphql</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">end</span><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">  </span></span>
<span class="line"><span style="color: #F6F6F4">post </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">/graphql</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">, to</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">graphql#execute</span><span style="color: #DEE492">&quot;</span></span></code></pre></div>



<p>Bây giờ, khi bạn chạy máy chủ Rails của mình (<code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">rails server</mark></code>), bạn có thể truy cập <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">http://localhost:3000/graphiql</mark></code> để tương tác với GraphQL API của bạn.</p>



<h2 id="thuc-hien-cac-truy-van" class="wp-block-heading">Thực Hiện Các Truy Vấn</h2>



<p>Bây giờ, bạn có thể kiểm thử các truy vấn GraphQL của mình trong GraphiQL. Ví dụ:</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:#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">GraphQL</span><span role="button" tabindex="0" data-code="query {
  posts {
    id
    title
    content
  }
}" 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: #F286C4">query</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #E7EE98">posts</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #E7EE98">id</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #E7EE98">title</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #E7EE98">content</span></span>
<span class="line"><span style="color: #F6F6F4">  }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p>Truy vấn này sẽ truy xuất tất cả các bài viết cùng với các trường <strong><code>id</code>, <code>title</code></strong>, và <code><strong>content</strong></code>.</p>



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



<p>Chúc mừng! Bạn đã xây dựng thành công một GraphQL API trong Ruby on Rails. <br>Happy coding!</p>
<p>The post <a href="https://blog.tomosia.com.vn/building-a-graphql-api-in-rails/">Building a GraphQL API 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/building-a-graphql-api-in-rails/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>Cách xử lý CSV hiệu quả trong Ruby</title>
		<link>https://blog.tomosia.com.vn/cach-xu-ly-csv-hieu-qua-trong-ruby/</link>
					<comments>https://blog.tomosia.com.vn/cach-xu-ly-csv-hieu-qua-trong-ruby/#comments</comments>
		
		<dc:creator><![CDATA[Thâm Davies]]></dc:creator>
		<pubDate>Tue, 28 Nov 2023 06:03:39 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=2064</guid>

					<description><![CDATA[<p>First things first Hey, bạn Thâm đây Như tiêu đề bài viết thì trong bài này mình sẽ&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/cach-xu-ly-csv-hieu-qua-trong-ruby/">Cách xử lý CSV hiệu quả trong Ruby</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h3 id="first-things-first" class="wp-block-heading">First things first</h3>



<p>Hey, bạn Thâm đây</p>



<p>Như tiêu đề bài viết thì trong bài này mình sẽ thử nghiệm các cách để đọc file CSV, rồi chọn ra cách tối ưu nhất ở phương diện tiêu thụ RAM, cũng như tốc độ xử lý. Let’s go</p>



<h3 id="chuan-bi-file-test" class="wp-block-heading">Chuẩn bị file test</h3>



<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="require 'csv'
require_relative './helpers'

headers   = ['id', 'name', 'email', 'city', 'street', 'country']

name      = &quot;Tham Davies&quot;
user_name = &quot;boygialaideptraikhongyeuai&quot;
email     = &quot;large-data@csv.com&quot;
city      = &quot;Pleiku&quot;
street    = &quot;Le Duan&quot;
country   = &quot;Viet Nam&quot;

print_memory_usage do
  print_time_spent do
    CSV.open('data.csv', 'w', write_headers: true, headers: headers) do |csv|
      1_000_000.times do |i|
        csv &lt;&lt; [i, name, user_name, email, city, street, country]
      end
    end
  end
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: #F286C4">require</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">csv</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F286C4">require_relative</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">./helpers</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">headers   </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> [</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">id</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">name</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">email</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">city</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">street</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">country</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">]</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">name      </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">Tham Davies</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">user_name </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">boygialaideptraikhongyeuai</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">email     </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">large-data@csv.com</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">city      </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">Pleiku</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">street    </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">Le Duan</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">country   </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">Viet Nam</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">print_memory_usage </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">  print_time_spent </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #97E1F1; font-style: italic">CSV</span><span style="color: #F6F6F4">.</span><span style="color: #97E1F1">open</span><span style="color: #F6F6F4">(</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">data.csv</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">w</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, write_headers</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">true</span><span style="color: #F6F6F4">, headers</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> headers) </span><span style="color: #F286C4">do</span><span style="color: #F6F6F4"> |csv|</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #BF9EEE">1_000_000</span><span style="color: #F6F6F4">.times </span><span style="color: #F286C4">do</span><span style="color: #F6F6F4"> |i|</span></span>
<span class="line"><span style="color: #F6F6F4">        csv </span><span style="color: #F286C4">&lt;&lt;</span><span style="color: #F6F6F4"> [i, name, user_name, email, city, street, country]</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F286C4">end</span></span></code></pre></div>



<h3 id="helpers" class="wp-block-heading">Helpers</h3>



<p>Tiếp theo, chúng ta sẽ sử dụng Benchmark để đo thời gian và đo lường việc sử dụng bộ nhớ.</p>



<ul class="wp-block-list">
<li><code>print_memory_usage</code> sẽ tính toán và in ra lượng bộ nhớ sử dụng trước và sau khi thực hiện các thao tác.</li>



<li><code>print_time_spent</code> sẽ tính toán và in ra thời gian thực hiện các thao tác.</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: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="require 'benchmark'

def print_memory_usage
  memory_before = `ps -o rss= -p #{Process.pid}`.to_i
  yield
  memory_after = `ps -o rss= -p #{Process.pid}`.to_i

  puts &quot;Memory: #{((memory_after - memory_before) / 1024.0).round(2)} MB&quot;
end

def print_time_spent
  time = Benchmark.realtime do
    yield
  end

  puts &quot;Time: #{time.round(2)} seconds&quot;
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: #F286C4">require</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">benchmark</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">def</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">print_memory_usage</span></span>
<span class="line"><span style="color: #F6F6F4">  memory_before </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">`</span><span style="color: #E7EE98">ps -o rss= -p </span><span style="color: #F286C4">#{</span><span style="color: #97E1F1; font-style: italic">Process</span><span style="color: #E7EE98">.pid</span><span style="color: #F286C4">}</span><span style="color: #DEE492">`</span><span style="color: #F6F6F4">.to_i</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #F286C4">yield</span></span>
<span class="line"><span style="color: #F6F6F4">  memory_after </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">`</span><span style="color: #E7EE98">ps -o rss= -p </span><span style="color: #F286C4">#{</span><span style="color: #97E1F1; font-style: italic">Process</span><span style="color: #E7EE98">.pid</span><span style="color: #F286C4">}</span><span style="color: #DEE492">`</span><span style="color: #F6F6F4">.to_i</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #97E1F1">puts</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">Memory: </span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">((memory_after </span><span style="color: #F286C4">-</span><span style="color: #E7EE98"> memory_before) </span><span style="color: #F286C4">/</span><span style="color: #E7EE98"> </span><span style="color: #BF9EEE">1024.0</span><span style="color: #E7EE98">).round(</span><span style="color: #BF9EEE">2</span><span style="color: #E7EE98">)</span><span style="color: #F286C4">}</span><span style="color: #E7EE98"> MB</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F286C4">end</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">def</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">print_time_spent</span></span>
<span class="line"><span style="color: #F6F6F4">  time </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">Benchmark</span><span style="color: #F6F6F4">.realtime </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">yield</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #F286C4">end</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #97E1F1">puts</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">Time: </span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">time.round(</span><span style="color: #BF9EEE">2</span><span style="color: #E7EE98">)</span><span style="color: #F286C4">}</span><span style="color: #E7EE98"> seconds</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F286C4">end</span></span></code></pre></div>



<p>Sau khi có 2 file trên thì các bạn chạy câu lệnh bên dưới để tiến hành tạo file test</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:#f6f6f4;--cbp-line-number-width:8.4375px;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">Bash</span><span role="button" tabindex="0" data-code="$ ruby generate_csv.rb
Time: 3.61
Memory: 1.67 MB

$ ls -lah data.csv
-rw-r--r--@ 1 tham  tham    85M Nov 22 10:45 data.csv" 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: #62E884">$</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">ruby</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">generate_csv.rb</span></span>
<span class="line"><span style="color: #62E884">Time:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">3.61</span></span>
<span class="line"><span style="color: #62E884">Memory:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">1.67</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">MB</span></span>
<span class="line"></span>
<span class="line"><span style="color: #62E884">$</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">ls</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">-lah</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">data.csv</span></span>
<span class="line"><span style="color: #62E884">-rw-r--r--@</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">1</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">tham</span><span style="color: #F6F6F4">  </span><span style="color: #E7EE98">tham</span><span style="color: #F6F6F4">    </span><span style="color: #BF9EEE">85</span><span style="color: #E7EE98">M</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">Nov</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">22</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">10</span><span style="color: #E7EE98">:45</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">data.csv</span></span></code></pre></div>



<p>Kết quả ở trên tuỳ thuộc vào máy, và điểm mấu chốt ở đây là Ruby sử dụng rất ít bộ nhớ (~1.7MB) để generate file CSV có kích thước là 85MB vì cơ chế dọn rác (GC) đã thu hồi lại bộ nhớ đã sử dụng.</p>



<h3 id="cac-cach-doc-file-csv" class="wp-block-heading">Các cách đọc file CSV</h3>



<p>1. <strong>CSV.read</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:#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="require_relative './helpers'
require 'csv'

print_memory_usage do
  print_time_spent do
    csv = CSV.read('data.csv', headers: true)
    sum = 0

    csv.each do |row|
      sum += row['id'].to_i
    end
    puts &quot;Sum: #{sum}&quot;
  end
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: #F286C4">require_relative</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">./helpers</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">csv</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">print_memory_usage </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">  print_time_spent </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">    csv </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">CSV</span><span style="color: #F6F6F4">.read(</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">data.csv</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, headers</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">true</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">    sum </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">0</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">    csv.each </span><span style="color: #F286C4">do</span><span style="color: #F6F6F4"> |row|</span></span>
<span class="line"><span style="color: #F6F6F4">      sum </span><span style="color: #F286C4">+=</span><span style="color: #F6F6F4"> row[</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">id</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">].to_i</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #97E1F1">puts</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">Sum: </span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">sum</span><span style="color: #F286C4">}</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F286C4">end</span></span>
<span class="line"></span></code></pre></div>



<p>Kết quả:</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:#f6f6f4;--cbp-line-number-width:8.4375px;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">Bash</span><span role="button" tabindex="0" data-code="$ ruby parse1.rb
Sum: 499999500000
Time: 20.12
Memory: 894.5 MB
" 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: #62E884">$</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">ruby</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">parse1.rb</span></span>
<span class="line"><span style="color: #62E884">Sum:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">499999500000</span></span>
<span class="line"><span style="color: #62E884">Time:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">20.12</span></span>
<span class="line"><span style="color: #62E884">Memory:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">894.5</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">MB</span></span>
<span class="line"></span></code></pre></div>



<p>Qoáo, cách này tiêu tốn 900MB RAM, mất 20S để đọc file, hãy thử tưởng tượng file của bạn tầm 10GB thì sẽ như thế nào 😄</p>



<p>Một số bạn sẽ thắc mắc tại sao file chỉ 85MB mà khi đọc file lại chiếm x10 bộ nhớ RAM?</p>



<p>Lý do là vì chúng ta đã đọc toàn bộ file và lưu đối tượng CSV trong bộ nhớ, khi làm như vậy thư viện CSV tạo ra rất nhiều đối tượng String, nên bộ nhớ sử dụng cao hơn nhiều so với kích thước thực tế của file CSV.</p>



<p>2. <strong>CSV.parse</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:#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="require_relative './helpers'
require 'csv'

print_memory_usage do
  print_time_spent do
    content = File.read('data.csv')
    csv = CSV.parse(content, headers: true)
    sum = 0

    csv.each do |row|
      sum += row['id'].to_i
    end

    puts &quot;Sum: #{sum}&quot;
  end
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: #F286C4">require_relative</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">./helpers</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">csv</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">print_memory_usage </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">  print_time_spent </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">    content </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">File</span><span style="color: #F6F6F4">.read(</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">data.csv</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">    csv </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">CSV</span><span style="color: #F6F6F4">.parse(content, headers</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">true</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">    sum </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">0</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">    csv.each </span><span style="color: #F286C4">do</span><span style="color: #F6F6F4"> |row|</span></span>
<span class="line"><span style="color: #F6F6F4">      sum </span><span style="color: #F286C4">+=</span><span style="color: #F6F6F4"> row[</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">id</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">].to_i</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">end</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #97E1F1">puts</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">Sum: </span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">sum</span><span style="color: #F286C4">}</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F286C4">end</span></span>
<span class="line"></span></code></pre></div>



<p>Kết quả:</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:#f6f6f4;--cbp-line-number-width:8.4375px;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">Bash</span><span role="button" tabindex="0" data-code="$ ruby parse2.rb
Sum: 499999500000
Time: 14.61
Memory: 1066.35 MB
" 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: #62E884">$</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">ruby</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">parse2.rb</span></span>
<span class="line"><span style="color: #62E884">Sum:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">499999500000</span></span>
<span class="line"><span style="color: #62E884">Time:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">14.61</span></span>
<span class="line"><span style="color: #62E884">Memory:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">1066.35</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">MB</span></span>
<span class="line"></span></code></pre></div>



<p>Cách này thậm chí còn tiêu tốn RAM hơn <strong>Cách 1</strong>, lý do là mình load toàn bộ dữ liệu từ file lưu vào biến (85MB), sau đó mới bắt đầu thực hiện các thao tác như <strong>Cách 1</strong>.</p>



<p>3. <strong>CSV.new</strong></p>



<p>Bây giờ chúng ta thử cách load toàn bộ file</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:#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="require_relative './helpers'
require 'csv'

print_memory_usage do
  print_time_spent do
    content = File.read('data.csv')
    csv = CSV.new(content, headers: true)
    sum = 0

    while row = csv.shift
      sum += row['id'].to_i
    end

    puts &quot;Sum: #{sum}&quot;
  end
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: #F286C4">require_relative</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">./helpers</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">csv</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">print_memory_usage </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">  print_time_spent </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">    content </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">File</span><span style="color: #F6F6F4">.read(</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">data.csv</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">    csv </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">CSV</span><span style="color: #F6F6F4">.</span><span style="color: #F286C4">new</span><span style="color: #F6F6F4">(content, headers</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">true</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">    sum </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">0</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">while</span><span style="color: #F6F6F4"> row </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> csv.shift</span></span>
<span class="line"><span style="color: #F6F6F4">      sum </span><span style="color: #F286C4">+=</span><span style="color: #F6F6F4"> row[</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">id</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">].to_i</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">end</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #97E1F1">puts</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">Sum: </span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">sum</span><span style="color: #F286C4">}</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F286C4">end</span></span>
<span class="line"></span></code></pre></div>



<p>Kết quả:</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:#f6f6f4;--cbp-line-number-width:8.4375px;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">Bash</span><span role="button" tabindex="0" data-code="$ ruby parse3.rb
Sum: 499999500000
Time: 6.7
Memory: 170.19 MB
" 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: #62E884">$</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">ruby</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">parse3.rb</span></span>
<span class="line"><span style="color: #62E884">Sum:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">499999500000</span></span>
<span class="line"><span style="color: #62E884">Time:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">6.7</span></span>
<span class="line"><span style="color: #62E884">Memory:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">170.19</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">MB</span></span>
<span class="line"></span></code></pre></div>



<p>Từ kết quả ta thấy lượng bộ nhớ sử dụng x2 kích thước của file (85 MB) vì nội dung file đã được nạp vào bộ nhớ. Thời gian xử lý nhanh hơn gấp đôi. </p>



<p>Phương pháp này hữu ích khi chúng ta đã có nội dung mà không cần đọc từ file, chỉ cần duyệt từng dòng. Việc lưu trực tiếp nội dung file vào bộ nhớ cho phép tăng tốc độ xử lý bằng cách loại bỏ quá trình đọc/ghi liên tục từ ổ đĩa.</p>



<p>Cách này được xem là cách tối ưu rồi, nhưng còn cách nào tốt hơn không? Cùng xem ví dụ ở dưới nhé.</p>



<p>4. <strong>IO read</strong></p>



<p>Ở đây chúng ta mở file, sau đó đọc từng dòng và parse sang CSV object</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:#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="require_relative './helpers'
require 'csv'

# cách 1: bằng cơm
print_memory_usage do
  print_time_spent do
    File.open('data.csv', 'r') do |file|
      csv = CSV.new(file, headers: true)
      sum = 0

      while row = csv.shift
        sum += row['id'].to_i
      end

      puts &quot;Sum: #{sum}&quot;
    end
  end
end

# cách 2: dùng built-in của Ruby
print_memory_usage do
  print_time_spent do
    sum = 0

    CSV.foreach('data.csv', headers: true) do |row|
      sum += row['id'].to_i
    end

    puts &quot;Sum: #{sum}&quot;
  end
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: #F286C4">require_relative</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">./helpers</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">csv</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #7B7F8B"># cách 1: bằng cơm</span></span>
<span class="line"><span style="color: #F6F6F4">print_memory_usage </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">  print_time_spent </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #97E1F1; font-style: italic">File</span><span style="color: #F6F6F4">.</span><span style="color: #97E1F1">open</span><span style="color: #F6F6F4">(</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">data.csv</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">r</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">) </span><span style="color: #F286C4">do</span><span style="color: #F6F6F4"> |file|</span></span>
<span class="line"><span style="color: #F6F6F4">      csv </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">CSV</span><span style="color: #F6F6F4">.</span><span style="color: #F286C4">new</span><span style="color: #F6F6F4">(file, headers</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">true</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">      sum </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">0</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">while</span><span style="color: #F6F6F4"> row </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> csv.shift</span></span>
<span class="line"><span style="color: #F6F6F4">        sum </span><span style="color: #F286C4">+=</span><span style="color: #F6F6F4"> row[</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">id</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">].to_i</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">end</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #97E1F1">puts</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">Sum: </span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">sum</span><span style="color: #F286C4">}</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F286C4">end</span></span>
<span class="line"></span>
<span class="line"><span style="color: #7B7F8B"># cách 2: dùng built-in của Ruby</span></span>
<span class="line"><span style="color: #F6F6F4">print_memory_usage </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">  print_time_spent </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">    sum </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">0</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #97E1F1; font-style: italic">CSV</span><span style="color: #F6F6F4">.foreach(</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">data.csv</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, headers</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">true</span><span style="color: #F6F6F4">) </span><span style="color: #F286C4">do</span><span style="color: #F6F6F4"> |row|</span></span>
<span class="line"><span style="color: #F6F6F4">      sum </span><span style="color: #F286C4">+=</span><span style="color: #F6F6F4"> row[</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">id</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">].to_i</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">end</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #97E1F1">puts</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">Sum: </span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">sum</span><span style="color: #F286C4">}</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F286C4">end</span></span>
<span class="line"></span></code></pre></div>



<p>Kết quả:</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:#f6f6f4;--cbp-line-number-width:8.4375px;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">Bash</span><span role="button" tabindex="0" data-code="$ ruby parse4.rb
Sum: 499999500000
Time: 9.57
Memory: 0.72 MB
" 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: #62E884">$</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">ruby</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">parse4.rb</span></span>
<span class="line"><span style="color: #62E884">Sum:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">499999500000</span></span>
<span class="line"><span style="color: #62E884">Time:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">9.57</span></span>
<span class="line"><span style="color: #62E884">Memory:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">0.72</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">MB</span></span>
<span class="line"></span></code></pre></div>



<p>Á chà chà, cách này tiêu tốn rất ít RAM, nhưng đổi lại là tốc độ xử lý chậm hơn một tẹo <strong>Cách 3</strong> vì nhiều thao tác IO hơn.</p>



<h3 id="loi-ket" class="wp-block-heading">Lời kết</h3>



<p>Trong bài viết này, chúng ta đã thử nghiệm các cách để đọc file CSV và tìm ra cách tối ưu nhất từ góc nhìn tiêu thụ RAM và tốc độ xử lý. Chúng ta đã thấy rằng cách sử dụng <code>CSV.foreach</code> là cách <strong>tiết kiệm RAM nhất</strong>, dù tốc độ xử lý có chậm hơn so với cách sử dụng <code>CSV.new</code>. Tuy nhiên, tùy thuộc vào yêu cầu và tình huống cụ thể, chúng ta có thể lựa chọn phương pháp phù hợp để đạt được hiệu suất tối ưu. </p>



<p>Nếu chúng ta xử lý file CSV dung lượng lớn thì rõ ràng cách tiêu thụ ít RAM nhất là cách hiệu quả nhất bởi nó sẽ không gây tràn RAM gây crash hệ thống.</p>



<p></p>
<p>The post <a href="https://blog.tomosia.com.vn/cach-xu-ly-csv-hieu-qua-trong-ruby/">Cách xử lý CSV hiệu quả trong Ruby</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/cach-xu-ly-csv-hieu-qua-trong-ruby/feed/</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
			</item>
		<item>
		<title>Debug trong Ruby mà không cần dùng thư viện</title>
		<link>https://blog.tomosia.com.vn/debug-trong-ruby-ma-khong-can-dung-thu-vien/</link>
					<comments>https://blog.tomosia.com.vn/debug-trong-ruby-ma-khong-can-dung-thu-vien/#comments</comments>
		
		<dc:creator><![CDATA[Minh Tang]]></dc:creator>
		<pubDate>Wed, 22 Nov 2023 01:44:30 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=1949</guid>

					<description><![CDATA[<p>Hướng dẫn debug không cần sử dụng thêm thư viện bên ngoài</p>
<p>The post <a href="https://blog.tomosia.com.vn/debug-trong-ruby-ma-khong-can-dung-thu-vien/">Debug trong Ruby mà không cần dùng thư viện</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Thông thường chúng ta muốn debug trong ruby thì hay sử dụng các gem pry, debugger, byebug. Nhược điểm là phải sử dụng thêm thư viện bên ngoài. Còn ở bài viết này mình sẽ chia sẻ thêm 1 cách mà không cần sử dụng thư viện bên ngoài mà vẫn có thể debug được.</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:#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="# door.rb
class Door
  def initialize
    @open = false
    binding.irb
    puts &quot;Is the door open: #{@open}&quot;
  end
end

Door.new" 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"># door.rb</span></span>
<span class="line"><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">Door</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #F286C4">def</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">initialize</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #BF9EEE; font-style: italic">@open</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">false</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #97E1F1">binding</span><span style="color: #F6F6F4">.irb</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #97E1F1">puts</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">Is the door open: </span><span style="color: #F286C4">#{</span><span style="color: #BF9EEE; font-style: italic">@open</span><span style="color: #F286C4">}</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #F286C4">end</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">Door</span><span style="color: #F6F6F4">.</span><span style="color: #F286C4">new</span></span></code></pre></div>



<p>Kết quả:</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:#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="Documentos/scripts/ruby via 💎 v3.2.2
❯ ruby door.rb

From: door.rb @ line 4 :

    1: class Door
    2:   def initialize
    3:     @open = false
 =&gt; 4:     binding.irb
    5:     puts &quot;Is the door open: #{@open}&quot;
    6:   end
    7: end
    8:
    9: Door.new

irb(#&lt;Door:0x00007fa9a0f367a8&gt;):001&gt; @open
=&gt; false
irb(#&lt;Door:0x00007fa9a0f367a8&gt;):002&gt; @open=true
=&gt; true
irb(#&lt;Door:0x00007fa9a0f367a8&gt;):003&gt; exit
Is the door open: true" 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: #BF9EEE">Documentos</span><span style="color: #F286C4">/</span><span style="color: #F6F6F4">scripts</span><span style="color: #F286C4">/</span><span style="color: #F6F6F4">ruby via 💎 v3.</span><span style="color: #BF9EEE">2.2</span></span>
<span class="line"><span style="color: #F6F6F4">❯ ruby door.rb</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">From</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> door.rb @ line </span><span style="color: #BF9EEE">4</span><span style="color: #F6F6F4"> :</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #BF9EEE">1</span><span style="color: #F6F6F4">: </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">Door</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #BF9EEE">2</span><span style="color: #F6F6F4">:   </span><span style="color: #F286C4">def</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">initialize</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #BF9EEE">3</span><span style="color: #F6F6F4">:     </span><span style="color: #BF9EEE; font-style: italic">@open</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">false</span></span>
<span class="line"><span style="color: #F6F6F4"> </span><span style="color: #F286C4">=&gt;</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">4</span><span style="color: #F6F6F4">:     </span><span style="color: #97E1F1">binding</span><span style="color: #F6F6F4">.irb</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #BF9EEE">5</span><span style="color: #F6F6F4">:     </span><span style="color: #97E1F1">puts</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">Is the door open: </span><span style="color: #F286C4">#{</span><span style="color: #BF9EEE; font-style: italic">@open</span><span style="color: #F286C4">}</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #BF9EEE">6</span><span style="color: #F6F6F4">:   </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #BF9EEE">7</span><span style="color: #F6F6F4">: </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #BF9EEE">8</span><span style="color: #F6F6F4">:</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #BF9EEE">9</span><span style="color: #F6F6F4">: </span><span style="color: #97E1F1; font-style: italic">Door</span><span style="color: #F6F6F4">.</span><span style="color: #F286C4">new</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">irb(</span><span style="color: #7B7F8B">#&lt;Door:0x00007fa9a0f367a8&gt;):001&gt; @open</span></span>
<span class="line"><span style="color: #F286C4">=&gt;</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">false</span></span>
<span class="line"><span style="color: #F6F6F4">irb(</span><span style="color: #7B7F8B">#&lt;Door:0x00007fa9a0f367a8&gt;):002&gt; @open=true</span></span>
<span class="line"><span style="color: #F286C4">=&gt;</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">true</span></span>
<span class="line"><span style="color: #F6F6F4">irb(</span><span style="color: #7B7F8B">#&lt;Door:0x00007fa9a0f367a8&gt;):003&gt; exit</span></span>
<span class="line"><span style="color: #BF9EEE">Is</span><span style="color: #F6F6F4"> the door open</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">true</span></span></code></pre></div>



<p>Happy coding! =]]z</p>
<p>The post <a href="https://blog.tomosia.com.vn/debug-trong-ruby-ma-khong-can-dung-thu-vien/">Debug trong Ruby mà không cần dùng thư viện</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/debug-trong-ruby-ma-khong-can-dung-thu-vien/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
		<item>
		<title>[ROR] Hướng dẫn setup CircleCI &#038; Code Quality</title>
		<link>https://blog.tomosia.com.vn/ror-huong-dan-setup-circleci-code-quality/</link>
					<comments>https://blog.tomosia.com.vn/ror-huong-dan-setup-circleci-code-quality/#comments</comments>
		
		<dc:creator><![CDATA[Thuan Nguyen Van]]></dc:creator>
		<pubDate>Wed, 22 Nov 2023 01:28:06 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[CI/CD]]></category>
		<category><![CDATA[Ruby On Rails]]></category>
		<category><![CDATA[Circle CI]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=1808</guid>

					<description><![CDATA[<p>Step 1: Access https://circleci.com/ and authorize a Github, Gitlab or Bitbucket account. I will use a Github account.&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/ror-huong-dan-setup-circleci-code-quality/">[ROR] Hướng dẫn setup CircleCI &#038; Code Quality</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p><strong>Step 1:</strong> Access <a href="https://circleci.com/">https://circleci.com/</a> and authorize a Github, Gitlab or Bitbucket account. I will use a Github account.</p>



<figure class="wp-block-image"><img decoding="async" src="https://lh7-us.googleusercontent.com/4-a7bO8VFdZjsOip_gK60WMFnOZJ0dD1PwI8ykJHCpPzJs-jjSvZekKGaQc7yth9dUIbdztuP4NDEC1F-xZMe7RDDys9RCbHf9EVDAIUCbvV2f9wvw-ZeUZH29uU_I72eS59O0zAyeOl88ueOYbhTw" alt=""/></figure>



<p><strong>Step 2</strong>: Click <strong>Go to Application </strong>in Home page -&gt; Projects</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="671" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.46.25-1024x671.png" alt="" class="wp-image-1828" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.46.25-1024x671.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.46.25-300x197.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.46.25-768x503.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.46.25-1536x1007.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.46.25-2048x1342.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.46.25-380x249.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.46.25-800x524.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.46.25-1160x760.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.46.25.png 2206w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p><strong>Step 3</strong>: Click to Setup Project button in the right Repo you want to setup</p>



<p><strong>Step 4</strong>: Select first Radio Button -&gt; Set Up Project</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="960" height="820" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.46.54.png" alt="" class="wp-image-1830" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.46.54.png 960w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.46.54-300x256.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.46.54-768x656.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.46.54-380x325.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.46.54-800x683.png 800w" sizes="auto, (max-width: 960px) 100vw, 960px" /></figure>



<p>After setup, click <strong>Dashboard </strong>and display as below</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="555" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.49.23-1024x555.png" alt="" class="wp-image-1831" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.49.23-1024x555.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.49.23-300x163.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.49.23-768x417.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.49.23-1536x833.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.49.23-2048x1111.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.49.23-380x206.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.49.23-800x434.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.49.23-1160x629.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-08.49.23.png 2360w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p><strong>Step 5</strong>: Click <strong>Project Setting -&gt; SSH Key </strong>and check if the ssh key has been linked or not.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="602" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-10.37.42-2-1024x602.png" alt="" class="wp-image-1926" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-10.37.42-2-1024x602.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-10.37.42-2-300x176.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-10.37.42-2-768x452.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-10.37.42-2-1536x903.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-10.37.42-2-380x223.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-10.37.42-2-800x471.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-10.37.42-2-1160x682.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-10.37.42-2.png 1600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Step 6: <strong>If you using Git Submodule,</strong> please create a Additional SSH Keys</p>



<ol class="wp-block-list">
<li>Open terminal and run <strong><code>ssh-keygen -t ed25519 -C "Circle CI".</code></strong></li>



<li>Click Add SSH Key and enter</li>
</ol>



<ul class="wp-block-list">
<li>Hostname: <strong>github.com</strong></li>



<li>Private Key: cat <strong>minh_id_ed25519</strong>, copy and paste</li>
</ul>



<ol class="wp-block-list" start="3">
<li>Back to Github, select Repository <strong>Shared submodule</strong> -&gt; <strong>Settings</strong> -&gt; <strong>Deploy Keys</strong> -&gt; <strong>Add deploy key</strong></li>



<li>Enter Title and Key -&gt; <strong>Add Key</strong></li>
</ol>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="524" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-10.38.40-3-1024x524.png" alt="" class="wp-image-1927" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-10.38.40-3-1024x524.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-10.38.40-3-300x154.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-10.38.40-3-768x393.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-10.38.40-3-1536x786.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-10.38.40-3-380x195.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-10.38.40-3-800x410.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-10.38.40-3-1160x594.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-10.38.40-3.png 1600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image"><img decoding="async" src="https://lh7-us.googleusercontent.com/DMqD1X_4hArkrqNjTitIIFNRe2HXnxxUpBu37aJgAH9XYYzgoDI2aE7GX8VLqt8cmKZiCl1EV0Nq_p7A7eOGg0ISwUcWUK-LdAqZdLg0heEL8GCH1qzpQI0lAHQxrtRcWJgnnSufCW9wVii8a7HUZQ" alt=""/></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="810" height="511" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-10.48.56.png" alt="" class="wp-image-1928" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-10.48.56.png 810w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-10.48.56-300x189.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-10.48.56-768x485.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-10.48.56-380x240.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-10.48.56-800x505.png 800w" sizes="auto, (max-width: 810px) 100vw, 810px" /></figure>



<p><strong>Step 7</strong>: Back to project setup config CircleCI and Danger</p>



<ol class="wp-block-list">
<li>Add to Gemfile</li>
</ol>



<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="gem 'brakeman', require: false
gem 'danger', '9.2.0'
# A Danger plugin to lint Ruby files through danger-brakeman_scanner.&lt;/em&gt;
gem 'danger-brakeman_scanner', '0.1.1'
# A Danger plugin to lint Ruby files through rails_best_practices.&lt;/em&gt;
gem 'danger-rails_best_practices', '0.1.3'
# A Danger plugin to lint Ruby files through Reek.&lt;/em&gt;
gem 'danger-reek', '0.3.0'
# A Danger plugin for running Ruby files through Rubocop.&lt;/em&gt;
gem 'danger-rubocop', '0.10.0'
# A Danger plugin to report code coverage generated by SimpleCov in JSON format.&lt;/em&gt;
gem 'danger-simplecov_json', '0.3.0'" 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">gem </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">brakeman</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, require</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">false</span></span>
<span class="line"><span style="color: #F6F6F4">gem </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">danger</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">9.2.0</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #7B7F8B"># A Danger plugin to lint Ruby files through danger-brakeman_scanner.&lt;/em&gt;</span></span>
<span class="line"><span style="color: #F6F6F4">gem </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">danger-brakeman_scanner</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">0.1.1</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #7B7F8B"># A Danger plugin to lint Ruby files through rails_best_practices.&lt;/em&gt;</span></span>
<span class="line"><span style="color: #F6F6F4">gem </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">danger-rails_best_practices</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">0.1.3</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #7B7F8B"># A Danger plugin to lint Ruby files through Reek.&lt;/em&gt;</span></span>
<span class="line"><span style="color: #F6F6F4">gem </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">danger-reek</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">0.3.0</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #7B7F8B"># A Danger plugin for running Ruby files through Rubocop.&lt;/em&gt;</span></span>
<span class="line"><span style="color: #F6F6F4">gem </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">danger-rubocop</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">0.10.0</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #7B7F8B"># A Danger plugin to report code coverage generated by SimpleCov in JSON format.&lt;/em&gt;</span></span>
<span class="line"><span style="color: #F6F6F4">gem </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">danger-simplecov_json</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">0.3.0</span><span style="color: #DEE492">&#39;</span></span></code></pre></div>



<ol class="wp-block-list" start="2">
<li>Create file in <strong>.circleci/config.yml</strong> and paste code</li>
</ol>



<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:25.296875px;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="# Best practises:
#   [https://www.netguru.com/blog/top-10-best-practises-to-benefit-more-form-circleci]
#   [https://circleci.com/blog/six-optimization-tips-for-your-config/]
references:
  working_directory: &amp;working_directory ~/quinblog
  images:
    base_image: &amp;base_image
      image: cimg/ruby:3.2.1
      environment:
        TZ: /usr/share/zoneinfo/Asia/Tokyo
        BUNDLE_JOBS: 4
        BUNDLE_RETRY: 3
        BUNDLE_PATH: vendor/bundle
        GEM_PATH: vendor/bundle
        RAILS_ENV: test
    db_image: &amp;db_image
      image: cimg/postgres:14.4
      environment:
        POSTGRES_USER: postgres
        POSTGRES_DB: quinblog_test
        POSTGRES_PASSWORD: postgres
    redis_image: &amp;redis_image
      image: cimg/redis:5.0
    mongodb_image: &amp;mongodb_image
      image: circleci/mongo:3.6
  commands:
    move_database_yml: &amp;move_database_yml
      name: Move database_yml
      command: mv config/database.ci.yml config/database.yml
    move_mongoid_yml: &amp;move_mongoid_yml
      name: Move mongoid_yml
      command: mv config/mongoid.ci.yml config/mongoid.yml
    sync_git_submodule: &amp;sync_git_submodule
      name: Sync git submodule
      command: |
        git submodule sync --recursive --quiet
        git submodule update --init --checkout --recursive --quiet

# Use the latest 2.1 version of CircleCI pipeline process engine.
# See: https://circleci.com/docs/2.0/configuration-reference
version: 2.1

# Orbs are reusable packages of CircleCI configuration that you may share across projects, enabling you to create encapsulated, parameterized commands, jobs, and executors that can be used across multiple projects.
# See: https://circleci.com/docs/2.0/orb-intro/
orbs:
  ruby: circleci/ruby@1.8.0

# Define a job to be invoked later in a workflow.
# See: https://circleci.com/docs/2.0/configuration-reference/#jobs
jobs:
  build:
    working_directory: *working_directory
    resource_class: small
    parallelism: 1
    docker:
      - *base_image
    steps:
      - add_ssh_keys:
          fingerprints:
            - '7c:72:77:4f:79:12:cb:af:c9:84:7b:d1:ab:24:69:41'
      - checkout

      - run: *move_database_yml
      - run: *move_mongoid_yml
      - run: *sync_git_submodule
      - run:
          name: Disabled auto completion
          command: echo 'IRB.conf[:USE_AUTOCOMPLETE] = false' &gt;&gt; ~/.irbrc

      # Restoring and saving cache
      - ruby/install-deps

      - persist_to_workspace:
          root: *working_directory
          paths:
            - ./*

  test:
    working_directory: *working_directory
    resource_class: small
    parallelism: 2
    docker:
      - *base_image
      - *db_image
      - *mongodb_image
      - *redis_image
    steps:
      - attach_workspace:
          at: *working_directory

      - run:
          name: Wait for Postgres DB
          command: dockerize -wait tcp://localhost:5432 -timeout 1m

      - run:
          name: Wait for Mongo DB
          command: dockerize -wait tcp://localhost:27017 -timeout 1m

      - run:
          name: Wait for Redis DB
          command: dockerize -wait tcp://localhost:6379 -timeout 1m

      - run:
          name: Migration DB
          command: |
            bundle exec rails db:schema:load:primary --trace
            bundle exec rails db:create:universal
            bundle exec rails db:schema:load:universal --trace

      - run:
          name: Run rspec
          command: |
            TESTFILES=$(circleci tests glob &quot;spec/**/*_spec.rb&quot; | circleci tests split --split-by=timings --timings-type=classname)
            echo ${TESTFILES}
            bundle exec rspec --profile 10 \
                              --format progress \
                              --format RspecJunitFormatter --out /tmp/test-results/rspec/rspec.xml \
                              ${TESTFILES}

      # Collect test data
      # See: https://circleci.com/docs/collect-test-data
      # See: https://circleci.com/blog/how-to-output-junit-tests-through-circleci-2-0-for-expanded-insights/
      - store_test_results:
          path: /tmp/test-results/rspec/

      - run:
          name: Run danger
          command: bundle exec danger --danger_id=test

  lint:
    working_directory: *working_directory
    resource_class: small
    parallelism: 1
    docker:
      - *base_image
    steps:
      - attach_workspace:
          at: *working_directory

      - run:
          name: Run danger
          command: bundle exec danger --danger_id=lint

# Invoke jobs via workflows
# See: https://circleci.com/docs/2.0/configuration-reference/#workflows
workflows:
  build_and_test:
    jobs:
      - build
      - test:
          context:
            - ctx_renew_api_company
          requires:
            - build
      - lint:
          context:
            - ctx_renew_api_company
          requires:
            - build
" 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"># Best practises:</span></span>
<span class="line"><span style="color: #7B7F8B">#   [https://www.netguru.com/blog/top-10-best-practises-to-benefit-more-form-circleci]</span></span>
<span class="line"><span style="color: #7B7F8B">#   [https://circleci.com/blog/six-optimization-tips-for-your-config/]</span></span>
<span class="line"><span style="color: #F6F6F4">references</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">  working_directory</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">&amp;</span><span style="color: #F6F6F4">working_directory </span><span style="color: #F286C4">~</span><span style="color: #E7EE98">/quinblog</span></span>
<span class="line"><span style="color: #E7EE98">  images:</span></span>
<span class="line"><span style="color: #E7EE98">    base_image: &amp;base_image</span></span>
<span class="line"><span style="color: #E7EE98">      image: cimg/</span><span style="color: #F6F6F4">ruby</span><span style="color: #F286C4">:</span><span style="color: #BF9EEE">3.2</span><span style="color: #F6F6F4">.</span><span style="color: #BF9EEE">1</span></span>
<span class="line"><span style="color: #F6F6F4">      environment</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">        TZ</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">/usr/s</span><span style="color: #F6F6F4">hare</span><span style="color: #F286C4">/</span><span style="color: #F6F6F4">zoneinfo</span><span style="color: #F286C4">/</span><span style="color: #BF9EEE">Asia</span><span style="color: #F286C4">/</span><span style="color: #BF9EEE">Tokyo</span></span>
<span class="line"><span style="color: #F6F6F4">        BUNDLE_JOBS</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">4</span></span>
<span class="line"><span style="color: #F6F6F4">        BUNDLE_RETRY</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">3</span></span>
<span class="line"><span style="color: #F6F6F4">        BUNDLE_PATH</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> vendor</span><span style="color: #F286C4">/</span><span style="color: #F6F6F4">bundle</span></span>
<span class="line"><span style="color: #F6F6F4">        GEM_PATH</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> vendor</span><span style="color: #F286C4">/</span><span style="color: #F6F6F4">bundle</span></span>
<span class="line"><span style="color: #F6F6F4">        RAILS_ENV</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">test</span></span>
<span class="line"><span style="color: #F6F6F4">    db_image</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">&amp;</span><span style="color: #F6F6F4">db_image</span></span>
<span class="line"><span style="color: #F6F6F4">      image</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> cimg</span><span style="color: #F286C4">/</span><span style="color: #F6F6F4">postgres</span><span style="color: #F286C4">:</span><span style="color: #BF9EEE">14.4</span></span>
<span class="line"><span style="color: #F6F6F4">      environment</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">        POSTGRES_USER</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> postgres</span></span>
<span class="line"><span style="color: #F6F6F4">        POSTGRES_DB</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> quinblog_test</span></span>
<span class="line"><span style="color: #F6F6F4">        POSTGRES_PASSWORD</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> postgres</span></span>
<span class="line"><span style="color: #F6F6F4">    redis_image</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">&amp;</span><span style="color: #F6F6F4">redis_image</span></span>
<span class="line"><span style="color: #F6F6F4">      image</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> cimg</span><span style="color: #F286C4">/</span><span style="color: #F6F6F4">redis</span><span style="color: #F286C4">:</span><span style="color: #BF9EEE">5.0</span></span>
<span class="line"><span style="color: #F6F6F4">    mongodb_image</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">&amp;</span><span style="color: #F6F6F4">mongodb_image</span></span>
<span class="line"><span style="color: #F6F6F4">      image</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> circleci</span><span style="color: #F286C4">/</span><span style="color: #F6F6F4">mongo</span><span style="color: #F286C4">:</span><span style="color: #BF9EEE">3.6</span></span>
<span class="line"><span style="color: #F6F6F4">  commands</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">    move_database_yml</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">&amp;</span><span style="color: #F6F6F4">move_database_yml</span></span>
<span class="line"><span style="color: #F6F6F4">      name</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">Move</span><span style="color: #F6F6F4"> database_yml</span></span>
<span class="line"><span style="color: #F6F6F4">      command</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> mv config</span><span style="color: #F286C4">/</span><span style="color: #F6F6F4">database.ci.yml config</span><span style="color: #F286C4">/</span><span style="color: #F6F6F4">database.yml</span></span>
<span class="line"><span style="color: #F6F6F4">    move_mongoid_yml</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">&amp;</span><span style="color: #F6F6F4">move_mongoid_yml</span></span>
<span class="line"><span style="color: #F6F6F4">      name</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">Move</span><span style="color: #F6F6F4"> mongoid_yml</span></span>
<span class="line"><span style="color: #F6F6F4">      command</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> mv config</span><span style="color: #F286C4">/</span><span style="color: #F6F6F4">mongoid.ci.yml config</span><span style="color: #F286C4">/</span><span style="color: #F6F6F4">mongoid.yml</span></span>
<span class="line"><span style="color: #F6F6F4">    sync_git_submodule</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">&amp;</span><span style="color: #F6F6F4">sync_git_submodule</span></span>
<span class="line"><span style="color: #F6F6F4">      name</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">Sync</span><span style="color: #F6F6F4"> git submodule</span></span>
<span class="line"><span style="color: #F6F6F4">      command</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">|</span></span>
<span class="line"><span style="color: #F6F6F4">        git submodule sync </span><span style="color: #F286C4">--</span><span style="color: #F6F6F4">recursive </span><span style="color: #F286C4">--</span><span style="color: #F6F6F4">quiet</span></span>
<span class="line"><span style="color: #F6F6F4">        git submodule update </span><span style="color: #F286C4">--</span><span style="color: #F6F6F4">init </span><span style="color: #F286C4">--</span><span style="color: #F6F6F4">checkout </span><span style="color: #F286C4">--</span><span style="color: #F6F6F4">recursive </span><span style="color: #F286C4">--</span><span style="color: #F6F6F4">quiet</span></span>
<span class="line"></span>
<span class="line"><span style="color: #7B7F8B"># Use the latest 2.1 version of CircleCI pipeline process engine.</span></span>
<span class="line"><span style="color: #7B7F8B"># See: https://circleci.com/docs/2.0/configuration-reference</span></span>
<span class="line"><span style="color: #F6F6F4">version</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">2.1</span></span>
<span class="line"></span>
<span class="line"><span style="color: #7B7F8B"># Orbs are reusable packages of CircleCI configuration that you may share across projects, enabling you to create encapsulated, parameterized commands, jobs, and executors that can be used across multiple projects.</span></span>
<span class="line"><span style="color: #7B7F8B"># See: https://circleci.com/docs/2.0/orb-intro/</span></span>
<span class="line"><span style="color: #F6F6F4">orbs</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">  ruby</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> circleci</span><span style="color: #F286C4">/</span><span style="color: #F6F6F4">ruby@</span><span style="color: #BF9EEE">1.8</span><span style="color: #F6F6F4">.</span><span style="color: #BF9EEE">0</span></span>
<span class="line"></span>
<span class="line"><span style="color: #7B7F8B"># Define a job to be invoked later in a workflow.</span></span>
<span class="line"><span style="color: #7B7F8B"># See: https://circleci.com/docs/2.0/configuration-reference/#jobs</span></span>
<span class="line"><span style="color: #F6F6F4">jobs</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">  build</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">    working_directory</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">*</span><span style="color: #F6F6F4">working_directory</span></span>
<span class="line"><span style="color: #F6F6F4">    resource_class</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> small</span></span>
<span class="line"><span style="color: #F6F6F4">    parallelism</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">1</span></span>
<span class="line"><span style="color: #F6F6F4">    docker</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">*</span><span style="color: #F6F6F4">base_image</span></span>
<span class="line"><span style="color: #F6F6F4">    steps</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> add_ssh_keys</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">          fingerprints</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">            </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">7c:72:77:4f:79:12:cb:af:c9:84:7b:d1:ab:24:69:41</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> checkout</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> run</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">*</span><span style="color: #F6F6F4">move_database_yml</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> run</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">*</span><span style="color: #F6F6F4">move_mongoid_yml</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> run</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">*</span><span style="color: #F6F6F4">sync_git_submodule</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> run</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">          name</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">Disabled</span><span style="color: #F6F6F4"> auto completion</span></span>
<span class="line"><span style="color: #F6F6F4">          command</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> echo </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">IRB.conf[:USE_AUTOCOMPLETE] = false</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">&gt;&gt;</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">~</span><span style="color: #E7EE98">/.irbrc</span></span>
<span class="line"></span>
<span class="line"><span style="color: #E7EE98">      </span><span style="color: #7B7F8B"># Restoring and saving cache</span></span>
<span class="line"><span style="color: #E7EE98">      - ruby/ins</span><span style="color: #F6F6F4">tall</span><span style="color: #F286C4">-</span><span style="color: #F6F6F4">deps</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> persist_to_workspace</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">          root</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">*</span><span style="color: #F6F6F4">working_directory</span></span>
<span class="line"><span style="color: #F6F6F4">          paths</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">            </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> .</span><span style="color: #F286C4">/*</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  test</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">    working_directory</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">*</span><span style="color: #F6F6F4">working_directory</span></span>
<span class="line"><span style="color: #F6F6F4">    resource_class</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> small</span></span>
<span class="line"><span style="color: #F6F6F4">    parallelism</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">2</span></span>
<span class="line"><span style="color: #F6F6F4">    docker</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">*</span><span style="color: #F6F6F4">base_image</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">*</span><span style="color: #F6F6F4">db_image</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">*</span><span style="color: #F6F6F4">mongodb_image</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">*</span><span style="color: #F6F6F4">redis_image</span></span>
<span class="line"><span style="color: #F6F6F4">    steps</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> attach_workspace</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">          at</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">*</span><span style="color: #F6F6F4">working_directory</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> run</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">          name</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">Wait</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">for</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">Postgres</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">DB</span></span>
<span class="line"><span style="color: #F6F6F4">          command</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> dockerize </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4">wait tcp</span><span style="color: #F286C4">:</span><span style="color: #E7EE98">//</span><span style="color: #F6F6F4">localhost</span><span style="color: #F286C4">:</span><span style="color: #BF9EEE">5432</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4">timeout 1m</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> run</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">          name</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">Wait</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">for</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">Mongo</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">DB</span></span>
<span class="line"><span style="color: #F6F6F4">          command</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> dockerize </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4">wait tcp</span><span style="color: #F286C4">:</span><span style="color: #E7EE98">//</span><span style="color: #F6F6F4">localhost</span><span style="color: #F286C4">:</span><span style="color: #BF9EEE">27017</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4">timeout 1m</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> run</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">          name</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">Wait</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">for</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">Redis</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">DB</span></span>
<span class="line"><span style="color: #F6F6F4">          command</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> dockerize </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4">wait tcp</span><span style="color: #F286C4">:</span><span style="color: #E7EE98">//</span><span style="color: #F6F6F4">localhost</span><span style="color: #F286C4">:</span><span style="color: #BF9EEE">6379</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4">timeout 1m</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> run</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">          name</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">Migration</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">DB</span></span>
<span class="line"><span style="color: #F6F6F4">          command</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">|</span></span>
<span class="line"><span style="color: #F6F6F4">            bundle </span><span style="color: #97E1F1">exec</span><span style="color: #F6F6F4"> rails db</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4">schema</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4">load</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4">primary </span><span style="color: #F286C4">--</span><span style="color: #F6F6F4">trace</span></span>
<span class="line"><span style="color: #F6F6F4">            bundle </span><span style="color: #97E1F1">exec</span><span style="color: #F6F6F4"> rails db</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4">create</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4">universal</span></span>
<span class="line"><span style="color: #F6F6F4">            bundle </span><span style="color: #97E1F1">exec</span><span style="color: #F6F6F4"> rails db</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4">schema</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4">load</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4">universal </span><span style="color: #F286C4">--</span><span style="color: #F6F6F4">trace</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> run</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">          name</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">Run</span><span style="color: #F6F6F4"> rspec</span></span>
<span class="line"><span style="color: #F6F6F4">          command</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">|</span></span>
<span class="line"><span style="color: #F6F6F4">            </span><span style="color: #BF9EEE">TESTFILES</span><span style="color: #F286C4">=</span><span style="color: #F6F6F4">$(circleci tests glob </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">spec/**/*_spec.rb</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">|</span><span style="color: #F6F6F4"> circleci tests split </span><span style="color: #F286C4">--</span><span style="color: #F6F6F4">split</span><span style="color: #F286C4">-</span><span style="color: #F6F6F4">by</span><span style="color: #F286C4">=</span><span style="color: #F6F6F4">timings </span><span style="color: #F286C4">--</span><span style="color: #F6F6F4">timings</span><span style="color: #F286C4">-</span><span style="color: #F6F6F4">type</span><span style="color: #F286C4">=</span><span style="color: #F6F6F4">classname)</span></span>
<span class="line"><span style="color: #F6F6F4">            echo ${</span><span style="color: #BF9EEE">TESTFILES</span><span style="color: #F6F6F4">}</span></span>
<span class="line"><span style="color: #F6F6F4">            bundle </span><span style="color: #97E1F1">exec</span><span style="color: #F6F6F4"> rspec </span><span style="color: #F286C4">--</span><span style="color: #F6F6F4">profile </span><span style="color: #BF9EEE">10</span><span style="color: #F6F6F4"> \</span></span>
<span class="line"><span style="color: #F6F6F4">                              </span><span style="color: #F286C4">--</span><span style="color: #97E1F1">format</span><span style="color: #F6F6F4"> progress \</span></span>
<span class="line"><span style="color: #F6F6F4">                              </span><span style="color: #F286C4">--</span><span style="color: #97E1F1">format</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">RspecJunitFormatter</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">--</span><span style="color: #F6F6F4">out </span><span style="color: #F286C4">/</span><span style="color: #F6F6F4">tmp</span><span style="color: #F286C4">/</span><span style="color: #97E1F1">test</span><span style="color: #F286C4">-</span><span style="color: #F6F6F4">results</span><span style="color: #F286C4">/</span><span style="color: #F6F6F4">rspec</span><span style="color: #F286C4">/</span><span style="color: #F6F6F4">rspec.xml \</span></span>
<span class="line"><span style="color: #F6F6F4">                              ${</span><span style="color: #BF9EEE">TESTFILES</span><span style="color: #F6F6F4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #7B7F8B"># Collect test data</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #7B7F8B"># See: https://circleci.com/docs/collect-test-data</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #7B7F8B"># See: https://circleci.com/blog/how-to-output-junit-tests-through-circleci-2-0-for-expanded-insights/</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> store_test_results</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">          path</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">/tmp/</span><span style="color: #97E1F1">test</span><span style="color: #F286C4">-</span><span style="color: #F6F6F4">results</span><span style="color: #F286C4">/</span><span style="color: #F6F6F4">rspec</span><span style="color: #F286C4">/</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> run</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">          name</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">Run</span><span style="color: #F6F6F4"> danger</span></span>
<span class="line"><span style="color: #F6F6F4">          command</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> bundle </span><span style="color: #97E1F1">exec</span><span style="color: #F6F6F4"> danger </span><span style="color: #F286C4">--</span><span style="color: #F6F6F4">danger_id</span><span style="color: #F286C4">=</span><span style="color: #97E1F1">test</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  lint</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">    working_directory</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">*</span><span style="color: #F6F6F4">working_directory</span></span>
<span class="line"><span style="color: #F6F6F4">    resource_class</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> small</span></span>
<span class="line"><span style="color: #F6F6F4">    parallelism</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">1</span></span>
<span class="line"><span style="color: #F6F6F4">    docker</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">*</span><span style="color: #F6F6F4">base_image</span></span>
<span class="line"><span style="color: #F6F6F4">    steps</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> attach_workspace</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">          at</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">*</span><span style="color: #F6F6F4">working_directory</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> run</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">          name</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">Run</span><span style="color: #F6F6F4"> danger</span></span>
<span class="line"><span style="color: #F6F6F4">          command</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> bundle </span><span style="color: #97E1F1">exec</span><span style="color: #F6F6F4"> danger </span><span style="color: #F286C4">--</span><span style="color: #F6F6F4">danger_id</span><span style="color: #F286C4">=</span><span style="color: #F6F6F4">lint</span></span>
<span class="line"></span>
<span class="line"><span style="color: #7B7F8B"># Invoke jobs via workflows</span></span>
<span class="line"><span style="color: #7B7F8B"># See: https://circleci.com/docs/2.0/configuration-reference/#workflows</span></span>
<span class="line"><span style="color: #F6F6F4">workflows</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">  build_and_test</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">    jobs</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> build</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> test</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">          context</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">            </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> ctx_renew_api_company</span></span>
<span class="line"><span style="color: #F6F6F4">          requires</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">            </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> build</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> lint</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">          context</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">            </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> ctx_renew_api_company</span></span>
<span class="line"><span style="color: #F6F6F4">          requires</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">            </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> build</span></span>
<span class="line"></span></code></pre></div>



<p><strong>Step 8</strong>: Config Danger. Create <strong>Dangerfile</strong> and paste code below:</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:#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="# frozen_string_literal: true

case ENV.fetch('CIRCLE_JOB', nil)

when 'lint'

  ### for Rubocop ###

  rubocop.lint(force_exclusion: true, inline_comment: true)

  ### for rails_best_practices ###

  # rails_best_practices.lint

  ### for Reek ###

  # reek.lint

  ### for brakeman ###

  brakeman.run('.')

  # Ensure there is a summary for a pr

  failure('Please provide a summary in the Pull Request description') if     github.pr_body.include?('___WRITE_HERE___')

  # Ensure that all prs have an assignee

  failure('This PR does not have any assignees yet.') unless github.pr_json['assignee']

  # Warn really big diffs

  warn('We cannot handle the scale of this PR') if git.lines_of_code &gt; 300

  # Note when a pr cannot be manually merged, which goes away when you can

  warn('This PR cannot be merged yet.', sticky: false) unless github.pr_json['mergeable']

 when 'test'

  ### for SimpleCov ###

  coverage_file = 'coverage/coverage.json'

  simplecov.report(coverage_file, sticky: false)

  simplecov.individual_report(coverage_file, Dir.pwd)

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: #7B7F8B"># frozen_string_literal: true</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">case</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">ENV</span><span style="color: #F6F6F4">.fetch(</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">CIRCLE_JOB</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #BF9EEE">nil</span><span style="color: #F6F6F4">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">when</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">lint</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #7B7F8B">### for Rubocop ###</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  rubocop.lint(force_exclusion</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">true</span><span style="color: #F6F6F4">, inline_comment</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">true</span><span style="color: #F6F6F4">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #7B7F8B">### for rails_best_practices ###</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #7B7F8B"># rails_best_practices.lint</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #7B7F8B">### for Reek ###</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #7B7F8B"># reek.lint</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #7B7F8B">### for brakeman ###</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  brakeman.run(</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">.</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #7B7F8B"># Ensure there is a summary for a pr</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  failure(</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">Please provide a summary in the Pull Request description</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">) </span><span style="color: #F286C4">if</span><span style="color: #F6F6F4">     github.pr_body.include?(</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">___WRITE_HERE___</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #7B7F8B"># Ensure that all prs have an assignee</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  failure(</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">This PR does not have any assignees yet.</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">) </span><span style="color: #F286C4">unless</span><span style="color: #F6F6F4"> github.pr_json[</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">assignee</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">]</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #7B7F8B"># Warn really big diffs</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #97E1F1">warn</span><span style="color: #F6F6F4">(</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">We cannot handle the scale of this PR</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">) </span><span style="color: #F286C4">if</span><span style="color: #F6F6F4"> git.lines_of_code </span><span style="color: #F286C4">&gt;</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">300</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #7B7F8B"># Note when a pr cannot be manually merged, which goes away when you can</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #97E1F1">warn</span><span style="color: #F6F6F4">(</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">This PR cannot be merged yet.</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, sticky</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">false</span><span style="color: #F6F6F4">) </span><span style="color: #F286C4">unless</span><span style="color: #F6F6F4"> github.pr_json[</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">mergeable</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">]</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4"> </span><span style="color: #F286C4">when</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">test</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #7B7F8B">### for SimpleCov ###</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  coverage_file </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">coverage/coverage.json</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  simplecov.report(coverage_file, sticky</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">false</span><span style="color: #F6F6F4">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  simplecov.individual_report(coverage_file, </span><span style="color: #97E1F1; font-style: italic">Dir</span><span style="color: #F6F6F4">.pwd)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">end</span></span></code></pre></div>



<p><strong>Step 9</strong>: Back to CircleCI -&gt; Click <a href="https://app.circleci.com/settings/organization/github/hinodelabo/overview?return-to=https%3A%2F%2Fapp.circleci.com%2Fpipelines%2Fgithub%2Fhinodelabo%2Fqlear-v2-bot"><strong>Organization Settings -&gt; Contexts -&gt; Create Context</strong></a></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="541" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-13.15.01-2-1024x541.png" alt="" class="wp-image-1929" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-13.15.01-2-1024x541.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-13.15.01-2-300x158.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-13.15.01-2-768x406.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-13.15.01-2-1536x811.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-13.15.01-2-380x201.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-13.15.01-2-800x423.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-13.15.01-2-1160x613.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-13.15.01-2.png 1600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p><strong>Step 10</strong>: Enter name <strong>Context</strong> and click <strong>Create Context</strong></p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="480" height="337" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-13.21.17-1.png" alt="" class="wp-image-1930" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-13.21.17-1.png 480w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-13.21.17-1-300x211.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-13.21.17-1-200x140.png 200w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-13.21.17-1-380x267.png 380w" sizes="auto, (max-width: 480px) 100vw, 480px" /></figure>



<p><strong>Step 11</strong>: Click Context Name created and add environment for project such as <strong>RAILS_MASTER_KEY</strong>, <strong>RAILS_ENV</strong>, <strong>RACK_ENV</strong>, <strong>DANGER_GITHUB_API_TOKEN</strong></p>



<p><img loading="lazy" decoding="async" width="602" height="369" src="https://lh7-us.googleusercontent.com/17QyXLD3bPoW37cSOYqHPLsPm0uKHPu6OeuHKJdiNjW0BYHRYPnPjpcAqA5T76mSrD8TWG-LWkKGXCnG3C4I38vCi4Cd7omWGvVoAaEupr0jK01mlqi-yk3ejp44tmiIINx_DKnS1ZlCYgSS2hvmkA"></p>



<p>Click Add Environment and enter value as below:</p>



<figure class="wp-block-image"><img decoding="async" src="https://lh7-us.googleusercontent.com/VawQSbkEyRNPF0gTcuZpOMupCXkMWjkHYUkubeARhEFwjAtprXU7dO_uB1kJj_arFhyvmuBcOROKFznmQ20Z17xrc4TPQYJAtPGN9vP8u6IuuAJtv8jbnzBHktucj95hNV1ngdzhq6uqiyO7CVnMpA" alt=""/></figure>



<p><strong>Note:</strong></p>



<ul class="wp-block-list">
<li>RAILS_MASTER_KEY: Open file config/crendentials/test.key on project and copy it.</li>



<li>RAILS_ENV: test</li>



<li>RACK_ENV: test</li>
</ul>



<p>After add 3 environments, it will displayed as below:</p>



<figure class="wp-block-image"><img decoding="async" src="https://lh7-us.googleusercontent.com/WiT33geUhW0yOKFsk__sCQAGncXWsmc2gYABWVxVpEFs1loyoiC2nswh9C3YwTovzG9umpGJqqHC_uIf455XlXv5T8LRER2VQKr6JSDhRT4TeAmHii1cJrkZ2MrPnwm6FjBB_DzUdZC3i3QzuqpMsw" alt=""/></figure>



<p><strong>Step 12</strong>: Create <strong>DANGER_GITHUB_API_TOKEN</strong></p>



<ol class="wp-block-list">
<li>Access <a href="https://github.com/settings/tokens">https://github.com/settings/tokens</a> and click <strong>Generate new token</strong></li>
</ol>



<figure class="wp-block-image"><img decoding="async" src="https://lh7-us.googleusercontent.com/G8nn12MjFXdAlmZPbLyXC9j_FDpA4Mg1ES-R79AqjJo6rwp-QqaIWbWbwgWo678Jx2qUMSY8DqvkQehGEYDwLeR5eLddtBcirZmUMXvGYOSuMHqEi35NP7Da1p0TYW-dn0UBHUmod9FEVhM8qlCoAw" alt=""/></figure>



<ol class="wp-block-list" start="2">
<li>Write Note and Select Expiration, Scope. I choose Expiration 90 days and click repo</li>
</ol>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="776" height="388" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-13.43.20-1.png" alt="" class="wp-image-1934" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-13.43.20-1.png 776w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-13.43.20-1-300x150.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-13.43.20-1-768x384.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-13.43.20-1-380x190.png 380w" sizes="auto, (max-width: 776px) 100vw, 776px" /></figure>



<ol class="wp-block-list" start="3">
<li>Click Generate Token and Copy this.</li>
</ol>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="800" height="379" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-13.44.39-1.png" alt="" class="wp-image-1931" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-13.44.39-1.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-13.44.39-1-300x142.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-13.44.39-1-768x364.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-13.44.39-1-380x180.png 380w" sizes="auto, (max-width: 800px) 100vw, 800px" /></figure>



<ol class="wp-block-list" start="4">
<li>Back to <strong>Context</strong> and Add <strong>DANGER_GITHUB_API_TOKEN</strong></li>
</ol>



<p><strong>Step 12</strong>: Push code and runnnnn</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="287" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-14.23.09-1-1024x287.png" alt="" class="wp-image-1933" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-14.23.09-1-1024x287.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-14.23.09-1-300x84.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-14.23.09-1-768x216.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-14.23.09-1-1536x431.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-14.23.09-1-380x107.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-14.23.09-1-800x225.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-14.23.09-1-1160x326.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-14.23.09-1.png 1600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="931" height="497" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-14.23.43.png" alt="" class="wp-image-1936" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-14.23.43.png 931w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-14.23.43-300x160.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-14.23.43-768x410.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-14.23.43-380x203.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-07-18-at-14.23.43-800x427.png 800w" sizes="auto, (max-width: 931px) 100vw, 931px" /></figure>
<p>The post <a href="https://blog.tomosia.com.vn/ror-huong-dan-setup-circleci-code-quality/">[ROR] Hướng dẫn setup CircleCI &#038; Code Quality</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/ror-huong-dan-setup-circleci-code-quality/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>Proc và Lambda trong Ruby: Sự Khác Biệt và Cách Sử Dụng</title>
		<link>https://blog.tomosia.com.vn/proc-va-lambda-trong-ruby-su-khac-biet-va-cach-su-dung/</link>
					<comments>https://blog.tomosia.com.vn/proc-va-lambda-trong-ruby-su-khac-biet-va-cach-su-dung/#comments</comments>
		
		<dc:creator><![CDATA[Thuc Phan]]></dc:creator>
		<pubDate>Wed, 15 Nov 2023 09:40:16 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=1826</guid>

					<description><![CDATA[<p>Trong ngôn ngữ lập trình Ruby, Proc và Lambda đóng vai trò quan trọng, mang lại sự linh&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/proc-va-lambda-trong-ruby-su-khac-biet-va-cach-su-dung/">Proc và Lambda trong Ruby: Sự Khác Biệt và Cách Sử Dụng</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Trong ngôn ngữ lập trình Ruby, Proc và Lambda đóng vai trò quan trọng, mang lại sự linh hoạt cho việc xử lý hàm và thực hiện các tác vụ khác nhau. Trong bài viết này, chúng ta sẽ khám phá sự khác biệt giữa Proc và Lambda, cách chúng được tích hợp có thể làm cho mã nguồn của bạn trở nên mạnh mẽ, linh hoạt, và dễ đọc hơn. Cùng đi sâu vào thế giới của Proc và Lambda để hiểu rõ hơn và nâng cao kĩ năng lập trình của bạn!</p>



<h2 id="1-proc" class="wp-block-heading">1. Proc</h2>



<p><strong>1.1 Khái niệm</strong></p>



<ul class="wp-block-list">
<li>Proc là một class trong Ruby</li>
</ul>



<ul class="wp-block-list">
<li>Đối tượng Proc là sự đóng gói của một khối mã, có thể được lưu trữ trong một biến, được truyền vào một method hoặc Proc khác và được gọi khi cần dùng</li>
</ul>



<p><strong>1.2 Khai báo và sử dụng Proc</strong></p>



<ul class="wp-block-list">
<li>Proc có 2 cách khai báo và nhiều cách gọi</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: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="# Lambda-like syntax
sample_proc = Proc.new {|x| puts x}
# Or short syntax
sample_proc = proc {|x| puts x}

# Call proc (Output: 10)
sample_proc.call(10) 
# Or
sample_proc[10]
# Or
sample_proc.10
# Or
sample_proc.yield(10)" 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"># Lambda-like syntax</span></span>
<span class="line"><span style="color: #F6F6F4">sample_proc </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">Proc</span><span style="color: #F6F6F4">.</span><span style="color: #F286C4">new</span><span style="color: #F6F6F4"> {|x| </span><span style="color: #97E1F1">puts</span><span style="color: #F6F6F4"> x}</span></span>
<span class="line"><span style="color: #7B7F8B"># Or short syntax</span></span>
<span class="line"><span style="color: #F6F6F4">sample_proc </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">proc</span><span style="color: #F6F6F4"> {|x| </span><span style="color: #97E1F1">puts</span><span style="color: #F6F6F4"> x}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #7B7F8B"># Call proc (Output: 10)</span></span>
<span class="line"><span style="color: #F6F6F4">sample_proc.call(</span><span style="color: #BF9EEE">10</span><span style="color: #F6F6F4">) </span></span>
<span class="line"><span style="color: #7B7F8B"># Or</span></span>
<span class="line"><span style="color: #F6F6F4">sample_proc[</span><span style="color: #BF9EEE">10</span><span style="color: #F6F6F4">]</span></span>
<span class="line"><span style="color: #7B7F8B"># Or</span></span>
<span class="line"><span style="color: #F6F6F4">sample_proc.</span><span style="color: #BF9EEE">10</span></span>
<span class="line"><span style="color: #7B7F8B"># Or</span></span>
<span class="line"><span style="color: #F6F6F4">sample_proc.yield(</span><span style="color: #BF9EEE">10</span><span style="color: #F6F6F4">)</span></span></code></pre></div>



<h2 id="2-lambda" class="wp-block-heading">2. Lambda</h2>



<p><strong>2.1 Khái niệm</strong></p>



<ul class="wp-block-list">
<li>Lambda là một đối tượng đặc biệt của Proc, mang lại cú pháp đơn giản hơn cho việc định nghĩa hàm</li>
</ul>



<p><strong>2.2 Khai báo và sử dụng Lambda</strong></p>



<ul class="wp-block-list">
<li>Lambda có 2 cách khai báo. Cách gọi Lambda cũng giống như  gọi Proc</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.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">Ruby</span><span role="button" tabindex="0" data-code="sample_lambda = lambda {|x| puts x}
# Or
sample_lambda = -&gt;(x) {puts x}" 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">sample_lambda </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">lambda</span><span style="color: #F6F6F4"> {|x| </span><span style="color: #97E1F1">puts</span><span style="color: #F6F6F4"> x}</span></span>
<span class="line"><span style="color: #7B7F8B"># Or</span></span>
<span class="line"><span style="color: #F6F6F4">sample_lambda </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">-&gt;</span><span style="color: #F6F6F4">(x) {</span><span style="color: #97E1F1">puts</span><span style="color: #F6F6F4"> x}</span></span></code></pre></div>



<h2 id="3-su-khac-biet" class="wp-block-heading">3. Sự khác biệt</h2>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Ngoài  syntax khai báo thì Proc và Lambda còn có những điểm khác biệt sau</p>
</blockquote>



<p><strong>3.1 Parameters</strong></p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1024" height="393" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-19.png" alt="This image has an empty alt attribute; its file name is Screen-Shot-2023-11-15-at-9.42.33-AM-1024x393.png" class="wp-image-1848" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-19.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-19-300x115.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-19-768x295.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-19-380x146.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-19-800x307.png 800w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Proc không cần truyền đúng số lượng <code>arguments</code> vẫn hoạt động tốt</li>



<li>Lambda bắt buộc truyền đúng số lượng <code>arguments</code> nếu không sẽ raise errors</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="370" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.58.53-AM-1024x370.png" alt="" class="wp-image-1876" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.58.53-AM-1024x370.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.58.53-AM-300x108.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.58.53-AM-768x277.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.58.53-AM-1536x554.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.58.53-AM-380x137.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.58.53-AM-800x289.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.58.53-AM-1160x419.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.58.53-AM.png 1718w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Proc có khả năng giải cấu trúc mảng để tương ứng với <code>arguments</code></li>



<li>Lambda thì không</li>
</ul>



<p><strong>3.2 Return</strong></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="450" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.05.44-AM-1024x450.png" alt="" class="wp-image-1854" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.05.44-AM-1024x450.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.05.44-AM-300x132.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.05.44-AM-768x337.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.05.44-AM-380x167.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.05.44-AM-800x352.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.05.44-AM-1160x510.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.05.44-AM.png 1238w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Khi gặp lệnh <code>return</code> trong method
<ul class="wp-block-list">
<li>Proc lập tức thoát hàm và không xử lý gì thêm</li>



<li>Lambda vẫn xử lý như một method thông thường</li>
</ul>
</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="497" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.21.13-AM-1024x497.png" alt="" class="wp-image-1860" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.21.13-AM-1024x497.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.21.13-AM-300x146.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.21.13-AM-768x373.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.21.13-AM-1536x745.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.21.13-AM-380x184.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.21.13-AM-800x388.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.21.13-AM-1160x563.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.21.13-AM.png 1670w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Khi <code>return</code> hiện diện trực tiếp trong block
<ul class="wp-block-list">
<li>Proc sẽ báo lỗi khi gọi</li>



<li>Lambda vẫn hoạt động tốt<br></li>
</ul>
</li>
</ul>



<pre class="wp-block-code"><code>Đây là lý do vì sao trong Rails, bạn sẽ hiếm khi thấy ai dùng Proc để viết scope, vì Proc kém linh hoạt hơn Lambda ở cú pháp return này</code></pre>



<h2 id="4-mot-vai-method-khac" class="wp-block-heading">4. Một vài method khác</h2>



<p><strong>4.1 lambda?</strong></p>



<p>Để kiểm tra một đối tượng Proc có phải là lambda hay không</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="628" height="202" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-11.06.07-AM.png" alt="" class="wp-image-1877" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-11.06.07-AM.png 628w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-11.06.07-AM-300x96.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-11.06.07-AM-380x122.png 380w" sizes="auto, (max-width: 628px) 100vw, 628px" /></figure>



<p><strong>4.2 <strong>source_location</strong></strong></p>



<p>Trả về tên file và số dòng chứa đối tượng Proc này</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="924" height="202" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-20.png" alt="This image has an empty alt attribute; its file name is Screen-Shot-2023-11-15-at-11.13.57-AM.png" class="wp-image-1881" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-20.png 924w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-20-300x66.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-20-768x168.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-20-380x83.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-20-800x175.png 800w" sizes="auto, (max-width: 924px) 100vw, 924px" /></figure>



<p><strong>4.3 Others</strong></p>



<p>Còn rất nhiều method hữu ích dành cho <code>proc</code> và <code>lambda</code>, bạn có thể tham khảo trực tiếp trên docs của Ruby</p>



<p><a href="https://ruby-doc.org/3.1.2/Proc.html">https://ruby-doc.org/3.1.2/Proc.html</a></p>



<h2 id="5-loi-ket" class="wp-block-heading">5. Lời kết</h2>



<ul class="wp-block-list">
<li>Chúng ta đã khám phá xong sự khác biệt giữa <code>Proc</code> và <code>Lambda</code> trong Ruby</li>



<li>Dù cả hai đều là đối tượng của Proc nhưng Lambda mang lại sự linh hoạt hơn với cú pháp khai báo, xử lý tham số nghiêm túc, và kiểm soát lệnh <code>return</code></li>



<li><code>Proc</code> và <code>Lambda</code> đều có vai trò quan trọng trong việc làm cho mã nguồn Ruby trở nên mạnh mẽ và dễ đọc hơn, tùy thuộc vào ngữ cảnh sử dụng</li>
</ul>
<p>The post <a href="https://blog.tomosia.com.vn/proc-va-lambda-trong-ruby-su-khac-biet-va-cach-su-dung/">Proc và Lambda trong Ruby: Sự Khác Biệt và Cách Sử Dụng</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/proc-va-lambda-trong-ruby-su-khac-biet-va-cach-su-dung/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
	</channel>
</rss>
