{"id":1349,"date":"2025-03-24T08:52:18","date_gmt":"2025-03-23T23:52:18","guid":{"rendered":"https:\/\/dexall.co.jp\/articles\/?p=1349"},"modified":"2025-03-24T08:52:18","modified_gmt":"2025-03-23T23:52:18","slug":"%e3%80%90%e4%bf%9d%e5%ad%98%e7%89%88%e3%80%91ruby-on-rails-activerecord%e3%81%ae%e5%ae%9f%e8%b7%b5%e7%9a%84%e3%81%aa%e4%bd%bf%e3%81%84%e6%96%b9%e3%81%a8%e6%9c%80%e9%81%a9%e5%8c%96%e3%83%86%e3%82%af","status":"publish","type":"post","link":"https:\/\/dexall.co.jp\/articles\/?p=1349","title":{"rendered":"\u3010\u4fdd\u5b58\u7248\u3011Ruby on Rails ActiveRecord\u306e\u5b9f\u8df5\u7684\u306a\u4f7f\u3044\u65b9\u3068\u6700\u9069\u5316\u30c6\u30af\u30cb\u30c3\u30af7\u9078"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\" id=\"i-0\">ActiveRecord\u3068\u306f\uff1f\u73fe\u5834\u3067\u5fc5\u8981\u306a\u57fa\u790e\u77e5\u8b58<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">ActiveRecord\u306f\u3001Ruby on Rails\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u64cd\u4f5c\u3092\u62c5\u3046\u91cd\u8981\u306a\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3067\u3059\u3002\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u6307\u5411\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u3068\u30ea\u30ec\u30fc\u30b7\u30e7\u30ca\u30eb\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u6a4b\u6e21\u3057\u3092\u884c\u3046OR\u30de\u30c3\u30d1\u30fc\uff08Object-Relational Mapper\uff09\u3068\u3057\u3066\u6a5f\u80fd\u3057\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u64cd\u4f5c\u3092\u76f4\u611f\u7684\u306b\u884c\u3046\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<div class=\"toc\"><br \/>\n<b>Warning<\/b>:  Undefined array key \"is_admin\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>116<\/b><br \/>\n<br \/>\n<b>Warning<\/b>:  Undefined array key \"is_category_top\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>121<\/b><br \/>\n<br \/>\n<b>Warning<\/b>:  Undefined array key \"is_top\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>128<\/b><br \/>\n    <div id=\"toc_container\" class=\"sgb-toc--bullets js-smooth-scroll\" data-dialog-title=\"\u76ee\u6b21\">\n      <p class=\"toc_title\">\u76ee\u6b21 <\/p>\n      <ul class=\"toc_list\">  <li class=\"first\">    <a href=\"#i-0\">ActiveRecord\u3068\u306f\uff1f\u73fe\u5834\u3067\u5fc5\u8981\u306a\u57fa\u790e\u77e5\u8b58<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-1\">ActiveRecord\u304c\u89e3\u6c7a\u3059\u308b3\u3064\u306e\u958b\u767a\u8ab2\u984c<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-2\">ActiveRecord\u306e\u52d5\u4f5c\u306e\u4ed5\u7d44\u307f\u3068\u91cd\u8981\u306a\u6982\u5ff5<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-7\">ActiveRecord\u3092\u4f7f\u3044\u3053\u306a\u3059\u305f\u3081\u306e\u5b9f\u8df5\u30c6\u30af\u30cb\u30c3\u30af<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-8\">\u8907\u96d1\u306a\u95a2\u9023\u4ed8\u3051\u3092\u52b9\u7387\u7684\u306b\u6271\u3046\u65b9\u6cd5<\/a>      <\/li>      <li>        <a href=\"#i-11\">\u30d0\u30eb\u30af\u30a4\u30f3\u30b5\u30fc\u30c8\u30fb\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u306e\u5b9f\u88c5\u65b9\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-14\">\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u51e6\u7406\u306e\u6b63\u3057\u3044\u4f7f\u3044\u65b9<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-19\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3092\u6700\u9069\u5316\u3059\u308bActiveRecord\u306e\u4f7f\u3044\u65b9<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-20\">N+1\u554f\u984c\u3092\u56de\u907f\u3059\u308bincludes\u306e\u52b9\u679c\u7684\u306a\u4f7f\u7528\u6cd5<\/a>      <\/li>      <li>        <a href=\"#i-24\">\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3092\u6d3b\u7528\u3057\u305f\u30af\u30a8\u30ea\u306e\u9ad8\u901f\u5316\u624b\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-27\">\u30ad\u30e3\u30c3\u30b7\u30e5\u6226\u7565\u3067\u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u6539\u5584\u3059\u308b\u65b9\u6cd5<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-33\">ActiveRecord\u306e\u30a2\u30f3\u30c1\u30d1\u30bf\u30fc\u30f3\u3068\u5bfe\u51e6\u6cd5<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-34\">\u30e1\u30e2\u30ea\u4f7f\u7528\u91cf\u304c\u5897\u5927\u3059\u308b\u5371\u967a\u306a\u5b9f\u88c5\u30d1\u30bf\u30fc\u30f3<\/a>      <\/li>      <li>        <a href=\"#i-38\">\u30c7\u30c3\u30c9\u30ed\u30c3\u30af\u3092\u5f15\u304d\u8d77\u3053\u3059\u5178\u578b\u7684\u306a\u30df\u30b9<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-42\">\u30a2\u30f3\u30c1\u30d1\u30bf\u30fc\u30f3\u3092\u56de\u907f\u3059\u308b\u305f\u3081\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-43\">\u5b9f\u52d9\u3067\u4f7f\u3048\u308b\u9ad8\u5ea6\u306aActiveRecord\u30c6\u30af\u30cb\u30c3\u30af<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-44\">\u30dd\u30ea\u30e2\u30fc\u30d5\u30a3\u30c3\u30af\u95a2\u9023\u4ed8\u3051\u306e\u6d3b\u7528\u30b7\u30fc\u30f3<\/a>      <\/li>      <li>        <a href=\"#i-47\">\u30b5\u30fc\u30d3\u30b9\u30af\u30e9\u30b9\u3068\u306e\u52b9\u679c\u7684\u306a\u4f75\u7528\u65b9\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-50\">\u30c6\u30b9\u30c8\u99c6\u52d5\u958b\u767a\u306b\u304a\u3051\u308bActiveRecord\u306e\u6271\u3044\u65b9<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-54\">ActiveRecord\u306e\u30e2\u30cb\u30bf\u30ea\u30f3\u30b0\u3068\u30c7\u30d0\u30c3\u30b0\u624b\u6cd5<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-55\">\u30b9\u30ed\u30fc\u30af\u30a8\u30ea\u3092\u7279\u5b9a\u3057\u3066\u6539\u5584\u3059\u308b\u624b\u9806<\/a>      <\/li>      <li>        <a href=\"#i-58\">\u672c\u756a\u74b0\u5883\u3067\u306e\u5b89\u5168\u306a\u30c7\u30d0\u30c3\u30b0\u65b9\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-61\">\u30e2\u30cb\u30bf\u30ea\u30f3\u30b0\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/a>      <\/li>    <\/ul>  <\/li>  <li class=\"last\">    <a href=\"#i-64\">ActiveRecord\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\u307e\u3068\u3081<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-65\">\u73fe\u5834\u3067\u4f7f\u3048\u308b7\u3064\u306e\u91cd\u8981\u306a\u8a2d\u8a08\u6307\u91dd<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-71\">\u4eca\u3059\u3050\u59cb\u3081\u3089\u308c\u308b\u6539\u5584\u30a2\u30af\u30b7\u30e7\u30f3<\/a>      <\/li>    <\/ul>  <\/li><\/ul>\n      <a href=\"#\" class=\"sgb-toc-button js-toc-button\" rel=\"nofollow\" data-open-dialog=\"true\"><i class=\"fa fa-list\"><\/i><span class=\"sgb-toc-button__text\">\u76ee\u6b21\u3078<\/span><\/a>\n    <\/div><\/div><h2 class=\"wp-block-heading\" id=\"i-1\">ActiveRecord\u304c\u89e3\u6c7a\u3059\u308b3\u3064\u306e\u958b\u767a\u8ab2\u984c<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>SQL\u306e\u8907\u96d1\u306a\u8a18\u8ff0\u304b\u3089\u306e\u89e3\u653e<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5f93\u6765\u306eSQL\u6587\u306e\u4ee3\u308f\u308a\u306b\u3001Ruby\u306e\u30e1\u30bd\u30c3\u30c9\u30c1\u30a7\u30fc\u30f3\u3067\u76f4\u611f\u7684\u306b\u30af\u30a8\u30ea\u3092\u8a18\u8ff0\u53ef\u80fd<\/li>\n\n\n\n<li>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u56fa\u6709\u306eSQL\u6587\u6cd5\u306e\u9055\u3044\u3092\u5438\u53ce\u3057\u3001\u7d71\u4e00\u7684\u306a\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3092\u63d0\u4f9b<\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u5f93\u6765\u306eSQL\n# SELECT * FROM users WHERE age &gt;= 20 ORDER BY created_at DESC LIMIT 10;\n\n# ActiveRecord\u3092\u4f7f\u7528\u3057\u305f\u5834\u5408\nUser.where('age &gt;= ?', 20).order(created_at: :desc).limit(10)<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30e2\u30c7\u30eb\u3068\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u4e00\u5143\u7ba1\u7406<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30c6\u30fc\u30d6\u30eb\u30b9\u30ad\u30fc\u30de\u306e\u5909\u66f4\u3092\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u30d5\u30a1\u30a4\u30eb\u3067\u7ba1\u7406<\/li>\n\n\n\n<li>\u30e2\u30c7\u30eb\u306e\u95a2\u9023\u4ed8\u3051\u3092\u76f4\u611f\u7684\u306b\u5b9a\u7fa9\u53ef\u80fd<\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class User &lt; ApplicationRecord\n  # has_many\u306b\u3088\u308b1\u5bfe\u591a\u306e\u95a2\u9023\u4ed8\u3051\n  has_many :posts\n\n  # \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5b9a\u7fa9\n  validates :email, presence: true, uniqueness: true\n  validates :age, numericality: { greater_than_or_equal_to: 0 }\nend<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u30c7\u30fc\u30bf\u306e\u6574\u5408\u6027\u7dad\u6301\u306e\u81ea\u52d5\u5316<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306b\u3088\u308b\u30c7\u30fc\u30bf\u691c\u8a3c\u306e\u81ea\u52d5\u5316<\/li>\n\n\n\n<li>\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u51e6\u7406\u306e\u7c21\u7565\u5316<\/li>\n\n\n\n<li>\u95a2\u9023\u3059\u308b\u30ec\u30b3\u30fc\u30c9\u306e\u6574\u5408\u6027\u7ba1\u7406<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-2\">ActiveRecord\u306e\u52d5\u4f5c\u306e\u4ed5\u7d44\u307f\u3068\u91cd\u8981\u306a\u6982\u5ff5<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-3\">1. \u30e2\u30c7\u30eb\u306e\u7d99\u627f\u3068\u30b9\u30ad\u30fc\u30de\u306e\u81ea\u52d5\u8a8d\u8b58<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">ActiveRecord\u306f<code>ApplicationRecord<\/code>\uff08\u307e\u305f\u306f<code>ActiveRecord::Base<\/code>\uff09\u3092\u7d99\u627f\u3059\u308b\u3053\u3068\u3067\u3001\u5bfe\u5fdc\u3059\u308b\u30c6\u30fc\u30d6\u30eb\u306e\u30b9\u30ad\u30fc\u30de\u3092\u81ea\u52d5\u7684\u306b\u8a8d\u8b58\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># app\/models\/product.rb\nclass Product &lt; ApplicationRecord\n  # \u30c6\u30fc\u30d6\u30eb\u540d\u306f\u81ea\u52d5\u7684\u306b'products'\u3068\u8a8d\u8b58\u3055\u308c\u308b\n  # \u30ab\u30e9\u30e0\u60c5\u5831\u3082\u81ea\u52d5\u7684\u306b\u53d6\u5f97\u3055\u308c\u308b\nend\n\n# \u30e2\u30c7\u30eb\u306e\u4f7f\u7528\u4f8b\nproduct = Product.new(\n  name: \"Ruby\u672c\",\n  price: 3000\n)\nproduct.save  # INSERT\u6587\u304c\u81ea\u52d5\u751f\u6210\u3055\u308c\u308b<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-4\">2. \u547d\u540d\u898f\u5247\uff08Convention over Configuration\uff09<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">ActiveRecord\u306f\u4ee5\u4e0b\u306e\u547d\u540d\u898f\u5247\u306b\u5f93\u3044\u307e\u3059\uff1a<\/p>\n\n\n<div id=\"id-e4ed5332-c0a8-43c4-8279-d5ba73a9fabf\">\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u30e2\u30c7\u30eb\uff08\u5358\u6570\u5f62\uff09<\/th><th>\u30c6\u30fc\u30d6\u30eb\uff08\u8907\u6570\u5f62\uff09<\/th><th>\u5916\u90e8\u30ad\u30fc<\/th><\/tr><\/thead><tbody><tr><td>User<\/td><td>users<\/td><td>user_id<\/td><\/tr><tr><td>Category<\/td><td>categories<\/td><td>category_id<\/td><\/tr><tr><td>Person<\/td><td>people<\/td><td>person_id<\/td><\/tr><\/tbody><\/table><\/figure>\n<\/div>\n\n\n<h3 class=\"wp-block-heading\" id=\"i-5\">3. \u30b3\u30fc\u30eb\u30d0\u30c3\u30af\u3068\u30aa\u30d6\u30b6\u30fc\u30d0\u30fc<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u30e2\u30c7\u30eb\u306e\u4fdd\u5b58\u3084\u66f4\u65b0\u6642\u306b\u81ea\u52d5\u7684\u306b\u51e6\u7406\u3092\u5b9f\u884c\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class User &lt; ApplicationRecord\n  # \u4fdd\u5b58\u524d\u306b\u5b9f\u884c\n  before_save :ensure_name_has_a_value\n\n  # \u4f5c\u6210\u5f8c\u306b\u5b9f\u884c\n  after_create :send_welcome_email\n\n  private\n\n  def ensure_name_has_a_value\n    self.name = 'Anonymous' if name.blank?\n  end\n\n  def send_welcome_email\n    UserMailer.welcome(self).deliver_later\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-6\">4. Dirty Object Tracking<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u30e2\u30c7\u30eb\u306e\u5c5e\u6027\u5909\u66f4\u3092\u8ffd\u8de1\u3059\u308b\u6a5f\u80fd\u3092\u63d0\u4f9b\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">user = User.find(1)\nuser.name = \"\u65b0\u3057\u3044\u540d\u524d\"\n\nuser.changed?  # =&gt; true\nuser.changes   # =&gt; {\"name\"=&gt;[\"\u53e4\u3044\u540d\u524d\", \"\u65b0\u3057\u3044\u540d\u524d\"]}\nuser.name_changed? # =&gt; true\nuser.name_was  # =&gt; \"\u53e4\u3044\u540d\u524d\"<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u3053\u306e\u3088\u3046\u306b\u3001ActiveRecord\u306f\u8c4a\u5bcc\u306a\u6a5f\u80fd\u3092\u63d0\u4f9b\u3057\u306a\u304c\u3089\u3001\u76f4\u611f\u7684\u306aAPI\u3067\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u64cd\u4f5c\u3092\u53ef\u80fd\u306b\u3057\u307e\u3059\u3002\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u3053\u308c\u3089\u306e\u57fa\u672c\u77e5\u8b58\u3092\u6d3b\u7528\u3057\u305f\u5b9f\u8df5\u7684\u306a\u30c6\u30af\u30cb\u30c3\u30af\u3092\u7d39\u4ecb\u3057\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"i-7\">ActiveRecord\u3092\u4f7f\u3044\u3053\u306a\u3059\u305f\u3081\u306e\u5b9f\u8df5\u30c6\u30af\u30cb\u30c3\u30af<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-8\">\u8907\u96d1\u306a\u95a2\u9023\u4ed8\u3051\u3092\u52b9\u7387\u7684\u306b\u6271\u3046\u65b9\u6cd5<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-9\">1. \u30dd\u30ea\u30e2\u30fc\u30d5\u30a3\u30c3\u30af\u95a2\u9023\u4ed8\u3051\u306e\u5b9f\u88c5<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u8907\u6570\u306e\u30e2\u30c7\u30eb\u306b\u5bfe\u3057\u3066\u540c\u3058\u95a2\u9023\u4ed8\u3051\u3092\u8a2d\u5b9a\u3059\u308b\u5834\u5408\u306b\u6709\u52b9\u3067\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># app\/models\/comment.rb\nclass Comment &lt; ApplicationRecord\n  belongs_to :commentable, polymorphic: true\nend\n\n# app\/models\/post.rb\nclass Post &lt; ApplicationRecord\n  has_many :comments, as: :commentable\nend\n\n# app\/models\/photo.rb\nclass Photo &lt; ApplicationRecord\n  has_many :comments, as: :commentable\nend\n\n# \u4f7f\u7528\u4f8b\npost = Post.first\npost.comments.create(content: \"Great post!\")\n\nphoto = Photo.first\nphoto.comments.create(content: \"Nice photo!\")<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-10\">2. \u5165\u308c\u5b50\u95a2\u4fc2\u306e\u52b9\u7387\u7684\u306a\u51e6\u7406<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">accepts_nested_attributes_for\u3092\u4f7f\u7528\u3057\u3066\u3001\u89aa\u5b50\u95a2\u4fc2\u306e\u3042\u308b\u8907\u6570\u306e\u30e2\u30c7\u30eb\u3092\u4e00\u5ea6\u306b\u66f4\u65b0\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class Order &lt; ApplicationRecord\n  has_many :order_items\n  accepts_nested_attributes_for :order_items, allow_destroy: true\n\n  # \u7279\u5b9a\u306e\u6761\u4ef6\u3067\u5b50\u30ec\u30b3\u30fc\u30c9\u3092\u524a\u9664\n  accepts_nested_attributes_for :order_items,\n    reject_if: proc { |attributes| attributes['quantity'].blank? }\nend\n\n# \u30d5\u30a9\u30fc\u30e0\u304b\u3089\u306e\u9001\u4fe1\u30c7\u30fc\u30bf\u3092\u4e00\u62ec\u3067\u4fdd\u5b58\nOrder.create(\n  customer: \"\u5c71\u7530\u592a\u90ce\",\n  order_items_attributes: [\n    { product_id: 1, quantity: 2 },\n    { product_id: 2, quantity: 1 }\n  ]\n)<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-11\">\u30d0\u30eb\u30af\u30a4\u30f3\u30b5\u30fc\u30c8\u30fb\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u306e\u5b9f\u88c5\u65b9\u6cd5<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-12\">1. insert_all\u306b\u3088\u308b\u4e00\u62ec\u633f\u5165<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u8907\u6570\u30ec\u30b3\u30fc\u30c9\u3092\u4e00\u5ea6\u306b\u633f\u5165\nUser.insert_all([\n  { name: '\u5c71\u7530', email: 'yamada@example.com' },\n  { name: '\u7530\u4e2d', email: 'tanaka@example.com' }\n], returning: %w[ id name ])\n\n# \u30bf\u30a4\u30e0\u30b9\u30bf\u30f3\u30d7\u3092\u81ea\u52d5\u8a2d\u5b9a\nUser.insert_all(\n  [ { name: '\u4f50\u85e4' }, { name: '\u9234\u6728' } ],\n  record_timestamps: true\n)<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-13\">2. update_all\u306b\u3088\u308b\u4e00\u62ec\u66f4\u65b0<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u6761\u4ef6\u306b\u5408\u81f4\u3059\u308b\u5168\u30ec\u30b3\u30fc\u30c9\u3092\u66f4\u65b0\nUser.where(active: true)\n    .update_all(newsletter: true)\n\n# \u8907\u6570\u306e\u30ab\u30e9\u30e0\u3092\u540c\u6642\u306b\u66f4\u65b0\nProduct.where('price &gt; ?', 1000)\n       .update_all('price = price * 0.9, updated_at = ?', Time.current)<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-14\">\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u51e6\u7406\u306e\u6b63\u3057\u3044\u4f7f\u3044\u65b9<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-15\">1. \u57fa\u672c\u7684\u306a\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">ActiveRecord::Base.transaction do\n  david.withdraw(100)\n  mary.deposit(100)\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-16\">2. \u30cd\u30b9\u30c8\u3057\u305f\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">User.transaction do\n  User.create!(name: '\u5c71\u7530')\n\n  # \u30cd\u30b9\u30c8\u3057\u305f\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\n  Account.transaction(requires_new: true) do\n    Account.create!(user_id: user.id, balance: 0)\n  rescue StandardError\n    # \u3053\u306e\u4f8b\u5916\u306f\u30cd\u30b9\u30c8\u3057\u305f\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306e\u307f\u3092\u30ed\u30fc\u30eb\u30d0\u30c3\u30af\n    raise ActiveRecord::Rollback\n  end\n\n  # \u5916\u5074\u306e\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306f\u7d99\u7d9a\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-17\">3. \u6761\u4ef6\u4ed8\u304d\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">def transfer_money(from_account, to_account, amount)\n  Account.transaction(isolation: :serializable) do\n    # \u6b8b\u9ad8\u30c1\u30a7\u30c3\u30af\n    raise InsufficientBalanceError unless from_account.sufficient_balance?(amount)\n\n    from_account.withdraw(amount)\n    to_account.deposit(amount)\n\n    # \u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306e\u5b8c\u4e86\u3092\u4fdd\u8a3c\n    raise ActiveRecord::Rollback unless from_account.save &amp;&amp; to_account.save\n  end\nrescue ActiveRecord::RecordInvalid\n  # \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30a8\u30e9\u30fc\u306e\u51e6\u7406\n  false\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-18\">\u91cd\u8981\u306a\u5b9f\u88c5\u306e\u30dd\u30a4\u30f3\u30c8<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306e\u5206\u96e2\u30ec\u30d9\u30eb<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>:read_uncommitted<\/code><\/li>\n\n\n\n<li><code>:read_committed<\/code><\/li>\n\n\n\n<li><code>:repeatable_read<\/code><\/li>\n\n\n\n<li><code>:serializable<\/code><\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u5206\u96e2\u30ec\u30d9\u30eb\u306e\u6307\u5b9a\nPost.transaction(isolation: :serializable) do\n  # \u53b3\u5bc6\u306a\u76f4\u5217\u5316\u304c\u5fc5\u8981\u306a\u51e6\u7406\nend<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30c7\u30c3\u30c9\u30ed\u30c3\u30af\u5bfe\u7b56<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">retry_count = 0\nbegin\n  Post.transaction do\n    # \u30c7\u30c3\u30c9\u30ed\u30c3\u30af\u306e\u53ef\u80fd\u6027\u304c\u3042\u308b\u51e6\u7406\n  end\nrescue ActiveRecord::Deadlocked\n  retry_count += 1\n  raise if retry_count &gt; 3\n  sleep(0.1 * retry_count)\n  retry\nend<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u30b3\u30fc\u30eb\u30d0\u30c3\u30af\u3068\u306e\u9023\u643a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class Order &lt; ApplicationRecord\n  after_commit :send_confirmation_email, on: :create\n  after_rollback :notify_admin_of_failure\n\n  private\n\n  def send_confirmation_email\n    OrderMailer.confirmation(self).deliver_later\n  end\n\n  def notify_admin_of_failure\n    AdminNotifier.failure_alert(self).deliver_now\n  end\nend<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u3053\u308c\u3089\u306e\u30c6\u30af\u30cb\u30c3\u30af\u3092\u9069\u5207\u306b\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3001\u52b9\u7387\u7684\u3067\u4fe1\u983c\u6027\u306e\u9ad8\u3044\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u64cd\u4f5c\u3092\u5b9f\u73fe\u3067\u304d\u307e\u3059\u3002\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u3053\u308c\u3089\u306e\u64cd\u4f5c\u3092\u3055\u3089\u306b\u6700\u9069\u5316\u3059\u308b\u65b9\u6cd5\u306b\u3064\u3044\u3066\u8aac\u660e\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"i-19\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3092\u6700\u9069\u5316\u3059\u308bActiveRecord\u306e\u4f7f\u3044\u65b9<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-20\">N+1\u554f\u984c\u3092\u56de\u907f\u3059\u308bincludes\u306e\u52b9\u679c\u7684\u306a\u4f7f\u7528\u6cd5<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-21\">N+1\u554f\u984c\u3068\u306f<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">N+1\u554f\u984c\u306f\u3001\u95a2\u9023\u4ed8\u3051\u3089\u308c\u305f\u30ec\u30b3\u30fc\u30c9\u3092\u53d6\u5f97\u3059\u308b\u969b\u306b\u767a\u751f\u3059\u308b\u4f59\u5206\u306a\u30af\u30a8\u30ea\u767a\u884c\u306e\u554f\u984c\u3067\u3059\u3002\u4ee5\u4e0b\u306e\u4f8b\u3067\u8aac\u660e\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># N+1\u554f\u984c\u304c\u767a\u751f\u3059\u308b\u30b3\u30fc\u30c9\nposts = Post.all\nposts.each do |post|\n  puts post.user.name  # \u5404\u6295\u7a3f\u306b\u5bfe\u3057\u3066\u30e6\u30fc\u30b6\u30fc\u60c5\u5831\u3092\u53d6\u5f97\u3059\u308b\u30af\u30a8\u30ea\u304c\u767a\u884c\u3055\u308c\u308b\nend\n\n# \u5b9f\u884c\u3055\u308c\u308bSQL\n# SELECT * FROM posts\n# SELECT * FROM users WHERE id = 1\n# SELECT * FROM users WHERE id = 2\n# SELECT * FROM users WHERE id = 3\n# ...<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-22\">includes\/preload\u306b\u3088\u308b\u89e3\u6c7a<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># N+1\u554f\u984c\u3092\u89e3\u6c7a\u3059\u308b\u30b3\u30fc\u30c9\nposts = Post.includes(:user)\nposts.each do |post|\n  puts post.user.name  # \u8ffd\u52a0\u306e\u30af\u30a8\u30ea\u306f\u767a\u884c\u3055\u308c\u306a\u3044\nend\n\n# \u5b9f\u884c\u3055\u308c\u308bSQL\n# SELECT * FROM posts\n# SELECT * FROM users WHERE id IN (1, 2, 3, ...)<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-23\">\u8907\u96d1\u306a\u95a2\u9023\u4ed8\u3051\u3067\u306e\u6700\u9069\u5316<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u8907\u6570\u306e\u95a2\u9023\u4ed8\u3051\u3092\u540c\u6642\u306b\u6700\u9069\u5316\nposts = Post.includes(:user, comments: :user)\n\n# \u6761\u4ef6\u4ed8\u304d\u306e\u95a2\u9023\u4ed8\u3051\nposts = Post.includes(:comments)\n            .where(comments: { status: 'approved' })\n            .references(:comments)\n\n# \u30cd\u30b9\u30c8\u3057\u305f\u95a2\u9023\u4ed8\u3051\nposts = Post.includes(comments: [{ user: :profile }, :likes])<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-24\">\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3092\u6d3b\u7528\u3057\u305f\u30af\u30a8\u30ea\u306e\u9ad8\u901f\u5316\u624b\u6cd5<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-25\">1. \u9069\u5207\u306a\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u8a2d\u8a08<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3067\u306e\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u8a2d\u5b9a\nclass AddIndexesToPosts &lt; ActiveRecord::Migration[7.0]\n  def change\n    # \u5358\u4e00\u30ab\u30e9\u30e0\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\n    add_index :posts, :published_at\n\n    # \u8907\u5408\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\n    add_index :posts, [:user_id, :published_at]\n\n    # \u30e6\u30cb\u30fc\u30af\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\n    add_index :posts, :slug, unique: true\n\n    # \u90e8\u5206\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\n    add_index :posts, :published_at, \n              where: \"status = 'published'\"\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-26\">2. \u30af\u30a8\u30ea\u6700\u9069\u5316\u306e\u5b9f\u8df5\u4f8b<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3092\u6d3b\u7528\u3059\u308b\u30af\u30a8\u30ea\nclass Post &lt; ApplicationRecord\n  # \u983b\u7e41\u306b\u4f7f\u7528\u3055\u308c\u308b\u691c\u7d22\u6761\u4ef6\u306b\u30b9\u30b3\u30fc\u30d7\u3092\u5b9a\u7fa9\n  scope :recent_published, -&gt; {\n    where(status: 'published')\n    .order(published_at: :desc)\n    .limit(10)\n  }\n\n  # \u8907\u5408\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3092\u6d3b\u7528\u3059\u308b\u691c\u7d22\n  scope :by_author_and_date, -&gt;(author_id, date) {\n    where(author_id: author_id)\n    .where('published_at &gt;= ?', date)\n  }\nend<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-27\">\u30ad\u30e3\u30c3\u30b7\u30e5\u6226\u7565\u3067\u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u6539\u5584\u3059\u308b\u65b9\u6cd5<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-28\">1. \u30e2\u30c7\u30eb\u30ad\u30e3\u30c3\u30b7\u30e5<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30ad\u30e3\u30c3\u30b7\u30e5\u30ad\u30fc\u306e\u8a2d\u5b9a\nclass Post &lt; ApplicationRecord\n  include ActiveModel::Caching\n\n  # \u30bf\u30c3\u30c1\u30aa\u30d7\u30b7\u30e7\u30f3\u3067\u95a2\u9023\u30e2\u30c7\u30eb\u306e\u30ad\u30e3\u30c3\u30b7\u30e5\u3082\u66f4\u65b0\n  belongs_to :user, touch: true\n\n  # \u30ad\u30e3\u30c3\u30b7\u30e5\u30ad\u30fc\u306e\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\n  def cache_key\n    \"#{super}-#{Digest::MD5.hexdigest(content)}\"\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-29\">2. \u30af\u30a8\u30ea\u30ad\u30e3\u30c3\u30b7\u30e5<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># find_by\u306e\u7d50\u679c\u3092\u30ad\u30e3\u30c3\u30b7\u30e5\ndef find_post_by_slug(slug)\n  Rails.cache.fetch(\"post\/#{slug}\", expires_in: 12.hours) do\n    Post.find_by(slug: slug)\n  end\nend\n\n# \u8907\u96d1\u306a\u30af\u30a8\u30ea\u7d50\u679c\u306e\u30ad\u30e3\u30c3\u30b7\u30e5\ndef trending_posts\n  Rails.cache.fetch('trending_posts', expires_in: 1.hour) do\n    Post.joins(:views)\n        .group('posts.id')\n        .order('COUNT(views.id) DESC')\n        .limit(10)\n        .to_a\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-30\">3. \u30ed\u30a6\u30ec\u30d9\u30eb\u30ad\u30e3\u30c3\u30b7\u30e5<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class Post &lt; ApplicationRecord\n  # \u30ab\u30a6\u30f3\u30bf\u30fc\u30ad\u30e3\u30c3\u30b7\u30e5\n  belongs_to :category, counter_cache: true\n\n  # \u7b97\u51fa\u5024\u306e\u30ad\u30e3\u30c3\u30b7\u30e5\n  def cached_comments_count\n    Rails.cache.fetch([self, 'comments_count']) do\n      comments.count\n    end\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-31\">4. \u30d5\u30e9\u30b0\u30e1\u30f3\u30c8\u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u6700\u9069\u5316<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30d3\u30e5\u30fc\u3067\u306e\u30ad\u30e3\u30c3\u30b7\u30e5\n&lt;% cache_if @post.cacheable?, @post do %&gt;\n  &lt;article class=\"post\"&gt;\n    &lt;%= render @post.content %&gt;\n\n    &lt;% cache @post.comments do %&gt;\n      &lt;%= render @post.comments %&gt;\n    &lt;% end %&gt;\n  &lt;\/article&gt;\n&lt;% end %&gt;\n\n# \u30ed\u30b7\u30a2\u30f3\u30c9\u30fc\u30eb\u30ad\u30e3\u30c3\u30b7\u30e5\n&lt;% cache ['v1', @post] do %&gt;\n  &lt;%= render @post %&gt;\n  &lt;% cache ['v1', @post, :comments] do %&gt;\n    &lt;%= render @post.comments %&gt;\n  &lt;% end %&gt;\n&lt;% end %&gt;<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-32\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u76e3\u8996\u3068\u30c1\u30e5\u30fc\u30cb\u30f3\u30b0\u306e\u30dd\u30a4\u30f3\u30c8<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30af\u30a8\u30ea\u30ed\u30b0\u306e\u76e3\u8996<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># development.rb\u3067\u306e\u8a2d\u5b9a\nconfig.after_initialize do\n  Bullet.enable = true\n  Bullet.alert = true\n  Bullet.rails_logger = true\nend<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u8a08\u6e2c<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u5b9f\u884c\u6642\u9593\u306e\u8a08\u6e2c\nActiveSupport::Notifications.subscribe('sql.active_record') do |*args|\n  event = ActiveSupport::Notifications::Event.new(*args)\n  if event.duration &gt; 100\n    Rails.logger.warn(\"Slow query detected: #{event.payload[:sql]}\")\n  end\nend<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u3053\u308c\u3089\u306e\u6700\u9069\u5316\u30c6\u30af\u30cb\u30c3\u30af\u3092\u9069\u5207\u306b\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3092\u5927\u304d\u304f\u6539\u5584\u3067\u304d\u307e\u3059\u3002\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u306b\u5f71\u97ff\u3092\u4e0e\u3048\u308b\u53ef\u80fd\u6027\u306e\u3042\u308b\u30a2\u30f3\u30c1\u30d1\u30bf\u30fc\u30f3\u306b\u3064\u3044\u3066\u8aac\u660e\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"i-33\">ActiveRecord\u306e\u30a2\u30f3\u30c1\u30d1\u30bf\u30fc\u30f3\u3068\u5bfe\u51e6\u6cd5<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-34\">\u30e1\u30e2\u30ea\u4f7f\u7528\u91cf\u304c\u5897\u5927\u3059\u308b\u5371\u967a\u306a\u5b9f\u88c5\u30d1\u30bf\u30fc\u30f3<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-35\">1. \u5927\u91cf\u306e\u30ec\u30b3\u30fc\u30c9\u306e\u4e00\u62ec\u8aad\u307f\u8fbc\u307f<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u5371\u967a\u306a\u30d1\u30bf\u30fc\u30f3\nall_users = User.all.to_a  # \u5168\u30ec\u30b3\u30fc\u30c9\u3092\u30e1\u30e2\u30ea\u306b\u5c55\u958b\n\n# \u63a8\u5968\u3055\u308c\u308b\u5b9f\u88c5\nUser.find_each do |user|\n  # \u4e00\u5b9a\u6570\u305a\u3064\u51e6\u7406\nend\n\n# \u30d0\u30c3\u30c1\u30b5\u30a4\u30ba\u306e\u6307\u5b9a\nUser.find_each(batch_size: 100) do |user|\n  # \u51e6\u7406\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-36\">2. \u4e0d\u5fc5\u8981\u306a\u30ab\u30e9\u30e0\u306e\u8aad\u307f\u8fbc\u307f<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30e1\u30e2\u30ea\u3092\u7121\u99c4\u306b\u4f7f\u7528\nusers = User.all.select(:id, :name, :email, :created_at, :updated_at)\n\n# \u5fc5\u8981\u306a\u30ab\u30e9\u30e0\u306e\u307f\u6307\u5b9a\nusers = User.select(:id, :name)  # \u5fc5\u8981\u6700\u5c0f\u9650\u306e\u30ab\u30e9\u30e0\n\n# \u7279\u5b9a\u306e\u30ab\u30e9\u30e0\u3092\u9664\u5916\nusers = User.select(User.attribute_names - ['huge_data_column'])<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-37\">3. \u5de8\u5927\u306a\u914d\u5217\u306e\u751f\u6210<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30e1\u30e2\u30ea\u4f7f\u7528\u91cf\u304c\u5897\u5927\u3059\u308b\u5b9f\u88c5\ndef self.all_user_names\n  pluck(:name)  # \u5168\u30e6\u30fc\u30b6\u30fc\u540d\u3092\u914d\u5217\u3068\u3057\u3066\u4fdd\u6301\n\n# \u30e1\u30e2\u30ea\u52b9\u7387\u306e\u826f\u3044\u5b9f\u88c5\ndef self.process_user_names\n  pluck(:name).find_each do |name|\n    yield name\n  end\nend<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-38\">\u30c7\u30c3\u30c9\u30ed\u30c3\u30af\u3092\u5f15\u304d\u8d77\u3053\u3059\u5178\u578b\u7684\u306a\u30df\u30b9<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-39\">1. \u4e0d\u9069\u5207\u306a\u30ed\u30c3\u30af\u9806\u5e8f<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30c7\u30c3\u30c9\u30ed\u30c3\u30af\u306e\u5371\u967a\u304c\u3042\u308b\u30b3\u30fc\u30c9\ndef transfer_money(from_account, to_account, amount)\n  from_account.with_lock do\n    to_account.with_lock do\n      # \u51e6\u7406\n    end\n  end\nend\n\n# \u6539\u5584\u3055\u308c\u305f\u5b9f\u88c5\uff08ID\u3067\u30ed\u30c3\u30af\u9806\u5e8f\u3092\u56fa\u5b9a\uff09\ndef transfer_money(from_account, to_account, amount)\n  first, second = [from_account, to_account].sort_by(&amp;:id)\n  first.with_lock do\n    second.with_lock do\n      # \u51e6\u7406\n    end\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-40\">2. \u9577\u6642\u9593\u306e\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u554f\u984c\u306e\u3042\u308b\u5b9f\u88c5\ndef process_large_data\n  Transaction.transaction do\n    huge_data.each do |data|\n      # \u6642\u9593\u306e\u304b\u304b\u308b\u51e6\u7406\n    end\n  end\nend\n\n# \u6539\u5584\u3055\u308c\u305f\u5b9f\u88c5\ndef process_large_data\n  huge_data.each_slice(100) do |batch|\n    Transaction.transaction do\n      batch.each do |data|\n        # \u51e6\u7406\n      end\n    end\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-41\">3. \u4e0d\u9069\u5207\u306a\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u8a2d\u8a08<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30c7\u30c3\u30c9\u30ed\u30c3\u30af\u3092\u8a98\u767a\u3059\u308b\u53ef\u80fd\u6027\u304c\u3042\u308b\u66f4\u65b0\nclass AddIndexWithoutLockStrategy &lt; ActiveRecord::Migration[7.0]\n  def change\n    add_index :large_table, :column_name  # \u30c6\u30fc\u30d6\u30eb\u30ed\u30c3\u30af\u304c\u767a\u751f\n\n    # \u4ee3\u308f\u308a\u306b\n    add_index :large_table, :column_name, algorithm: :concurrently\n  end\nend<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-42\">\u30a2\u30f3\u30c1\u30d1\u30bf\u30fc\u30f3\u3092\u56de\u907f\u3059\u308b\u305f\u3081\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30e1\u30e2\u30ea\u4f7f\u7528\u91cf\u306e\u6700\u9069\u5316<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5fc5\u8981\u306a\u30ab\u30e9\u30e0\u306e\u307f\u3092\u9078\u629e<\/li>\n\n\n\n<li>\u30d0\u30c3\u30c1\u51e6\u7406\u306e\u6d3b\u7528<\/li>\n\n\n\n<li>\u30b9\u30c8\u30ea\u30fc\u30df\u30f3\u30b0\u51e6\u7406\u306e\u5229\u7528<\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30b9\u30c8\u30ea\u30fc\u30df\u30f3\u30b0\u51e6\u7406\u306e\u4f8b\nrequire 'csv'\n\nCSV.open('users.csv', 'w') do |csv|\n  User.select(:id, :name).find_each do |user|\n    csv &lt;&lt; [user.id, user.name]\n  end\nend<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30c7\u30c3\u30c9\u30ed\u30c3\u30af\u5bfe\u7b56<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306e\u7bc4\u56f2\u3092\u6700\u5c0f\u9650\u306b<\/li>\n\n\n\n<li>\u30ed\u30c3\u30af\u9806\u5e8f\u306e\u4e00\u8cab\u6027\u7dad\u6301<\/li>\n\n\n\n<li>\u9069\u5207\u306a\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8\u8a2d\u5b9a<\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30bf\u30a4\u30e0\u30a2\u30a6\u30c8\u8a2d\u5b9a\u306e\u4f8b\nconfig.active_record.lock_timeout = 5.seconds\nconfig.active_record.statement_timeout = 10.seconds<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u30e2\u30cb\u30bf\u30ea\u30f3\u30b0<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30af\u30a8\u30ea\u5b9f\u884c\u6642\u9593\u306e\u76e3\u8996\nActiveSupport::Notifications.subscribe('sql.active_record') do |*args|\n  event = ActiveSupport::Notifications::Event.new(*args)\n  if event.duration &gt; 100\n    Rails.logger.warn(\"Slow query detected: #{event.payload[:sql]}\")\n    Rails.logger.warn(\"Duration: #{event.duration}ms\")\n  end\nend<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u3053\u308c\u3089\u306e\u30a2\u30f3\u30c1\u30d1\u30bf\u30fc\u30f3\u3092\u7406\u89e3\u3057\u3001\u9069\u5207\u306a\u5bfe\u51e6\u6cd5\u3092\u5b9f\u88c5\u3059\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u5b89\u5b9a\u3057\u305f\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u904b\u7528\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\u3002\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u3055\u3089\u306b\u9ad8\u5ea6\u306aActiveRecord\u306e\u30c6\u30af\u30cb\u30c3\u30af\u306b\u3064\u3044\u3066\u8aac\u660e\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"i-43\">\u5b9f\u52d9\u3067\u4f7f\u3048\u308b\u9ad8\u5ea6\u306aActiveRecord\u30c6\u30af\u30cb\u30c3\u30af<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-44\">\u30dd\u30ea\u30e2\u30fc\u30d5\u30a3\u30c3\u30af\u95a2\u9023\u4ed8\u3051\u306e\u6d3b\u7528\u30b7\u30fc\u30f3<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-45\">1. \u901a\u77e5\u30b7\u30b9\u30c6\u30e0\u306e\u5b9f\u88c5<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># app\/models\/notification.rb\nclass Notification &lt; ApplicationRecord\n  belongs_to :notifiable, polymorphic: true\n  belongs_to :recipient, class_name: 'User'\n\n  scope :unread, -&gt; { where(read_at: nil) }\n  scope :recent, -&gt; { order(created_at: :desc) }\nend\n\n# app\/models\/comment.rb\nclass Comment &lt; ApplicationRecord\n  has_many :notifications, as: :notifiable, dependent: :destroy\n\n  after_create :create_notification\n\n  private\n\n  def create_notification\n    Notification.create(\n      notifiable: self,\n      recipient: post.user,\n      action: 'commented',\n      message: \"#{user.name}\u304c\u3042\u306a\u305f\u306e\u6295\u7a3f\u306b\u30b3\u30e1\u30f3\u30c8\u3057\u307e\u3057\u305f\"\n    )\n  end\nend\n\n# app\/models\/like.rb\nclass Like &lt; ApplicationRecord\n  has_many :notifications, as: :notifiable, dependent: :destroy\n\n  after_create :create_notification\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-46\">2. \u6dfb\u4ed8\u30d5\u30a1\u30a4\u30eb\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># app\/models\/attachment.rb\nclass Attachment &lt; ApplicationRecord\n  belongs_to :attachable, polymorphic: true\n\n  has_one_attached :file\n\n  validates :file, presence: true\n  validates :file, content_type: { \n    in: %w[image\/jpeg image\/png application\/pdf],\n    message: '\u8a31\u53ef\u3055\u308c\u3066\u3044\u306a\u3044\u30d5\u30a1\u30a4\u30eb\u5f62\u5f0f\u3067\u3059'\n  }\nend\n\n# \u4f7f\u7528\u4f8b\nclass Report &lt; ApplicationRecord\n  has_many :attachments, as: :attachable, dependent: :destroy\n  accepts_nested_attributes_for :attachments, allow_destroy: true\nend<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-47\">\u30b5\u30fc\u30d3\u30b9\u30af\u30e9\u30b9\u3068\u306e\u52b9\u679c\u7684\u306a\u4f75\u7528\u65b9\u6cd5<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-48\">1. \u8907\u96d1\u306a\u696d\u52d9\u30ed\u30b8\u30c3\u30af\u306e\u5206\u96e2<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># app\/services\/order_processor.rb\nclass OrderProcessor\n  def initialize(order)\n    @order = order\n  end\n\n  def process\n    ApplicationRecord.transaction do\n      update_inventory\n      process_payment\n      send_notifications\n    end\n  rescue =&gt; e\n    handle_error(e)\n    false\n  end\n\n  private\n\n  def update_inventory\n    @order.order_items.each do |item|\n      item.product.with_lock do\n        raise InsufficientStock unless item.product.sufficient_stock?(item.quantity)\n        item.product.decrease_stock(item.quantity)\n      end\n    end\n  end\n\n  def process_payment\n    payment = Payment.create!(\n      order: @order,\n      amount: @order.total_amount\n    )\n    PaymentGateway.new(payment).process\n  end\nend\n\n# \u4f7f\u7528\u4f8b\nclass OrdersController &lt; ApplicationController\n  def create\n    @order = Order.new(order_params)\n\n    if OrderProcessor.new(@order).process\n      redirect_to @order, notice: '\u6ce8\u6587\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f'\n    else\n      render :new\n    end\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-49\">2. \u30d5\u30a9\u30fc\u30e0\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u306e\u9023\u643a<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># app\/forms\/user_registration_form.rb\nclass UserRegistrationForm\n  include ActiveModel::Model\n\n  attr_accessor :email, :password, :terms_accepted\n\n  validates :email, presence: true, format: { with: URI::MailTo::EMAIL_REGEXP }\n  validates :password, length: { minimum: 8 }\n  validates :terms_accepted, acceptance: true\n\n  def save\n    return false unless valid?\n\n    User.transaction do\n      user = User.create!(\n        email: email,\n        password: password\n      )\n      Profile.create!(user: user)\n      UserMailer.welcome(user).deliver_later\n    end\n  rescue ActiveRecord::RecordInvalid\n    false\n  end\nend<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-50\">\u30c6\u30b9\u30c8\u99c6\u52d5\u958b\u767a\u306b\u304a\u3051\u308bActiveRecord\u306e\u6271\u3044\u65b9<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-51\">1. \u30d5\u30a1\u30af\u30c8\u30ea\u3092\u6d3b\u7528\u3057\u305f\u30c6\u30b9\u30c8<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># spec\/factories\/users.rb\nFactoryBot.define do\n  factory :user do\n    sequence(:email) { |n| \"user#{n}@example.com\" }\n    password { \"password123\" }\n\n    # \u95a2\u9023\u4ed8\u3051\u3092\u6301\u3064\u30d5\u30a1\u30af\u30c8\u30ea\n    factory :user_with_posts do\n      transient do\n        posts_count { 5 }\n      end\n\n      after(:create) do |user, evaluator|\n        create_list(:post, evaluator.posts_count, user: user)\n      end\n    end\n  end\nend\n\n# spec\/models\/user_spec.rb\nRSpec.describe User, type: :model do\n  describe '#active_posts' do\n    let(:user) { create(:user_with_posts) }\n\n    before do\n      user.posts.first.update(status: 'archived')\n    end\n\n    it 'returns only active posts' do\n      expect(user.active_posts.count).to eq 4\n    end\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-52\">2. \u30e2\u30c3\u30af\u3068\u30b9\u30bf\u30d6\u306e\u9069\u5207\u306a\u4f7f\u7528<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">RSpec.describe OrderProcessor do\n  let(:order) { create(:order) }\n  let(:processor) { OrderProcessor.new(order) }\n\n  describe '#process' do\n    before do\n      allow(PaymentGateway).to receive(:new)\n        .and_return(double(process: true))\n    end\n\n    it 'processes the order successfully' do\n      expect(processor.process).to be true\n    end\n\n    context 'when stock is insufficient' do\n      before do\n        allow_any_instance_of(Product)\n          .to receive(:sufficient_stock?)\n          .and_return(false)\n      end\n\n      it 'fails to process the order' do\n        expect(processor.process).to be false\n      end\n    end\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-53\">3. SharedExamples\u306e\u6d3b\u7528<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">RSpec.shared_examples 'softly deletable' do\n  let(:model) { described_class }\n\n  it 'can be soft deleted' do\n    instance = create(model.to_s.underscore)\n    expect {\n      instance.soft_delete\n    }.to change { instance.deleted_at }.from(nil)\n  end\n\n  it 'scopes active records' do\n    active = create(model.to_s.underscore)\n    deleted = create(model.to_s.underscore, deleted_at: Time.current)\n\n    expect(model.active).to include(active)\n    expect(model.active).not_to include(deleted)\n  end\nend\n\nRSpec.describe Post do\n  it_behaves_like 'softly deletable'\nend<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u3053\u308c\u3089\u306e\u9ad8\u5ea6\u306a\u30c6\u30af\u30cb\u30c3\u30af\u3092\u9069\u5207\u306b\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3001\u4fdd\u5b88\u6027\u304c\u9ad8\u304f\u3001\u30c6\u30b9\u30c8\u53ef\u80fd\u306a\u5b9f\u88c5\u3092\u5b9f\u73fe\u3067\u304d\u307e\u3059\u3002\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001ActiveRecord\u306e\u30e2\u30cb\u30bf\u30ea\u30f3\u30b0\u3068\u30c7\u30d0\u30c3\u30b0\u624b\u6cd5\u306b\u3064\u3044\u3066\u8aac\u660e\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"i-54\">ActiveRecord\u306e\u30e2\u30cb\u30bf\u30ea\u30f3\u30b0\u3068\u30c7\u30d0\u30c3\u30b0\u624b\u6cd5<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-55\">\u30b9\u30ed\u30fc\u30af\u30a8\u30ea\u3092\u7279\u5b9a\u3057\u3066\u6539\u5584\u3059\u308b\u624b\u9806<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-56\">1. \u30ed\u30b0\u306e\u8a2d\u5b9a\u3068\u89e3\u6790<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># config\/environments\/production.rb\nconfig.active_record.verbose_query_logs = true\nconfig.logger = ActiveSupport::Logger.new(\"log\/production.log\")\n\n# \u30b9\u30ed\u30fc\u30af\u30a8\u30ea\u306e\u30ed\u30b0\u8a2d\u5b9a\nActiveRecord::Base.logger = ActiveSupport::TaggedLogging.new(\n  ActiveSupport::Logger.new(\"log\/slow_queries.log\")\n)\n\n# \u30af\u30a8\u30ea\u5b9f\u884c\u6642\u9593\u306e\u76e3\u8996\nActiveSupport::Notifications.subscribe('sql.active_record') do |*args|\n  event = ActiveSupport::Notifications::Event.new(*args)\n  if event.duration &gt; 1000  # 1\u79d2\u4ee5\u4e0a\u304b\u304b\u308b\u30af\u30a8\u30ea\n    Rails.logger.warn(&lt;&lt;~SQL)\n      Slow Query Detected:\n      Duration: #{event.duration}ms\n      SQL: #{event.payload[:sql]}\n      Location: #{event.payload[:name]}\n    SQL\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-57\">2. \u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u5206\u6790\u30c4\u30fc\u30eb\u306e\u6d3b\u7528<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Gemfile\ngroup :development do\n  gem 'rack-mini-profiler'\n  gem 'bullet'\n  gem 'rails-erd'  # ER\u30c0\u30a4\u30a2\u30b0\u30e9\u30e0\u751f\u6210\nend\n\n# config\/environments\/development.rb\nconfig.after_initialize do\n  Bullet.enable = true\n  Bullet.alert = true\n  Bullet.rails_logger = true\n  Bullet.add_footer = true\n\n  Bullet.unused_eager_loading_enable = false\nend<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-58\">\u672c\u756a\u74b0\u5883\u3067\u306e\u5b89\u5168\u306a\u30c7\u30d0\u30c3\u30b0\u65b9\u6cd5<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-59\">1. \u5b89\u5168\u306a\u30c7\u30d0\u30c3\u30b0\u60c5\u5831\u306e\u53ce\u96c6<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># app\/controllers\/application_controller.rb\nclass ApplicationController &lt; ActionController::Base\n  around_action :catch_and_log_exceptions\n\n  private\n\n  def catch_and_log_exceptions\n    yield\n  rescue =&gt; error\n    ErrorLogger.log(\n      error: error,\n      controller: controller_name,\n      action: action_name,\n      params: filtered_params,\n      user: current_user&amp;.id\n    )\n    raise\n  end\n\n  def filtered_params\n    params.except('controller', 'action').to_unsafe_h\n  end\nend\n\n# lib\/error_logger.rb\nclass ErrorLogger\n  def self.log(error:, **context)\n    Rails.logger.error(&lt;&lt;~ERROR)\n      Exception: #{error.class}\n      Message: #{error.message}\n      Context: #{context}\n      Backtrace:\n      #{error.backtrace&amp;.first(10)&amp;.join(\"\\n\")}\n    ERROR\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-60\">2. \u30c7\u30d0\u30c3\u30b0\u30e2\u30fc\u30c9\u306e\u5b9f\u88c5<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># config\/initializers\/debug_mode.rb\nmodule DebugMode\n  mattr_accessor :enabled\n\n  def self.enable!\n    self.enabled = true\n    ActiveRecord::Base.logger = Logger.new(STDOUT)\n  end\n\n  def self.disable!\n    self.enabled = false\n    ActiveRecord::Base.logger = Rails.logger\n  end\nend\n\n# \u4f7f\u7528\u4f8b\nclass ComplexQuery\n  def execute\n    if DebugMode.enabled\n      log_query_execution do\n        perform_query\n      end\n    else\n      perform_query\n    end\n  end\n\n  private\n\n  def log_query_execution\n    start_time = Time.current\n    result = yield\n    duration = Time.current - start_time\n\n    Rails.logger.info(&lt;&lt;~DEBUG)\n      Query Execution:\n      Duration: #{duration}s\n      Result Count: #{result.size}\n    DEBUG\n\n    result\n  end\nend<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-61\">\u30e2\u30cb\u30bf\u30ea\u30f3\u30b0\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-62\">1. \u30e1\u30c8\u30ea\u30af\u30b9\u306e\u53ce\u96c6<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># config\/initializers\/metrics.rb\nmodule ActiveRecordMetrics\n  def self.included(base)\n    base.extend(ClassMethods)\n\n    base.class_eval do\n      after_create :track_creation\n      after_update :track_update\n      after_destroy :track_deletion\n    end\n  end\n\n  module ClassMethods\n    def track_metrics!\n      include ActiveRecordMetrics\n    end\n  end\n\n  private\n\n  def track_creation\n    StatsD.increment(\"#{self.class.name.underscore}.created\")\n  end\n\n  def track_update\n    StatsD.increment(\"#{self.class.name.underscore}.updated\")\n  end\n\n  def track_deletion\n    StatsD.increment(\"#{self.class.name.underscore}.deleted\")\n  end\nend\n\n# \u30e2\u30c7\u30eb\u3067\u306e\u4f7f\u7528\nclass User &lt; ApplicationRecord\n  track_metrics!\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-63\">2. \u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u30e2\u30cb\u30bf\u30ea\u30f3\u30b0<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">module QueryMonitoring\n  def self.included(base)\n    base.extend(ClassMethods)\n  end\n\n  module ClassMethods\n    def monitor_queries!\n      around_query do |*, &amp;block|\n        start_time = Time.current\n        result = block.call\n        duration = Time.current - start_time\n\n        if duration &gt; threshold\n          alert_slow_query(duration)\n        end\n\n        result\n      end\n    end\n\n    private\n\n    def threshold\n      ENV.fetch('QUERY_THRESHOLD', 1.0).to_f\n    end\n\n    def alert_slow_query(duration)\n      SlackNotifier.notify(\n        channel: '#performance',\n        text: \"Slow query detected (#{duration}s)\"\n      )\n    end\n  end\nend<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u3053\u308c\u3089\u306e\u30e2\u30cb\u30bf\u30ea\u30f3\u30b0\u3068\u30c7\u30d0\u30c3\u30b0\u624b\u6cd5\u3092\u9069\u5207\u306b\u5b9f\u88c5\u3059\u308b\u3053\u3068\u3067\u3001\u554f\u984c\u306e\u65e9\u671f\u767a\u898b\u3068\u8fc5\u901f\u306a\u5bfe\u5fdc\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\u3002\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u3053\u308c\u307e\u3067\u306e\u5185\u5bb9\u3092\u8e0f\u307e\u3048\u305f\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\u306b\u3064\u3044\u3066\u307e\u3068\u3081\u307e\u3059\u3002<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"i-64\">ActiveRecord\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\u307e\u3068\u3081<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-65\">\u73fe\u5834\u3067\u4f7f\u3048\u308b7\u3064\u306e\u91cd\u8981\u306a\u8a2d\u8a08\u6307\u91dd<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-66\">1. \u30e2\u30c7\u30eb\u8a2d\u8a08\u306e\u539f\u5247<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u5358\u4e00\u8cac\u4efb\u306e\u539f\u5247\u3092\u5b88\u308b<\/strong><\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u60aa\u3044\u4f8b\uff1a\u30e2\u30c7\u30eb\u306b\u591a\u3059\u304e\u308b\u8cac\u4efb\u304c\u3042\u308b\nclass User &lt; ApplicationRecord\n  # \u8a8d\u8a3c\u3001\u30d7\u30ed\u30d5\u30a3\u30fc\u30eb\u3001\u6c7a\u6e08\u306a\u3069\u591a\u304f\u306e\u8cac\u4efb\u3092\u6301\u3064\nend\n\n# \u826f\u3044\u4f8b\uff1a\u8cac\u4efb\u3092\u9069\u5207\u306b\u5206\u5272\nclass User &lt; ApplicationRecord\n  has_one :profile\n  has_one :payment_setting\n\n  # \u8a8d\u8a3c\u95a2\u9023\u306e\u51e6\u7406\n  include Authenticatable\n\n  # \u30d7\u30ed\u30d5\u30a3\u30fc\u30eb\u95a2\u9023\u306e\u51e6\u7406\n  delegate :full_name, :avatar_url, to: :profile\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-67\">2. \u30af\u30a8\u30ea\u306e\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u5fc5\u8981\u6700\u5c0f\u9650\u306e\u30c7\u30fc\u30bf\u3060\u3051\u3092\u53d6\u5f97\u3059\u308b<\/strong><\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u57fa\u672c\u7684\u306a\u30b9\u30b3\u30fc\u30d7\u306e\u5b9a\u7fa9\nclass Article &lt; ApplicationRecord\n  scope :published_with_author, -&gt; {\n    select('articles.id, articles.title, users.name as author_name')\n    .joins(:user)\n    .where(published: true)\n  }\n\n  # \u30ab\u30b9\u30bf\u30e0\u30b9\u30b3\u30fc\u30d7\u30d3\u30eb\u30c0\u30fc\n  scope :with_required_columns, -&gt;(columns) {\n    select(Array(columns))\n  }\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-68\">3. \u30d0\u30c3\u30c1\u51e6\u7406\u3068\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u30e1\u30e2\u30ea\u4f7f\u7528\u91cf\u3092\u8003\u616e\u3057\u305f\u5b9f\u88c5<\/strong><\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class BatchProcessor\n  def self.process_users\n    User.find_each(batch_size: 100) do |user|\n      UserStatisticsCalculator.new(user).calculate\n    rescue =&gt; e\n      Rails.logger.error(\"Failed to process user #{user.id}: #{e.message}\")\n      next\n    end\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-69\">4. \u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u7ba1\u7406<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u9069\u5207\u306a\u7c92\u5ea6\u3067\u306e\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u5236\u5fa1<\/strong><\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class OrderProcessor\n  def process(order)\n    Order.transaction(requires_new: true) do\n      begin\n        update_inventory(order)\n        process_payment(order)\n        send_confirmation(order)\n      rescue =&gt; e\n        handle_error(e)\n        raise ActiveRecord::Rollback\n      end\n    end\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-70\">5. \u30c6\u30b9\u30bf\u30d3\u30ea\u30c6\u30a3\u306e\u78ba\u4fdd<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u30c6\u30b9\u30c8\u5bb9\u6613\u6027\u3092\u8003\u616e\u3057\u305f\u8a2d\u8a08<\/strong><\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class Article &lt; ApplicationRecord\n  # \u30c6\u30b9\u30c8\u53ef\u80fd\u306a\u7bc4\u56f2\u3067\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\n  validates :title, presence: true, length: { maximum: 100 }\n  validates :content, presence: true\n\n  # \u30c6\u30b9\u30c8\u53ef\u80fd\u306a\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\n  validate :publication_date_cannot_be_in_past\n\n  private\n\n  def publication_date_cannot_be_in_past\n    return unless publication_date.present?\n\n    if publication_date &lt; Time.current\n      errors.add(:publication_date, \"can't be in the past\")\n    end\n  end\nend<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-71\">\u4eca\u3059\u3050\u59cb\u3081\u3089\u308c\u308b\u6539\u5584\u30a2\u30af\u30b7\u30e7\u30f3<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-72\">1. \u30b3\u30fc\u30c9\u30ec\u30d3\u30e5\u30fc\u30c1\u30a7\u30c3\u30af\u30ea\u30b9\u30c8<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30e2\u30c7\u30eb\u306e\u30c1\u30a7\u30c3\u30af\u30dd\u30a4\u30f3\u30c8\nclass ModelReviewer\n  def self.check_points\n    {\n      validation: '\u9069\u5207\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u308b\u304b',\n      scope: '\u30b9\u30b3\u30fc\u30d7\u306f\u9069\u5207\u306b\u540d\u524d\u4ed8\u3051\u3055\u308c\u3001\u52b9\u7387\u7684\u304b',\n      callback: '\u30b3\u30fc\u30eb\u30d0\u30c3\u30af\u306e\u526f\u4f5c\u7528\u306f\u8003\u616e\u3055\u308c\u3066\u3044\u308b\u304b',\n      relation: '\u95a2\u9023\u4ed8\u3051\u306f\u9069\u5207\u306b\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u308b\u304b',\n      index: '\u5fc5\u8981\u306a\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306f\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u308b\u304b'\n    }\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-73\">2. \u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6539\u5584\u30b9\u30c6\u30c3\u30d7<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>N+1\u30af\u30a8\u30ea\u306e\u691c\u51fa\u3068\u6539\u5584<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Bulletgem\u306e\u5c0e\u5165<\/li>\n\n\n\n<li>includes\/preload\u306e\u9069\u5207\u306a\u4f7f\u7528<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u6700\u9069\u5316<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u983b\u7e41\u306b\u4f7f\u7528\u3055\u308c\u308b\u30af\u30a8\u30ea\u306e\u5206\u6790<\/li>\n\n\n\n<li>\u8907\u5408\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306e\u691c\u8a0e<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30ad\u30e3\u30c3\u30b7\u30e5\u6226\u7565\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30e2\u30c7\u30eb\u30ec\u30d9\u30eb\u306e\u30ad\u30e3\u30c3\u30b7\u30e5<\/li>\n\n\n\n<li>\u30af\u30a8\u30ea\u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u6d3b\u7528<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-74\">3. \u7d99\u7d9a\u7684\u306a\u6539\u5584\u306e\u305f\u3081\u306e\u30a2\u30af\u30b7\u30e7\u30f3<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30b3\u30fc\u30c9\u30ec\u30d3\u30e5\u30fc\u3067\u306e\u6ce8\u610f\u70b9\u30c1\u30a7\u30c3\u30af<\/li>\n\n\n\n<li>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u30e2\u30cb\u30bf\u30ea\u30f3\u30b0\u306e\u7fd2\u6163\u5316<\/li>\n\n\n\n<li>\u5b9a\u671f\u7684\u306a\u30af\u30a8\u30ea\u30ed\u30b0\u306e\u5206\u6790<\/li>\n\n\n\n<li>\u30c1\u30fc\u30e0\u5185\u3067\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\u5171\u6709<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u3053\u308c\u3089\u306e\u6307\u91dd\u3068\u30a2\u30af\u30b7\u30e7\u30f3\u3092\u5b9f\u8df5\u3059\u308b\u3053\u3068\u3067\u3001\u30e1\u30f3\u30c6\u30ca\u30f3\u30b9\u6027\u304c\u9ad8\u304f\u3001\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u306e\u826f\u3044Rails\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u69cb\u7bc9\u30fb\u904b\u7528\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u5b9a\u671f\u7684\u306b\u3053\u308c\u3089\u306e\u70b9\u3092\u30ec\u30d3\u30e5\u30fc\u3057\u3001\u5fc5\u8981\u306b\u5fdc\u3058\u3066\u6539\u5584\u3092\u91cd\u306d\u3066\u3044\u304f\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>ActiveRecord\u3068\u306f\uff1f\u73fe\u5834\u3067\u5fc5\u8981\u306a\u57fa\u790e\u77e5\u8b58 ActiveRecord\u306f\u3001Ruby on Rails\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u64cd\u4f5c\u3092\u62c5\u3046\u91cd\u8981\u306a\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3067\u3059\u3002\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u6307\u5411\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u3068\u30ea\u30ec\u30fc\u30b7\u30e7\u30ca\u30eb\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u6a4b\u6e21 &#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-1349","post","type-post","status-publish","format-standard","category-ruby","nothumb"],"_links":{"self":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/1349","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1349"}],"version-history":[{"count":1,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/1349\/revisions"}],"predecessor-version":[{"id":1350,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/1349\/revisions\/1350"}],"wp:attachment":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1349"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1349"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1349"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}