<?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>Dang Van Luan, Author at Tomoshare</title>
	<atom:link href="https://blog.tomosia.com.vn/author/luandang/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.tomosia.com.vn/author/luandang/</link>
	<description>Kênh chia sẻ kiến thức Tomosia Việt Nam</description>
	<lastBuildDate>Tue, 26 Dec 2023 01:58:55 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://blog.tomosia.com.vn/wp-content/uploads/2023/09/cropped-icon-32x32.png</url>
	<title>Dang Van Luan, Author at Tomoshare</title>
	<link>https://blog.tomosia.com.vn/author/luandang/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<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 class="wp-block-paragraph">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 class="wp-block-paragraph">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 class="wp-block-paragraph">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 class="wp-block-paragraph">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 class="wp-block-paragraph">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 class="wp-block-paragraph">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 class="wp-block-paragraph">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 class="wp-block-paragraph">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 class="wp-block-paragraph">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 class="wp-block-paragraph">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 class="wp-block-paragraph">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 class="wp-block-paragraph"><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>8</slash:comments>
		
		
			</item>
		<item>
		<title>Sử dụng :where() và :is() trong CSS Selector &#8211; Ngắn gọn và mạnh mẽ</title>
		<link>https://blog.tomosia.com.vn/su-dung-where-va-is-trong-css-selector-ngan-gon-va-manh-me/</link>
					<comments>https://blog.tomosia.com.vn/su-dung-where-va-is-trong-css-selector-ngan-gon-va-manh-me/#comments</comments>
		
		<dc:creator><![CDATA[Dang Van Luan]]></dc:creator>
		<pubDate>Tue, 28 Nov 2023 06:10:35 +0000</pubDate>
				<category><![CDATA[Html/CSS]]></category>
		<category><![CDATA[css selector]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[html]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=1998</guid>

					<description><![CDATA[<p>CSS (Cascading Style Sheets) ngày càng phát triển với những tính năng mới, và một số pseudo-classes mới&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/su-dung-where-va-is-trong-css-selector-ngan-gon-va-manh-me/">Sử dụng :where() và :is() trong CSS Selector &#8211; Ngắn gọn và mạnh mẽ</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"> CSS (Cascading Style Sheets) ngày càng phát triển với những tính năng mới, và một số pseudo-classes mới như <code>:where()</code> và <code>:is()</code> đã giúp làm cho việc chọn lựa và áp dụng kiểu cho các phần tử trở nên linh hoạt và dễ dàng hơn. Trong bài viết này, chúng ta sẽ khám phá cách sử dụng <code>:where()</code> và <code>:is()</code> để tối ưu hóa CSS selector.</p>



<h3 id="i-tai-sao-chung-ta-can-where-va-is" class="wp-block-heading">I. <strong>Tại sao chúng ta cần <code>:where()</code> và <code>:is()</code>?</strong></h3>



<p class="wp-block-paragraph">Trước khi có những pseudo-classes này, để áp dụng kiểu cho nhiều selector, chúng ta thường phải sử dụng một danh sách dài các selector, đôi khi dẫn đến mã CSS dài và khó đọc. Cùng xem xét một 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">CSS</span><span role="button" tabindex="0" data-code="h1, h2, h3, h4, h5, h6 {
  color: blue;
}" 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">h1</span><span style="color: #F6F6F4">,</span><span style="color: #F286C4"> h2</span><span style="color: #F6F6F4">,</span><span style="color: #F286C4"> h3</span><span style="color: #F6F6F4">,</span><span style="color: #F286C4"> h4</span><span style="color: #F6F6F4">,</span><span style="color: #F286C4"> h5</span><span style="color: #F6F6F4">,</span><span style="color: #F286C4"> h6</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #97E1F1">color</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">blue</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">Trong trường hợp này, chúng ta muốn áp dụng màu xanh cho tất cả các phần tử tiêu đề từ h1 đến h6. Tuy nhiên, khi cần loại bỏ một số phần tử khỏi danh sách, chúng ta phải lặp lại toàn bộ danh sách và loại bỏ chúng:</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">CSS</span><span role="button" tabindex="0" data-code="h1, h2, h3, h5, h6 {
  color: blue;
}" 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">h1</span><span style="color: #F6F6F4">,</span><span style="color: #F286C4"> h2</span><span style="color: #F6F6F4">,</span><span style="color: #F286C4"> h3</span><span style="color: #F6F6F4">,</span><span style="color: #F286C4"> h5</span><span style="color: #F6F6F4">,</span><span style="color: #F286C4"> h6</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #97E1F1">color</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">blue</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">Với <code>:where()</code> và <code>:is()</code>, chúng ta có cách tiếp cận mới giúp giảm sự lặp lại và làm cho mã CSS trở nên sáng sủa hơn.</p>



<h3 id="ii-su-dung-where-va-is" class="wp-block-heading">II. <strong>Sử Dụng <code>:where()</code> và <code>:is()</code></strong></h3>



<h4 id="1-su-dung-where" class="wp-block-heading">1. <strong>Sử dụng <code>:where()</code></strong></h4>



<p class="wp-block-paragraph">Cú pháp của <code>:where()</code> rất đơn giản. Nó cho phép bạn nhóm các selector lại một cách hiệu quả mà không cần phải lặp lại toàn bộ danh sách:</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">CSS</span><span role="button" tabindex="0" data-code=":where(h1, h2, h3, h4, h5, h6) {
  color: blue;
}" 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; font-style: italic">:</span><span style="color: #62E884; font-style: italic">where</span><span style="color: #F286C4">(h1</span><span style="color: #F6F6F4">,</span><span style="color: #F286C4"> h2</span><span style="color: #F6F6F4">,</span><span style="color: #F286C4"> h3</span><span style="color: #F6F6F4">,</span><span style="color: #F286C4"> h4</span><span style="color: #F6F6F4">,</span><span style="color: #F286C4"> h5</span><span style="color: #F6F6F4">,</span><span style="color: #F286C4"> h6)</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #97E1F1">color</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">blue</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">Câu lệnh trên sẽ có kết quả giống như ví dụ đầu tiên, áp dụng màu xanh cho tất cả các phần tử tiêu đề từ h1 đến h6</p>



<h4 id="2-su-dung-is" class="wp-block-heading">2. <strong>Sử dụng <code>:is()</code></strong></h4>



<p class="wp-block-paragraph">Tương tự như <code>:where()</code>, <code>:is()</code> cung cấp một cách khác để nhóm các selector:</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">CSS</span><span role="button" tabindex="0" data-code=":is(h1, h2, h3, h4, h5, h6) {
  color: blue;
}" 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; font-style: italic">:</span><span style="color: #62E884; font-style: italic">is</span><span style="color: #F286C4">(h1</span><span style="color: #F6F6F4">,</span><span style="color: #F286C4"> h2</span><span style="color: #F6F6F4">,</span><span style="color: #F286C4"> h3</span><span style="color: #F6F6F4">,</span><span style="color: #F286C4"> h4</span><span style="color: #F6F6F4">,</span><span style="color: #F286C4"> h5</span><span style="color: #F6F6F4">,</span><span style="color: #F286C4"> h6)</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #97E1F1">color</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">blue</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">Cả hai cách tiếp cận đều tạo ra kết quả tương tự và giúp bạn làm cho mã CSS ngắn gọn hơn và dễ đọc hơn.</p>



<h3 id="iii-uu-diem-va-luu-y" class="wp-block-heading">III. <strong>Ưu điểm và Lưu ý</strong></h3>



<h4 id="1-ngan-gon-va-de-doc" class="wp-block-heading">1. <strong>Ngắn Gọn và Dễ Đọc:</strong></h4>



<p class="wp-block-paragraph">Cả <code>:where()</code> và <code>:is()</code> giúp giảm sự lặp lại trong mã CSS, làm cho nó trở nên ngắn gọn và dễ đọc hơn.</p>



<h4 id="2-tich-hop-de-dang" class="wp-block-heading">2. <strong>Tích hợp Dễ Dàng:</strong></h4>



<p class="wp-block-paragraph">Cả hai pseudo-classes này tích hợp tốt với các selector khác, giúp bạn duy trì tính tương thích và tính linh hoạt trong mã nguồn của mình.</p>



<h4 id="3-de-bao-tri" class="wp-block-heading">3. <strong>Dễ Bảo Trì:</strong></h4>



<p class="wp-block-paragraph">Khi cần thêm hoặc loại bỏ các selector, bạn chỉ cần thực hiện thay đổi ở một địa điểm duy nhất, giúp dễ bảo trì hơn.</p>



<h4 id="4-trinh-duyet-ho-tro" class="wp-block-heading">4. <strong>Trình duyệt hỗ trợ:</strong></h4>



<p class="wp-block-paragraph"><strong>:where()</strong></p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="327" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/where_support-1024x327.png" alt="" class="wp-image-2030" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/where_support-1024x327.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/where_support-300x96.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/where_support-768x245.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/where_support-380x121.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/where_support-800x255.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/where_support-1160x370.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/where_support.png 1382w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph"><strong>:is()</strong></p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="354" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/is_support-1024x354.png" alt="" class="wp-image-2031" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/is_support-1024x354.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/is_support-300x104.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/is_support-768x266.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/is_support-380x131.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/is_support-800x277.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/is_support-1160x401.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/is_support.png 1368w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h3 id="iv-ket-luan" class="wp-block-heading">IV. <strong>Kết Luận</strong></h3>



<p class="wp-block-paragraph">Sử dụng <code>:where()</code> và <code>:is()</code> trong CSS selector mang lại những lợi ích đáng kể về sự ngắn gọn và dễ đọc. Đặc biệt, chúng là một công cụ hữu ích khi bạn cần áp dụng kiểu cho nhiều phần tử cùng loại một cách linh hoạt. Hãy tích hợp chúng vào công cụ lập trình CSS của bạn để trải nghiệm sự tiện lợi mà chúng mang lại.</p>
<p>The post <a href="https://blog.tomosia.com.vn/su-dung-where-va-is-trong-css-selector-ngan-gon-va-manh-me/">Sử dụng :where() và :is() trong CSS Selector &#8211; Ngắn gọn và mạnh mẽ</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/su-dung-where-va-is-trong-css-selector-ngan-gon-va-manh-me/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
		<item>
		<title>Khám Phá CSS Parent Selector :has()</title>
		<link>https://blog.tomosia.com.vn/kham-pha-css-parent-selector-has/</link>
					<comments>https://blog.tomosia.com.vn/kham-pha-css-parent-selector-has/#comments</comments>
		
		<dc:creator><![CDATA[Dang Van Luan]]></dc:creator>
		<pubDate>Tue, 28 Nov 2023 06:07:36 +0000</pubDate>
				<category><![CDATA[Html/CSS]]></category>
		<category><![CDATA[css selector]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[html]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=2036</guid>

					<description><![CDATA[<p>CSS, ngôn ngữ định dạng trang web mạnh mẽ, ngày càng được cải tiến với những tính năng&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/kham-pha-css-parent-selector-has/">Khám Phá CSS Parent Selector :has()</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">CSS, ngôn ngữ định dạng trang web mạnh mẽ, ngày càng được cải tiến với những tính năng mới giúp lập trình viên tối ưu hóa mã CSS của mình. Một trong những thêm mới gần đây là pseudo-class <code>:has()</code>, mang lại khả năng lựa chọn các phần tử dựa trên nội dung của chúng. Trong bài viết này, chúng ta sẽ chi tiết tìm hiểu về cú pháp và ứng dụng của <code>:has()</code>.</p>



<h3 id="i-gioi-thieu-ve-has" class="wp-block-heading">I. <strong>Giới Thiệu về :has()</strong></h3>



<p class="wp-block-paragraph"><code>:has()</code> là một pseudo-class mới trong CSS, cho phép bạn chọn các phần tử cha dựa trên nội dung của các phần tử con bên trong chúng. Cú pháp cơ bản 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">CSS</span><span role="button" tabindex="0" data-code="parent:has(child) {
  /* CSS styles */ 
}" 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">parent</span><span style="color: #F286C4; font-style: italic">:</span><span style="color: #62E884; font-style: italic">has</span><span style="color: #F286C4">(child)</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #7B7F8B">/* CSS styles */</span><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">Với <code>:has()</code>, bạn có thể áp dụng kiểu cho các phần tử cha chứa một hoặc nhiều phần tử con cụ thể, làm cho việc chọn lựa và định dạng trang web trở nên linh hoạt hơn.</p>



<h3 id="ii-su-dung-cu-phap-has" class="wp-block-heading">II. <strong>Sử Dụng Cú Pháp :has()</strong></h3>



<h4 id="1-chon-parent-co-phan-tu-con-cu-the" class="wp-block-heading">1. <strong>Chọn Parent Có Phần Tử Con Cụ Thể</strong></h4>



<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">CSS</span><span role="button" tabindex="0" data-code="div:has(p) {
  background-color: #f0f0f0;
}" 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">div</span><span style="color: #F286C4; font-style: italic">:</span><span style="color: #62E884; font-style: italic">has</span><span style="color: #F286C4">(p)</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #97E1F1">background-color</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">#f0f0f0</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">Trong trường hợp này, tất cả các <code>div</code> chứa ít nhất một phần tử <code>p</code> sẽ có nền màu xám nhạt.</p>



<h4 id="2-ket-hop-nhieu-phan-tu-con" class="wp-block-heading">2. <strong>Kết Hợp Nhiều Phần Tử Con</strong></h4>



<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">CSS</span><span role="button" tabindex="0" data-code="article:has(h2, p) {
  border: 1px solid #ccc;
}" 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">article</span><span style="color: #F286C4; font-style: italic">:</span><span style="color: #62E884; font-style: italic">has</span><span style="color: #F286C4">(h2</span><span style="color: #F6F6F4">,</span><span style="color: #F286C4"> p)</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #97E1F1">border</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">1</span><span style="color: #F286C4">px</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">solid</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">#ccc</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">Câu lệnh trên sẽ chọn tất cả các phần tử <code>article</code> chứa ít nhất một phần tử <code>h2</code> hoặc <code>p</code> và áp dụng đường viền xám nhạt.</p>



<h4 id="3-su-dung-nested-has" class="wp-block-heading">3. <strong>Sử Dụng Nested :has()</strong></h4>



<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">CSS</span><span role="button" tabindex="0" data-code="section:has(article:has(h2)) {
  margin: 10px;
}" 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">section</span><span style="color: #F286C4; font-style: italic">:</span><span style="color: #62E884; font-style: italic">has</span><span style="color: #F286C4">(article</span><span style="color: #F286C4; font-style: italic">:</span><span style="color: #62E884; font-style: italic">has</span><span style="color: #F286C4">(h2))</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #97E1F1">margin</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">10</span><span style="color: #F286C4">px</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">Trong trường hợp này, <code>section</code> sẽ được chọn nếu nó chứa ít nhất một <code>article</code> có chứa ít nhất một phần tử <code>h2</code>.</p>



<h3 id="iii-uu-diem-va-han-che" class="wp-block-heading">III. <strong>Ưu Điểm và Hạn Chế</strong></h3>



<h4 id="1-uu-diem-cua-has" class="wp-block-heading">1. <strong>Ưu Điểm của :has()</strong></h4>



<ul class="wp-block-list">
<li><strong>Linh Hoạt:</strong> Cho phép bạn chọn các phần tử cha dựa trên nội dung của phần tử con, mang lại sự linh hoạt cao khi định dạng trang web.</li>



<li><strong>Dễ Đọc:</strong> Làm cho mã CSS trở nên rõ ràng hơn, giảm sự phức tạp của selector.</li>
</ul>



<h4 id="2-han-che-va-luu-y" class="wp-block-heading">2. <strong>Hạn Chế và Lưu ý</strong></h4>



<ul class="wp-block-list">
<li><strong>Hạn Chế Sự Linh Hoạt:</strong> Mặc dù mạnh mẽ, nhưng <code>:has()</code> có thể hạn chế sự linh hoạt khi so sánh với một số phương pháp khác như JavaScript.</li>



<li><strong>Hỗ Trợ Trình Duyệt:</strong> Hiện tại, <code>:has()</code> chưa được hỗ trợ rộng rãi, vì vậy hãy kiểm tra hỗ trợ trình duyệt trước khi sử dụng.</li>
</ul>



<h4 id="3-trinh-duyet-ho-tro" class="wp-block-heading">3. Trình duyệt hỗ trợ</h4>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="422" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/has_supprot-1024x422.png" alt="" class="wp-image-2038" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/has_supprot-1024x422.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/has_supprot-300x124.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/has_supprot-768x317.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/has_supprot-380x157.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/has_supprot-800x330.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/has_supprot-1160x478.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/has_supprot.png 1370w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h3 id="iv-ket-luan" class="wp-block-heading">IV. <strong>Kết Luận</strong></h3>



<p class="wp-block-paragraph">Pseudo-class <code>:has()</code> mang lại một cách tiếp cận mới và thú vị cho việc chọn các phần tử cha dựa trên nội dung của phần tử con trong CSS. Tuy nhiên, đối với sự hỗ trợ và linh hoạt, cân nhắc kết hợp <code>:has()</code> với các phương pháp khác để đảm bảo tính ổn định và tương thích trình duyệt. Hãy thử nghiệm và tận dụng sức mạnh của <code>:has()</code> để tối ưu hóa mã CSS của bạn.</p>
<p>The post <a href="https://blog.tomosia.com.vn/kham-pha-css-parent-selector-has/">Khám Phá CSS Parent Selector :has()</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/kham-pha-css-parent-selector-has/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
		<item>
		<title>Sentry for Rails</title>
		<link>https://blog.tomosia.com.vn/sentry-for-rails/</link>
					<comments>https://blog.tomosia.com.vn/sentry-for-rails/#comments</comments>
		
		<dc:creator><![CDATA[Dang Van Luan]]></dc:creator>
		<pubDate>Tue, 17 Oct 2023 02:39:51 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[Rails]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=1277</guid>

					<description><![CDATA[<p>Đặt vấn đề Trong quá trình phát triển web, không tránh khỏi việc ứng dụng của chúng ta&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/sentry-for-rails/">Sentry for Rails</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="718" height="250" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-44.png" alt="" class="wp-image-1291" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-44.png 718w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-44-300x104.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-44-380x132.png 380w" sizes="auto, (max-width: 718px) 100vw, 718px" /></figure>



<h2 id="dat-van-de" class="wp-block-heading">Đặt vấn đề</h2>



<p class="wp-block-paragraph">Trong quá trình phát triển web, không tránh khỏi việc ứng dụng của chúng ta xảy lỗi hệ thống.Mỗi lỗi hệ thống, crash, hoặc sự cố có thể gây ra tác động nghiêm trọng đến trải nghiệm người dùng và ảnh hưởng đến hiệu suất của ứng dụng. Sentry là một lựa chọn có thể giúp chúng ta kiểm soát tình hình và quản lý các lỗi hệ thống này một cách hiệu quả.</p>



<h2 id="gioi-thieu-sentry" class="wp-block-heading">Giới thiệu Sentry</h2>



<p class="wp-block-paragraph">Sentry là một dịch vụ giám sát lỗi và hiểu lỗi phát triển dành cho các ứng dụng web và di động. Sentry giúp các nhà phát triển theo dõi và kiểm soát lỗi trong ứng dụng của họ để cải thiện chất lượng và hiệu suất của ứng dụng. Dưới đây là một số điểm quan trọng về Sentry:</p>



<ol class="wp-block-list">
<li><strong>Giám sát Lỗi (Error Monitoring)</strong>: Sentry thu thập thông tin về lỗi và sự cố trong ứng dụng và hiển thị chúng trong một giao diện quản trị để giúp bạn dễ dàng theo dõi và quản lý lỗi.</li>



<li><strong>Ghi Log (Logging)</strong>: Ngoài việc giám sát lỗi, Sentry cũng hỗ trợ ghi log để giúp bạn theo dõi và hiểu hơn về hoạt động của ứng dụng.</li>



<li><strong>Integrations</strong>: Sentry có khả năng tích hợp với nhiều ngôn ngữ lập trình và framework phổ biến như JavaScript, Python, Ruby, PHP, Java, và nhiều ứng dụng web framework khác.</li>



<li><strong>Tích hợp CICD</strong>: Sentry có thể tích hợp vào quy trình Continuous Integration và Continuous Deployment (CI/CD) để đảm bảo rằng lỗi không xuất hiện trong các phiên bản mới của ứng dụng.</li>



<li><strong>Thời gian thực (Real-Time)</strong>: Sentry cung cấp thông tin về lỗi và sự cố trong thời gian thực, giúp bạn nhanh chóng phát hiện và giải quyết các vấn đề liên quan đến hiệu suất của ứng dụng.</li>



<li><strong>Cấu hình tùy chỉnh (Customization)</strong>: Bạn có thể tùy chỉnh Sentry để phản ánh cơ cấu tổ chức và yêu cầu riêng của ứng dụng của bạn.</li>
</ol>



<p class="wp-block-paragraph"><em>Sentry là một công cụ quan trọng trong việc quản lý và cải thiện chất lượng của ứng dụng, giúp đảm bảo rằng lỗi được xử lý một cách hiệu quả và <strong>không ảnh hưởng đến trải nghiệm người dùng</strong>.</em></p>



<h2 id="config-sentry-cho-rails-app" class="wp-block-heading">Config Sentry cho Rails app</h2>



<p class="wp-block-paragraph">Đăng ký / Đăng nhập tại <a href="https://sentry.io/">đây</a></p>



<p class="wp-block-paragraph">Sau khi đăng nhập hãy tạo 1 project</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="784" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_2-1-1024x784.png" alt="" class="wp-image-1281" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_2-1-1024x784.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_2-1-300x230.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_2-1-768x588.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_2-1-380x291.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_2-1-800x612.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_2-1-1160x888.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_2-1.png 1262w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Có thể thấy Sentry hỗ trợ rất nhiều ngôn ngữ và framework. Có một option Ruby nhưng option Rails sẽ hỗ trợ nhiều hơn và dễ sử dụng.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="778" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_4-2-1024x778.png" alt="" class="wp-image-1284" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_4-2-1024x778.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_4-2-300x228.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_4-2-768x583.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_4-2-380x289.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_4-2-800x608.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_4-2-1160x881.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_4-2.png 1280w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Sau khi tạo 1 sự án, Sentry sẽ cho chúng ta 1 hướng dẫn tích hợp Sentry vào Rails app như trên</p>



<p class="wp-block-paragraph">Tiếp theo, setup cho source rails:</p>



<p class="wp-block-paragraph"><br>Add gem <em>sentry-ruby</em> và <em>sentry-rails</em></p>



<p class="wp-block-paragraph"><em>Đừng quên chạy <strong>bundle install</strong> nhé 🤣🤣</em></p>



<pre class="wp-block-code"><code>#Gemfile
gem "sentry-ruby"
gem "sentry-rails"</code></pre>



<p class="wp-block-paragraph">Khởi tạo SDK với một số cấu hình cơ bản phục vụ cho việc tracking lỗi:</p>



<pre class="wp-block-code has-small-font-size"><code>#config/initializers/sentry.rb
Sentry.init do |config|
  config.dsn = 'https://4506035982696448.ingest.sentry.io/....'
  config.send_default_pii = true
  config.include_local_variables = true
  config.breadcrumbs_logger = &#91;:sentry_logger, :active_support_logger, :http_logger]

  filter = ActiveSupport::ParameterFilter.new(Rails.application.config.filter_parameters)
  config.before_send = lambda do |event, hint|
    filter.filter(event.to_hash)
  end

  config.traces_sample_rate = 0.1
end
</code></pre>



<p class="wp-block-paragraph">Ở trong phần configure này, các cấu hình có ý nghĩa sau:<br></p>



<figure class="wp-block-table"><table><tbody><tr><td>config.dsn</td><td>Cấu hình Data Source Name (DSN) do Sentry cung cấp</td></tr><tr><td>config.send_default_pii</td><td>Đặt giá trị này thành <code>true</code> để gửi thông tin cá nhân (PII &#8211; Personally Identifiable Information) mặc định với các báo cáo lỗi. Thông tin cá nhân bao gồm địa chỉ IP và thông tin người dùng. Có thể điều chỉnh cài đặt này để bảo vệ sự riêng tư của người dùng.</td></tr><tr><td>config.include_local_variables</td><td>Đặt giá trị này thành <code>true</code> để bao gồm các biến cục bộ (local variables) trong báo cáo lỗi. Cài đặt này giúp theo dõi giá trị của các biến tại thời điểm xảy ra lỗi.</td></tr><tr><td>config.breadcrumbs_logger</td><td>Cấu hình loại logger mà Sentry sẽ sử dụng để ghi lại breadcrumbs. Trong trường hợp này, chỉ định ba loại logger: <code>:sentry_logger</code>, <code>:active_support_logger</code>, và <code>:http_logger</code>. Điều này có nghĩa là các breadcrumbs sẽ được ghi lại từ các sự kiện được ghi log bởi Sentry, Active Support, và HTTP.</td></tr><tr><td>config.before_send</td><td>Đây là một hàm lambda (anonymous function) được sử dụng để lọc dữ liệu trước khi nó được gửi đến Sentry. Trong trường hợp này, bạn sử dụng <code>ActiveSupport::ParameterFilter</code> để lọc các tham số cấu hình trong Rails để bảo vệ thông tin nhạy cảm trước khi gửi chúng đến Sentry.</td></tr><tr><td>config.traces_sample_rate</td><td>Đây là tỷ lệ mẫu (sample rate) cho việc theo dõi và thu thập dữ liệu về hiệu suất (traces). Giá trị 1.0 có nghĩa là tất cả các traces sẽ được thu thập. Nếu muốn giảm tỷ lệ thu thập, có thể đặt giá trị này dưới 1.0.</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Sau khi configure, hãy kiểm tra xem Sentry đã được tính hợp đúng trong ứng dụng của chúng ta chưa nhé!</p>



<p class="wp-block-paragraph"><br>Có thể tạo 1 <em>Exception</em> hoặc sử dụng <em>rails console</em> và chạy lệnh sau:</p>



<pre class="wp-block-code"><code>Sentry.capture_message("test message")</code></pre>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1000" height="631" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_5.png" alt="" class="wp-image-1286" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_5.png 1000w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_5-300x189.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_5-768x485.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_5-380x240.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_5-800x505.png 800w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /></figure>



<p class="wp-block-paragraph">Kết quả Sentry trả về cho chúng ta một event tracking lỗi chứa một số thông tin như: <em>thời gian, tên OS, môi trường, server name, message, vv&#8230;</em><br>như vậy có nghĩa là chúng ta đã tích hợp thành công Sentry vào Rails app<br><br>Các thông tin này sẽ được gửi lên server của Sentry và chúng ta có thể xem nó trên giao diện dasborad</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="774" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_6-1-1024x774.png" alt="" class="wp-image-1288" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_6-1-1024x774.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_6-1-300x227.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_6-1-768x581.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_6-1-380x287.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_6-1-800x605.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_6-1-1160x877.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/sentry_6-1.png 1283w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 id="summary" class="wp-block-heading">Summary</h2>



<p class="wp-block-paragraph">Tóm tắt lại, trong bài viết này, chúng ta đã tìm hiểu về Sentry, một công cụ quan trọng trong quá trình phát triển ứng dụng Rails. Sentry không chỉ giúp theo dõi và ghi lại lỗi, mà còn cung cấp nhiều tính năng hữu ích khác để cải thiện chất lượng phần mềm.</p>



<p class="wp-block-paragraph">Chúng ta đã xem xét cách tích hợp Sentry vào ứng dụng Rails, cấu hình gem, tùy chỉnh các cài đặt như gửi thông tin cá nhân, breadcrumbs, và lọc thông tin trước khi gửi đến Sentry.</p>



<p class="wp-block-paragraph">Không chỉ với Ruby hay Rails, Sentry còn hỗ trợ hơn <a href="https://docs.sentry.io/platforms/">85 Platforms</a> khác nhau.<br>Tôi nghĩ trong vòng đời ứng dụng, việc tích hợp Sentry là càng sớm càng tốt<br></p>



<p class="wp-block-paragraph"><strong>Tài liệu</strong><br><a href="https://docs.sentry.io/platforms/ruby/guides/rails/">https://docs.sentry.io/platforms/ruby/guides/rails/</a></p>
<p>The post <a href="https://blog.tomosia.com.vn/sentry-for-rails/">Sentry for Rails</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/sentry-for-rails/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
	</channel>
</rss>
