{"id":140,"date":"2024-09-11T16:15:34","date_gmt":"2024-09-11T07:15:34","guid":{"rendered":"https:\/\/dexall.co.jp\/articles\/?p=140"},"modified":"2025-03-24T08:55:00","modified_gmt":"2025-03-23T23:55:00","slug":"%e3%80%90%e4%bf%9d%e5%ad%98%e7%89%88%e3%80%91ruby-on-rails-validate%e3%81%ae%e5%ae%8c%e5%85%a8%e3%82%ac%e3%82%a4%e3%83%89%ef%bc%9a%e5%9f%ba%e7%a4%8e%e3%81%8b%e3%82%89%e5%bf%9c%e7%94%a8%e3%81%be","status":"publish","type":"post","link":"https:\/\/dexall.co.jp\/articles\/?p=140","title":{"rendered":"\u3010\u4fdd\u5b58\u7248\u3011Ruby on Rails validate\u306e\u5b8c\u5168\u30ac\u30a4\u30c9\uff1a\u57fa\u790e\u304b\u3089\u5fdc\u7528\u307e\u3067\u89e3\u8aac\u3059\u308b7\u3064\u306e\u30c6\u30af\u30cb\u30c3\u30af"},"content":{"rendered":"\n<p>Ruby on Rails\u306evalidate\u306f\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30c7\u30fc\u30bf\u6574\u5408\u6027\u3092\u4fdd\u3061\u3001\u30e6\u30fc\u30b6\u30fc\u4f53\u9a13\u3092\u5411\u4e0a\u3055\u305b\u308b\u91cd\u8981\u306a\u6a5f\u80fd\u3067\u3059\u3002<br>\u672c\u8a18\u4e8b\u3067\u306f\u3001\u57fa\u790e\u304b\u3089\u5fdc\u7528\u307e\u3067\u3001validate\u306e\u52b9\u679c\u7684\u306a\u6d3b\u7528\u6cd5\u30927\u3064\u306e\u30c6\u30af\u30cb\u30c3\u30af\u3092\u901a\u3058\u3066\u89e3\u8aac\u3057\u307e\u3059\u3002<br>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3068\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u306b\u3082\u914d\u616e\u3057\u305f\u5b9f\u8df5\u7684\u306a\u30a2\u30d7\u30ed\u30fc\u30c1\u3067\u3001\u3042\u306a\u305f\u306eRails\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u54c1\u8cea\u3092\u4e00\u6bb5\u968e\u4e0a\u3052\u307e\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<div class=\"wp-block-sgb-block-simple sgb-box-simple sgb-box-simple--title-normal sgb-box-simple--with-border\"><div style=\"background-color:var(--wp--preset--color--sango-main);color:#FFF\" class=\"sgb-box-simple__title\">\u3053\u306e\u8a18\u4e8b\u3092\u901a\u3057\u3066\u7406\u89e3\u3067\u304d\u308b8\u3064\u306e\u3053\u3068<\/div><div class=\"sgb-box-simple__body\" style=\"border-color:var(--wp--preset--color--sango-main);background-color:#FFF\">\n<ul class=\"wp-block-list\">\n<li>validate\u306e\u57fa\u672c\u7684\u306a\u4f7f\u3044\u65b9\u3068\u91cd\u8981\u6027<\/li>\n\n\n\n<li>\u4e3b\u8981\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30d8\u30eb\u30d1\u30fc\u306e\u6d3b\u7528\u6cd5<\/li>\n\n\n\n<li>\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5\u30c6\u30af\u30cb\u30c3\u30af<\/li>\n\n\n\n<li>\u6761\u4ef6\u4ed8\u304d\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306b\u3088\u308b\u67d4\u8edf\u306a\u5236\u5fa1\u65b9\u6cd5<\/li>\n\n\n\n<li>\u30a2\u30bd\u30b7\u30a8\u30fc\u30b7\u30e7\u30f3\u3092\u8003\u616e\u3057\u305f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5<\/li>\n\n\n\n<li>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3092\u8003\u616e\u3057\u305f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u6700\u9069\u5316\u624b\u6cd5<\/li>\n\n\n\n<li>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3092\u5f37\u5316\u3059\u308b\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30c6\u30af\u30cb\u30c3\u30af<\/li>\n\n\n\n<li>\u52b9\u679c\u7684\u306avalidate\u306e\u6d3b\u7528\u306b\u3088\u308b\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u54c1\u8cea\u5411\u4e0a\u306e\u65b9\u6cd5<\/li>\n<\/ul>\n<\/div><\/div>\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\">Ruby on Rails\u306evalidate\u3068\u306f\uff1f\u57fa\u672c\u7684\u306a\u4f7f\u3044\u65b9\u3092\u89e3\u8aac<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-1\">\u30e2\u30c7\u30eb\u306e\u6574\u5408\u6027\u3092\u4fdd\u3064validate\u306e\u91cd\u8981\u6027<\/a>      <\/li>      <li>        <a href=\"#i-2\">validate\u30e1\u30bd\u30c3\u30c9\u306e\u57fa\u672c\u7684\u306a\u69cb\u6587\u3068\u4f7f\u7528\u4f8b<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-3\">validate\u3092\u4f7f\u3046\u969b\u306e\u6ce8\u610f\u70b9\u3068\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-4\">validate\u3067\u4f7f\u3048\u308b\u4e3b\u8981\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30d8\u30eb\u30d1\u30fc\u3068\u305d\u306e\u6d3b\u7528\u6cd5<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-5\">presence\u3001length\u3001format\u306a\u3069\u3001\u3088\u304f\u4f7f\u3046\u30d8\u30eb\u30d1\u30fc\u306e\u89e3\u8aac<\/a>      <\/li>      <li>        <a href=\"#i-13\">\u8907\u6570\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u7d44\u307f\u5408\u308f\u305b\u308b\u65b9\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-14\">\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30d8\u30eb\u30d1\u30fc\u4f7f\u7528\u6642\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-18\">\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5\u30c6\u30af\u30cb\u30c3\u30af<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-19\">validate :\u30e1\u30bd\u30c3\u30c9\u540d\u3092\u4f7f\u3063\u305f\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u66f8\u304d\u65b9<\/a>      <\/li>      <li>        <a href=\"#i-20\">ActiveModel::Validator\u3092\u7d99\u627f\u3057\u305f\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30bf\u306e\u4f5c\u6210\u65b9\u6cd5<\/a>      <\/li>      <li>        <a href=\"#i-21\">\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u30c6\u30b9\u30c8\u65b9\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-22\">\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\u3068\u6ce8\u610f\u70b9<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-23\">\u6761\u4ef6\u4ed8\u304d\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3067\u67d4\u8edf\u306a\u5236\u5fa1\u3092\u5b9f\u73fe\u3059\u308b<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-24\">if\u3001unless\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u4f7f\u3063\u305f\u6761\u4ef6\u5206\u5c90\u306e\u5b9f\u88c5<\/a>      <\/li>      <li>        <a href=\"#i-25\">Proc\u3092\u6d3b\u7528\u3057\u305f\u52d5\u7684\u306a\u6761\u4ef6\u8a2d\u5b9a\u306e\u30c6\u30af\u30cb\u30c3\u30af<\/a>      <\/li>      <li>        <a href=\"#i-26\">\u6761\u4ef6\u4ed8\u304d\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5177\u4f53\u7684\u306a\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9<\/a>      <\/li>      <li>        <a href=\"#i-27\">\u6761\u4ef6\u4ed8\u304d\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u30c6\u30b9\u30c8\u65b9\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-28\">\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\u3068\u6ce8\u610f\u70b9<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-29\">\u30a2\u30bd\u30b7\u30a8\u30fc\u30b7\u30e7\u30f3\u3092\u8003\u616e\u3057\u305f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5\u65b9\u6cd5<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-30\">accepts_nested_attributes_for\u3068validates\u306e\u4f75\u7528\u30c6\u30af\u30cb\u30c3\u30af<\/a>      <\/li>      <li>        <a href=\"#i-31\">\u95a2\u9023\u30e2\u30c7\u30eb\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u5236\u5fa1\u3059\u308bbest\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/a>      <\/li>      <li>        <a href=\"#i-35\">\u30a2\u30bd\u30b7\u30a8\u30fc\u30b7\u30e7\u30f3\u3092\u8003\u616e\u3057\u305f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u30c6\u30b9\u30c8\u65b9\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-39\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3068\u30b9\u30b1\u30fc\u30e9\u30d3\u30ea\u30c6\u30a3\u306e\u89b3\u70b9\u304b\u3089\u306e\u6ce8\u610f\u70b9<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-43\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3092\u8003\u616e\u3057\u305f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u6700\u9069\u5316\u624b\u6cd5<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-44\">\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30ec\u30d9\u30eb\u3067\u306e\u5236\u7d04\u3068\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30ec\u30d9\u30eb\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u4f7f\u3044\u5206\u3051<\/a>      <\/li>      <li>        <a href=\"#i-47\">\u30d0\u30c3\u30c1\u51e6\u7406\u6642\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30b9\u30ad\u30c3\u30d7\u306b\u3088\u308b\u51e6\u7406\u901f\u5ea6\u306e\u5411\u4e0a<\/a>      <\/li>      <li>        <a href=\"#i-48\">\u30e1\u30e2\u30ea\u4f7f\u7528\u91cf\u3092\u6291\u3048\u308b\u305f\u3081\u306e\u30c6\u30af\u30cb\u30c3\u30af<\/a>      <\/li>      <li>        <a href=\"#i-52\">\u975e\u540c\u671f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5<\/a>      <\/li>      <li>        <a href=\"#i-53\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u306e\u5177\u4f53\u7684\u306a\u5b9f\u88c5\u4f8b\u3068\u30d9\u30f3\u30c1\u30de\u30fc\u30af\u7d50\u679c<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-54\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u6642\u306e\u6ce8\u610f\u70b9\u3068\u30c8\u30ec\u30fc\u30c9\u30aa\u30d5<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-55\">\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3092\u5f37\u5316\u3059\u308b\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30c6\u30af\u30cb\u30c3\u30af<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-56\">Strong Parameters\u3068\u306e\u9023\u643a\u306b\u3088\u308b\u30de\u30b9\u30a2\u30b5\u30a4\u30f3\u30e1\u30f3\u30c8\u5bfe\u7b56<\/a>      <\/li>      <li>        <a href=\"#i-57\">\u30b5\u30cb\u30bf\u30a4\u30ba\u3068\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u7d44\u307f\u5408\u308f\u305b\u305fXSS\u5bfe\u7b56\u306e\u5b9f\u88c5<\/a>      <\/li>      <li>        <a href=\"#i-58\">SQL Injection\u3092\u9632\u3050\u305f\u3081\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30c6\u30af\u30cb\u30c3\u30af<\/a>      <\/li>      <li>        <a href=\"#i-59\">\u6a5f\u5bc6\u60c5\u5831\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3068\u4fdd\u8b77<\/a>      <\/li>      <li>        <a href=\"#i-60\">\u30bb\u30ad\u30e5\u30a2\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5\u4f8b\u3068\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/a>      <\/li>      <li>        <a href=\"#i-65\">\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u95a2\u9023\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u30c6\u30b9\u30c8\u3059\u308b\u65b9\u6cd5<\/a>      <\/li>      <li>        <a href=\"#i-66\">\u8ffd\u52a0\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5f37\u5316\u30c6\u30af\u30cb\u30c3\u30af<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-72\">\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u7d99\u7d9a\u7684\u306a\u6539\u5584<\/a>      <\/li>    <\/ul>  <\/li>  <li class=\"last\">    <a href=\"#i-73\">\u307e\u3068\u3081\uff1a\u52b9\u679c\u7684\u306avalidate\u306e\u6d3b\u7528\u3067\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u54c1\u8cea\u3092\u5411\u4e0a\u3055\u305b\u3088\u3046<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-74\">\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u91cd\u8981\u6027\u3068\u5b66\u3093\u30607\u3064\u306e\u30c6\u30af\u30cb\u30c3\u30af<\/a>      <\/li>      <li>        <a href=\"#i-75\">\u52b9\u679c\u7684\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u6d3b\u7528\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/a>      <\/li>      <li>        <a href=\"#i-76\">\u4eca\u5f8c\u306e\u5b66\u7fd2\u3068\u5b9f\u8df5\u306b\u5411\u3051\u3066<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-77\">\u3055\u3089\u306a\u308b\u5b66\u7fd2\u30ea\u30bd\u30fc\u30b9<\/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-sgb-headings sgb-heading\" id=\"i-0\"><span class=\"sgb-heading__inner sgb-heading--type1 with-icon\" style=\"background-color:transparent;border-color:transparent;font-size:1.2em\"><i class=\"fa fa-check\" style=\"color:var(--wp--preset--color--sango-main)\"><\/i><span class=\"sgb-heading__text\" style=\"color:#333\">Ruby on Rails\u306evalidate\u3068\u306f\uff1f\u57fa\u672c\u7684\u306a\u4f7f\u3044\u65b9\u3092\u89e3\u8aac<\/span><\/span><\/h2>\n\n\n\n<p>Ruby on Rails\u306b\u304a\u3051\u308b<code>validate<\/code>\u306f\u3001ActiveRecord\u30e2\u30c7\u30eb\u306b\u7d44\u307f\u8fbc\u307e\u308c\u305f\u30c7\u30fc\u30bf\u691c\u8a3c\u6a5f\u80fd\u3067\u3059\u3002<br>\u3053\u306e\u6a5f\u80fd\u3092\u4f7f\u3046\u3053\u3068\u3067\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u4fdd\u5b58\u3055\u308c\u308b\u524d\u306b\u30c7\u30fc\u30bf\u306e\u6574\u5408\u6027\u3092\u30c1\u30a7\u30c3\u30af\u3057\u3001\u7121\u52b9\u306a\u30c7\u30fc\u30bf\u306e\u633f\u5165\u3092\u9632\u3050\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-1\">\u30e2\u30c7\u30eb\u306e\u6574\u5408\u6027\u3092\u4fdd\u3064validate\u306e\u91cd\u8981\u6027<\/h3>\n\n\n\n<p>validate\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u306b\u306f\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u91cd\u8981\u306a\u5229\u70b9\u304c\u3042\u308a\u307e\u3059<\/p>\n\n\n\n<div class=\"wp-block-sgb-block-simple sgb-box-simple sgb-box-simple--title-normal sgb-box-simple--with-border\"><div style=\"background-color:var(--wp--preset--color--sango-main);color:#FFF\" class=\"sgb-box-simple__title\"><code>validate<\/code>\u306e3\u3064\u306e\u5229\u70b9<\/div><div class=\"sgb-box-simple__body\" style=\"border-color:var(--wp--preset--color--sango-main);background-color:#FFF\">\n<ol class=\"wp-block-list\">\n<li><strong>\u30c7\u30fc\u30bf\u306e\u6574\u5408\u6027\u4fdd\u6301<\/strong>: \u4e00\u8cab\u6027\u306e\u3042\u308b\u30c7\u30fc\u30bf\u3092\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u4fdd\u5b58\u3067\u304d\u307e\u3059\u3002<\/li>\n\n\n\n<li><strong>\u30e6\u30fc\u30b6\u30fc\u5165\u529b\u306e\u691c\u8a3c<\/strong>: \u30d5\u30a9\u30fc\u30e0\u306a\u3069\u304b\u3089\u9001\u4fe1\u3055\u308c\u308b\u30c7\u30fc\u30bf\u3092\u9069\u5207\u306b\u691c\u8a3c\u3067\u304d\u307e\u3059\u3002<\/li>\n\n\n\n<li><strong>\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u5805\u7262\u6027\u5411\u4e0a<\/strong>: \u4e88\u671f\u305b\u306c\u30c7\u30fc\u30bf\u306b\u3088\u308b\u30a8\u30e9\u30fc\u3092\u9632\u304e\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u5b89\u5b9a\u6027\u304c\u5411\u4e0a\u3057\u307e\u3059\u3002<\/li>\n<\/ol>\n<\/div><\/div>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u5229\u70b9\u306b\u3088\u308a\u3001\u30c7\u30fc\u30bf\u306e\u4fe1\u983c\u6027\u304c\u5411\u4e0a\u3057\u3001\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30ea\u30b9\u30af\u304c\u8efd\u6e1b\u3055\u308c\u3001\u7d50\u679c\u3068\u3057\u3066\u30e6\u30fc\u30b6\u30fc\u4f53\u9a13\u306e\u5411\u4e0a\u306b\u3082\u3064\u306a\u304c\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-2\">validate\u30e1\u30bd\u30c3\u30c9\u306e\u57fa\u672c\u7684\u306a\u69cb\u6587\u3068\u4f7f\u7528\u4f8b<\/h3>\n\n\n\n<p>validate\u30e1\u30bd\u30c3\u30c9\u306e\u57fa\u672c\u7684\u306a\u69cb\u6587\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\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=\"\">class User &lt; ApplicationRecord\n  validates :\u5c5e\u6027\u540d, \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u7a2e\u985e: \u5024\nend<\/pre>\n\n\n\n<p>\u5177\u4f53\u7684\u306a\u4f7f\u7528\u4f8b\u3092\u898b\u3066\u307f\u307e\u3057\u3087\u3046\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=\"\">class User &lt; ApplicationRecord\n  # \u30e6\u30fc\u30b6\u30fc\u540d\u304c\u5fc5\u9808\u3067\u3042\u308b\u3053\u3068\u3092\u691c\u8a3c\n  validates :username, presence: true\n\n  # \u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u304c\u5fc5\u9808\u3067\u3001\u4e00\u610f\u3067\u3042\u308b\u3053\u3068\u3092\u691c\u8a3c\n  validates :email, presence: true, uniqueness: true\n\n  # \u30d1\u30b9\u30ef\u30fc\u30c9\u304c6\u6587\u5b57\u4ee5\u4e0a20\u6587\u5b57\u4ee5\u4e0b\u3067\u3042\u308b\u3053\u3068\u3092\u691c\u8a3c\n  validates :password, length: { minimum: 6, maximum: 20 }\n\n  # \u540d\u524d\u304c\u82f1\u5b57\u306e\u307f\u3067\u3042\u308b\u3053\u3068\u3092\u691c\u8a3c\uff08\u6b63\u898f\u8868\u73fe\u3092\u4f7f\u7528\uff09\n  validates :name, format: { with: \/\\A[a-zA-Z]+\\z\/, message: '\u82f1\u5b57\u306e\u307f\u4f7f\u7528\u3067\u304d\u307e\u3059' }\nend<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u4f8b\u3067\u306f\u3001\u305d\u308c\u305e\u308c\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u884c\u3063\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<div class=\"wp-block-sgb-message\"><div class=\"memo sng-shadow-0\" style=\"border-radius:0px;background-color:#b4e0fa;color:#009EF3\"><div class=\"memo_ttl dfont\"><span class=\"sng-box-msg__icon\" style=\"background:#009EF3\"><i class=\"far fa-lightbulb\"><\/i><\/span><div class=\"sng-box-msg__title\">\u4e0a\u8a18\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u306e\u89e3\u8aac<\/div><\/div><div class=\"sng-box-msg__contents\">\n<ul class=\"wp-block-list\">\n<li><code>presence: true<\/code>: \u5024\u304c\u5b58\u5728\u3057\u3001\u7a7a\u3067\u306a\u3044\u3053\u3068\u3092\u78ba\u8a8d<\/li>\n\n\n\n<li><code>uniqueness: true<\/code>: \u5024\u304c\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u5185\u3067\u4e00\u610f\u3067\u3042\u308b\u3053\u3068\u3092\u78ba\u8a8d<\/li>\n\n\n\n<li><code>length: { minimum: X, maximum: Y }<\/code>: \u5024\u306e\u9577\u3055\u304c\u6307\u5b9a\u7bc4\u56f2\u5185\u3067\u3042\u308b\u3053\u3068\u3092\u78ba\u8a8d<\/li>\n\n\n\n<li><code>format: { with: \/\u6b63\u898f\u8868\u73fe\/, message: '\u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8' }<\/code>: \u5024\u304c\u6307\u5b9a\u3055\u308c\u305f\u30d1\u30bf\u30fc\u30f3\u306b\u4e00\u81f4\u3059\u308b\u3053\u3068\u3092\u78ba\u8a8d<\/li>\n<\/ul>\n<\/div><\/div><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-3\">validate\u3092\u4f7f\u3046\u969b\u306e\u6ce8\u610f\u70b9\u3068\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h3>\n\n\n\n<p>validate\u3092\u52b9\u679c\u7684\u306b\u4f7f\u7528\u3059\u308b\u306b\u306f\u3001\u4ee5\u4e0b\u306e\u70b9\u306b\u6ce8\u610f\u3057\u307e\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<div class=\"wp-block-sgb-message\"><div class=\"memo sng-shadow-0\" style=\"border-radius:0px;background-color:#ffebeb;color:#f88080\"><div class=\"memo_ttl dfont\"><span class=\"sng-box-msg__icon\" style=\"background:#f88080\"><i class=\"fas fa-exclamation\"><\/i><\/span><div class=\"sng-box-msg__title\"><code>validate<\/code>\u5229\u7528\u6642\u306e\u6ce8\u610f\u70b9<\/div><\/div><div class=\"sng-box-msg__contents\">\n<ol class=\"wp-block-list\">\n<li><strong>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3078\u306e\u914d\u616e<\/strong>: \u904e\u5ea6\u306b\u8907\u96d1\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306f\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u306b\u5f71\u97ff\u3092\u4e0e\u3048\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002\u5fc5\u8981\u6700\u5c0f\u9650\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u5fc3\u304c\u3051\u307e\u3057\u3087\u3046\u3002<\/li>\n\n\n\n<li><strong>\u9069\u5207\u306a\u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\u306e\u8a2d\u5b9a<\/strong>: \u30e6\u30fc\u30b6\u30fc\u306b\u308f\u304b\u308a\u3084\u3059\u3044\u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u8a2d\u5b9a\u3059\u308b\u3053\u3068\u3067\u3001UX\u3092\u5411\u4e0a\u3055\u305b\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/li>\n\n\n\n<li><strong>\u8907\u6570\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u7d44\u307f\u5408\u308f\u305b<\/strong>: \u5fc5\u8981\u306b\u5fdc\u3058\u3066\u8907\u6570\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u53b3\u5bc6\u306a\u691c\u8a3c\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\u3002<\/li>\n\n\n\n<li><strong>\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u6d3b\u7528<\/strong>: \u6a19\u6e96\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3067\u306f\u5bfe\u5fdc\u3067\u304d\u306a\u3044\u8907\u96d1\u306a\u30eb\u30fc\u30eb\u306f\u3001\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u4f5c\u6210\u3057\u3066\u5bfe\u5fdc\u3057\u307e\u3057\u3087\u3046\u3002<\/li>\n<\/ol>\n<\/div><\/div><\/div>\n\n\n\n<p>validate\u3092\u9069\u5207\u306b\u4f7f\u7528\u3059\u308b\u3053\u3068\u3067\u3001Ruby on Rails\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u54c1\u8cea\u3068\u4fe1\u983c\u6027\u3092\u5927\u304d\u304f\u5411\u4e0a\u3055\u305b\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<br>\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u3055\u3089\u306b\u8a73\u7d30\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30d8\u30eb\u30d1\u30fc\u3068\u305d\u306e\u6d3b\u7528\u6cd5\u306b\u3064\u3044\u3066\u89e3\u8aac\u3057\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-sgb-headings sgb-heading\" id=\"i-4\"><span class=\"sgb-heading__inner sgb-heading--type1 with-icon\" style=\"background-color:transparent;border-color:transparent;font-size:1.2em\"><i class=\"fa fa-check\" style=\"color:var(--wp--preset--color--sango-main)\"><\/i><span class=\"sgb-heading__text\" style=\"color:#333\">validate\u3067\u4f7f\u3048\u308b\u4e3b\u8981\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30d8\u30eb\u30d1\u30fc\u3068\u305d\u306e\u6d3b\u7528\u6cd5<\/span><\/span><\/h2>\n\n\n\n<p>Ruby on Rails\u306b\u306f\u3001\u30e2\u30c7\u30eb\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u7c21\u5358\u306b\u5b9f\u88c5\u3067\u304d\u308b\u591a\u304f\u306e\u30d8\u30eb\u30d1\u30fc\u30e1\u30bd\u30c3\u30c9\u304c\u7528\u610f\u3055\u308c\u3066\u3044\u307e\u3059\u3002<br>\u3053\u308c\u3089\u306e\u30d8\u30eb\u30d1\u30fc\u3092\u4f7f\u3044\u3053\u306a\u3059\u3053\u3068\u3067\u3001\u52b9\u7387\u7684\u304b\u3064\u5805\u7262\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u5b9f\u88c5\u3067\u304d\u307e\u3059\u3002<br>\u3053\u3053\u3067\u306f\u3001\u4e3b\u8981\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30d8\u30eb\u30d1\u30fc\u3068\u305d\u306e\u6d3b\u7528\u6cd5\u306b\u3064\u3044\u3066\u8a73\u3057\u304f\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-5\">presence\u3001length\u3001format\u306a\u3069\u3001\u3088\u304f\u4f7f\u3046\u30d8\u30eb\u30d1\u30fc\u306e\u89e3\u8aac<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-6\">1. <strong><code>presence<\/code><\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u7528\u9014\uff1a\u5024\u304c\u5b58\u5728\u3057\u3001\u7a7a\u3067\u306a\u3044\u3053\u3068\u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002<\/li>\n\n\n\n<li>\u4f7f\u7528\u4f8b\uff1a<code>ruby validates :username, presence: true<\/code><\/li>\n\n\n\n<li>\u6ce8\u610f\u70b9\uff1a\u7a7a\u6587\u5b57\u5217\u3084\u7a7a\u767d\u306e\u307f\u306e\u6587\u5b57\u5217\u3082\u300c\u5b58\u5728\u3059\u308b\u300d\u3068\u5224\u65ad\u3055\u308c\u308b\u305f\u3081\u3001\u5fc5\u8981\u306b\u5fdc\u3058\u3066<code>strip<\/code>\u30e1\u30bd\u30c3\u30c9\u3068\u7d44\u307f\u5408\u308f\u305b\u3066\u4f7f\u7528\u3057\u307e\u3059\u3002<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-7\">2. <strong><code>length<\/code><\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u7528\u9014\uff1a\u6587\u5b57\u5217\u306e\u9577\u3055\u3092\u691c\u8a3c\u3057\u307e\u3059\u3002<\/li>\n\n\n\n<li>\u4f7f\u7528\u4f8b\uff1a<code>ruby validates :password, length: { minimum: 8, maximum: 20 }<\/code><\/li>\n\n\n\n<li>\u30aa\u30d7\u30b7\u30e7\u30f3\uff1a<code>minimum<\/code>\u3001<code>maximum<\/code>\u3001<code>in<\/code>\uff08\u7bc4\u56f2\u6307\u5b9a\uff09\u3001<code>is<\/code>\uff08\u53b3\u5bc6\u306a\u9577\u3055\u6307\u5b9a\uff09<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-8\">3. <strong><code>format<\/code><\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u7528\u9014\uff1a\u6b63\u898f\u8868\u73fe\u306b\u3088\u308b\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u691c\u8a3c\u3092\u884c\u3044\u307e\u3059\u3002<\/li>\n\n\n\n<li>\u4f7f\u7528\u4f8b\uff1a<code>ruby validates :email, format: { with: \/\\A[\\w+\\-.]+@[a-z\\d\\-]+(\\.[a-z\\d\\-]+)*\\.[a-z]+\\z\/i, message: \"\u6b63\u3057\u3044\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u306e\u5f62\u5f0f\u3067\u306f\u3042\u308a\u307e\u305b\u3093\" }<\/code><\/li>\n\n\n\n<li>\u6ce8\u610f\u70b9\uff1a\u8907\u96d1\u306a\u6b63\u898f\u8868\u73fe\u306f\u53ef\u8aad\u6027\u304c\u4f4e\u4e0b\u3059\u308b\u305f\u3081\u3001\u5fc5\u8981\u306b\u5fdc\u3058\u3066\u30b3\u30e1\u30f3\u30c8\u3092\u4ed8\u3051\u308b\u3088\u3046\u306b\u3057\u307e\u3057\u3087\u3046\u3002<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-9\">4. <strong><code>uniqueness<\/code><\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u7528\u9014\uff1a\u5024\u304c\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u5185\u3067\u4e00\u610f\u3067\u3042\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002<\/li>\n\n\n\n<li>\u4f7f\u7528\u4f8b\uff1a<code>ruby validates :email, uniqueness: { case_sensitive: false }<\/code><\/li>\n\n\n\n<li>\u6ce8\u610f\u70b9\uff1a\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30ec\u30d9\u30eb\u3067\u3082\u30e6\u30cb\u30fc\u30af\u5236\u7d04\u3092\u8a2d\u5b9a\u3059\u308b\u3053\u3068\u3092\u304a\u52e7\u3081\u3057\u307e\u3059\u3002<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-10\">5. <strong><code>numericality<\/code><\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u7528\u9014\uff1a\u6570\u5024\u306b\u95a2\u3059\u308b\u6761\u4ef6\u3092\u691c\u8a3c\u3057\u307e\u3059\u3002<\/li>\n\n\n\n<li>\u4f7f\u7528\u4f8b\uff1a<code>ruby validates :age, numericality: { greater_than_or_equal_to: 0, less_than: 150 }<\/code><\/li>\n\n\n\n<li>\u30aa\u30d7\u30b7\u30e7\u30f3\uff1a<code>only_integer<\/code>\u3001<code>greater_than<\/code>\u3001<code>less_than<\/code>\u3001<code>odd<\/code>\u3001<code>even<\/code>\u306a\u3069<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-11\">6. <strong><code>inclusion<\/code><\/strong> \/ <strong><code>exclusion<\/code><\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u7528\u9014\uff1a\u6307\u5b9a\u3055\u308c\u305f\u5024\u306e\u96c6\u5408\u306b\u542b\u307e\u308c\u308b\uff08inclusion\uff09\u307e\u305f\u306f\u542b\u307e\u308c\u306a\u3044\uff08exclusion\uff09\u3053\u3068\u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002<\/li>\n\n\n\n<li>\u4f7f\u7528\u4f8b\uff1a<code>ruby validates :status, inclusion: { in: %w(pending approved rejected), message: \"%{value} \u306f\u6709\u52b9\u306a\u30b9\u30c6\u30fc\u30bf\u30b9\u3067\u306f\u3042\u308a\u307e\u305b\u3093\" }<\/code><\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-12\">7. <strong><code>acceptance<\/code><\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u7528\u9014\uff1a\u30c1\u30a7\u30c3\u30af\u30dc\u30c3\u30af\u30b9\u306a\u3069\u306e\u540c\u610f\u78ba\u8a8d\u306b\u4f7f\u7528\u3057\u307e\u3059\u3002<\/li>\n\n\n\n<li>\u4f7f\u7528\u4f8b\uff1a<code>ruby validates :terms_of_service, acceptance: true<\/code><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-13\">\u8907\u6570\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u7d44\u307f\u5408\u308f\u305b\u308b\u65b9\u6cd5<\/h3>\n\n\n\n<p>\u8907\u6570\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u53b3\u5bc6\u306a\u691c\u8a3c\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\u3002<br>\u4ee5\u4e0b\u306b\u4f8b\u3092\u793a\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=\"\">class User &lt; ApplicationRecord\n  validates :username, presence: true, \n                       length: { minimum: 3, maximum: 20 },\n                       format: { with: \/\\A[a-zA-Z0-9_]+\\z\/, message: \"\u30e6\u30fc\u30b6\u30fc\u540d\u306f\u82f1\u6570\u5b57\u3068\u30a2\u30f3\u30c0\u30fc\u30b9\u30b3\u30a2\u306e\u307f\u4f7f\u7528\u3067\u304d\u307e\u3059\" },\n                       uniqueness: { case_sensitive: false }\n\n  validates :age, numericality: { greater_than_or_equal_to: 18 },\n                  inclusion: { in: 18..120, message: \"\u5e74\u9f62\u306f18\u6b73\u304b\u3089120\u6b73\u306e\u9593\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\" }\nend<\/pre>\n\n\n\n<p>\u3053\u306e\u4f8b\u3067\u306f\u3001<code>username<\/code>\u306b\u5bfe\u3057\u3066\u8907\u6570\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u9069\u7528\u3057\u3001\u5b58\u5728\u30c1\u30a7\u30c3\u30af\u3001\u9577\u3055\u30c1\u30a7\u30c3\u30af\u3001\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u30c1\u30a7\u30c3\u30af\u3001\u4e00\u610f\u6027\u30c1\u30a7\u30c3\u30af\u3092\u884c\u3063\u3066\u3044\u307e\u3059\u3002<br>\u307e\u305f\u3001<code>age<\/code>\u306b\u5bfe\u3057\u3066\u306f\u6570\u5024\u30c1\u30a7\u30c3\u30af\u3068\u7bc4\u56f2\u30c1\u30a7\u30c3\u30af\u3092\u7d44\u307f\u5408\u308f\u305b\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-14\">\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30d8\u30eb\u30d1\u30fc\u4f7f\u7528\u6642\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-15\">1. <strong>\u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\u306e\u30ab\u30b9\u30bf\u30de\u30a4\u30ba<\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30c7\u30d5\u30a9\u30eb\u30c8\u306e\u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\u306f\u4e00\u822c\u7684\u3059\u304e\u308b\u5834\u5408\u304c\u3042\u308b\u305f\u3081\u3001<code>message<\/code>\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u4f7f\u7528\u3057\u3066\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\u3057\u307e\u3057\u3087\u3046\u3002<\/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=\"\">   validates :email, format: { with: \/\\A[\\w+\\-.]+@[a-z\\d\\-]+(\\.[a-z\\d\\-]+)*\\.[a-z]+\\z\/i, message: \"\u6b63\u3057\u3044\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u306e\u5f62\u5f0f\u3067\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\" }<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-16\">2. <strong>\u6761\u4ef6\u4ed8\u304d\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u6d3b\u7528<\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>if<\/code>\u3084<code>unless<\/code>\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u4f7f\u7528\u3057\u3066\u3001\u7279\u5b9a\u306e\u6761\u4ef6\u4e0b\u3067\u306e\u307f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u5b9f\u884c\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/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=\"\">   validates :card_number, presence: true, if: :paid_with_card?<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-17\">3. <strong>\u30b9\u30b3\u30fc\u30d7\u3092\u4f7f\u3063\u305f\u30e6\u30cb\u30fc\u30af\u5236\u7d04<\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>uniqueness<\/code>\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306b<code>scope<\/code>\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u8ffd\u52a0\u3059\u308b\u3053\u3068\u3067\u3001\u7279\u5b9a\u306e\u7bc4\u56f2\u5185\u3067\u306e\u307f\u30e6\u30cb\u30fc\u30af\u5236\u7d04\u3092\u9069\u7528\u3067\u304d\u307e\u3059\u3002<\/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=\"\">   validates :name, uniqueness: { scope: :year, message: \"\u540c\u3058\u5e74\u306b\u540c\u540d\u306e\u9805\u76ee\u306f\u4f5c\u6210\u3067\u304d\u307e\u305b\u3093\" }<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u4e3b\u8981\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30d8\u30eb\u30d1\u30fc\u3068\u6d3b\u7528\u6cd5\u3092\u7406\u89e3\u3057\u3001\u9069\u5207\u306b\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3001\u5805\u7262\u3067\u30e6\u30fc\u30b6\u30fc\u30d5\u30ec\u30f3\u30c9\u30ea\u30fc\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u5b9f\u88c5\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<br>\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u3088\u308a\u8907\u96d1\u306a\u30cb\u30fc\u30ba\u306b\u5bfe\u5fdc\u3059\u308b\u305f\u3081\u306e\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5\u30c6\u30af\u30cb\u30c3\u30af\u306b\u3064\u3044\u3066\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-sgb-headings sgb-heading\" id=\"i-18\"><span class=\"sgb-heading__inner sgb-heading--type1 with-icon\" style=\"background-color:transparent;border-color:transparent;font-size:1.2em\"><i class=\"fa fa-check\" style=\"color:var(--wp--preset--color--sango-main)\"><\/i><span class=\"sgb-heading__text\" style=\"color:#333\">\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5\u30c6\u30af\u30cb\u30c3\u30af<\/span><\/span><\/h2>\n\n\n\n<p>\u6a19\u6e96\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30d8\u30eb\u30d1\u30fc\u3060\u3051\u3067\u306f\u5bfe\u5fdc\u3067\u304d\u306a\u3044\u8907\u96d1\u306a\u30eb\u30fc\u30eb\u3084\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u56fa\u6709\u306e\u8981\u4ef6\u306b\u5bfe\u5fdc\u3059\u308b\u305f\u3081\u306b\u3001\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u304c\u5fc5\u8981\u306b\u306a\u308b\u3053\u3068\u304c\u3042\u308a\u307e\u3059\u3002<br>\u3053\u3053\u3067\u306f\u3001Ruby on Rails\u3067\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u5b9f\u88c5\u3059\u308b\u305f\u3081\u306e2\u3064\u306e\u4e3b\u8981\u306a\u65b9\u6cd5\u3068\u3001\u305d\u306e\u5b9f\u8df5\u7684\u306a\u30c6\u30af\u30cb\u30c3\u30af\u306b\u3064\u3044\u3066\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-19\">validate :\u30e1\u30bd\u30c3\u30c9\u540d\u3092\u4f7f\u3063\u305f\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u66f8\u304d\u65b9<\/h3>\n\n\n\n<p>\u6700\u3082\u30b7\u30f3\u30d7\u30eb\u306a\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u65b9\u6cd5\u306f\u3001\u30e2\u30c7\u30eb\u5185\u306b\u30e1\u30bd\u30c3\u30c9\u3092\u5b9a\u7fa9\u3057\u3001<code>validate<\/code>\u30e1\u30bd\u30c3\u30c9\u3067\u547c\u3073\u51fa\u3059\u65b9\u6cd5\u3067\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=\"\">class Product &lt; ApplicationRecord\n  validate :check_expiration_date\n\n  private\n\n  def check_expiration_date\n    if expiration_date.present? &amp;&amp; expiration_date &lt; Date.today\n      errors.add(:expiration_date, \"\u306f\u4eca\u65e5\u4ee5\u964d\u306e\u65e5\u4ed8\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\")\n    end\n  end\nend<\/pre>\n\n\n\n<div class=\"wp-block-sgb-message\"><div class=\"memo sng-shadow-0\" style=\"border-radius:0px;background-color:#b4e0fa;color:#009EF3\"><div class=\"memo_ttl dfont\"><span class=\"sng-box-msg__icon\" style=\"background:#009EF3\"><i class=\"far fa-thumbs-up\"><\/i><\/span><div class=\"sng-box-msg__title\">\u4e0a\u8a18\u624b\u6cd5\u306e\u30e1\u30ea\u30c3\u30c8<\/div><\/div><div class=\"sng-box-msg__contents\">\n<ul class=\"wp-block-list\">\n<li>\u30b7\u30f3\u30d7\u30eb\u3067\u76f4\u611f\u7684\u306a\u5b9f\u88c5<\/li>\n\n\n\n<li>\u30e2\u30c7\u30eb\u56fa\u6709\u306e\u30ed\u30b8\u30c3\u30af\u306b\u9069\u3057\u3066\u3044\u308b<\/li>\n\n\n\n<li>\u4ed6\u306e\u30e2\u30c7\u30eb\u30e1\u30bd\u30c3\u30c9\u3084\u5c5e\u6027\u306b\u7c21\u5358\u306b\u30a2\u30af\u30bb\u30b9\u3067\u304d\u308b<\/li>\n<\/ul>\n<\/div><\/div><\/div>\n\n\n\n<div class=\"wp-block-sgb-message\"><div class=\"memo sng-shadow-0\" style=\"border-radius:0px;background-color:#ffebeb;color:#f88080\"><div class=\"memo_ttl dfont\"><span class=\"sng-box-msg__icon\" style=\"background:#f88080\"><i class=\"fas fa-thumbs-down\"><\/i><\/span><div class=\"sng-box-msg__title\">\u4e0a\u8a18\u624b\u6cd5\u306e\u30c7\u30e1\u30ea\u30c3\u30c8<\/div><\/div><div class=\"sng-box-msg__contents\">\n<ul class=\"wp-block-list\">\n<li>\u518d\u5229\u7528\u6027\u304c\u4f4e\u3044\uff08\u4ed6\u306e\u30e2\u30c7\u30eb\u3067\u540c\u3058\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u4f7f\u3044\u305f\u3044\u5834\u5408\u306b\u8ab2\u984c\u304c\u3042\u308b\uff09<\/li>\n<\/ul>\n<\/div><\/div><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-20\">ActiveModel::Validator\u3092\u7d99\u627f\u3057\u305f\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30bf\u306e\u4f5c\u6210\u65b9\u6cd5<\/h3>\n\n\n\n<p>\u3088\u308a\u518d\u5229\u7528\u6027\u306e\u9ad8\u3044\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u4f5c\u6210\u3057\u305f\u3044\u5834\u5408\u306f\u3001<code>ActiveModel::Validator<\/code>\u3092\u7d99\u627f\u3057\u305f\u30af\u30e9\u30b9\u3092\u4f5c\u6210\u3059\u308b\u65b9\u6cd5\u304c\u3042\u308a\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=\"\">class ExpirationDateValidator &lt; ActiveModel::Validator\n  def validate(record)\n    if record.expiration_date.present? &amp;&amp; record.expiration_date &lt; Date.today\n      record.errors.add(:expiration_date, \"\u306f\u4eca\u65e5\u4ee5\u964d\u306e\u65e5\u4ed8\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\")\n    end\n  end\nend\n\nclass Product &lt; ApplicationRecord\n  validates_with ExpirationDateValidator\nend<\/pre>\n\n\n\n<div class=\"wp-block-sgb-message\"><div class=\"memo sng-shadow-0\" style=\"border-radius:0px;background-color:#b4e0fa;color:#009EF3\"><div class=\"memo_ttl dfont\"><span class=\"sng-box-msg__icon\" style=\"background:#009EF3\"><i class=\"far fa-thumbs-up\"><\/i><\/span><div class=\"sng-box-msg__title\">\u4e0a\u8a18\u624b\u6cd5\u306e\u30e1\u30ea\u30c3\u30c8<\/div><\/div><div class=\"sng-box-msg__contents\">\n<ul class=\"wp-block-list\">\n<li>\u8907\u6570\u306e\u30e2\u30c7\u30eb\u3067\u518d\u5229\u7528\u53ef\u80fd<\/li>\n\n\n\n<li>\u30c6\u30b9\u30c8\u304c\u66f8\u304d\u3084\u3059\u3044\uff08\u30d0\u30ea\u30c7\u30fc\u30bf\u30af\u30e9\u30b9\u3092\u5358\u72ec\u3067\u30c6\u30b9\u30c8\u3067\u304d\u308b\uff09<\/li>\n\n\n\n<li>\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30ed\u30b8\u30c3\u30af\u3092\u30e2\u30c7\u30eb\u304b\u3089\u5206\u96e2\u3067\u304d\u308b<\/li>\n<\/ul>\n<\/div><\/div><\/div>\n\n\n\n<div class=\"wp-block-sgb-message\"><div class=\"memo sng-shadow-0\" style=\"border-radius:0px;background-color:#ffebeb;color:#f88080\"><div class=\"memo_ttl dfont\"><span class=\"sng-box-msg__icon\" style=\"background:#f88080\"><i class=\"fas fa-thumbs-down\"><\/i><\/span><div class=\"sng-box-msg__title\">\u4e0a\u8a18\u624b\u6cd5\u306e\u30c7\u30e1\u30ea\u30c3\u30c8<\/div><\/div><div class=\"sng-box-msg__contents\">\n<ul class=\"wp-block-list\">\n<li>\u5b9f\u88c5\u304c\u82e5\u5e72\u8907\u96d1\u306b\u306a\u308b<\/li>\n\n\n\n<li>\u30e2\u30c7\u30eb\u306e\u5c5e\u6027\u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b\u969b\u306b\u5c11\u3057\u5197\u9577\u306b\u306a\u308b\u5834\u5408\u304c\u3042\u308b<\/li>\n<\/ul>\n<\/div><\/div><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-21\">\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u30c6\u30b9\u30c8\u65b9\u6cd5<\/h3>\n\n\n\n<p>\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u30c6\u30b9\u30c8\u306f\u3001\u901a\u5e38\u306e\u30e2\u30c7\u30eb\u306e\u30c6\u30b9\u30c8\u3068\u540c\u69d8\u306b\u884c\u3046\u3053\u3068\u304c\u3067\u304d\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=\"\">RSpec.describe Product, type: :model do\n  describe 'expiration date validation' do\n    it 'is invalid with a past expiration date' do\n      product = Product.new(expiration_date: Date.yesterday)\n      expect(product).to be_invalid\n      expect(product.errors[:expiration_date]).to include(\"\u306f\u4eca\u65e5\u4ee5\u964d\u306e\u65e5\u4ed8\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\")\n    end\n\n    it 'is valid with a future expiration date' do\n      product = Product.new(expiration_date: Date.tomorrow)\n      expect(product).to be_valid\n    end\n  end\nend<\/pre>\n\n\n\n<p><code>ActiveModel::Validator<\/code>\u3092\u4f7f\u7528\u3057\u3066\u3044\u308b\u5834\u5408\u306f\u3001\u30d0\u30ea\u30c7\u30fc\u30bf\u30af\u30e9\u30b9\u81ea\u4f53\u3082\u30c6\u30b9\u30c8\u3059\u308b\u3053\u3068\u304c\u3067\u304d\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=\"\">RSpec.describe ExpirationDateValidator do\n  describe '#validate' do\n    it 'adds an error for past expiration dates' do\n      record = double('record', expiration_date: Date.yesterday, errors: double('errors'))\n      expect(record.errors).to receive(:add).with(:expiration_date, \"\u306f\u4eca\u65e5\u4ee5\u964d\u306e\u65e5\u4ed8\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\")\n\n      validator = ExpirationDateValidator.new\n      validator.validate(record)\n    end\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-22\">\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\u3068\u6ce8\u610f\u70b9<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306f\u5c0f\u3055\u304f\u4fdd\u3064<\/strong>: \u8907\u96d1\u306a\u30ed\u30b8\u30c3\u30af\u306f\u5225\u306e\u30b5\u30fc\u30d3\u30b9\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306b\u5207\u308a\u51fa\u3059\u3053\u3068\u3092\u691c\u8a0e\u3057\u307e\u3057\u3087\u3046\u3002<\/li>\n\n\n\n<li><strong>\u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\u306f\u5177\u4f53\u7684\u304b\u3064\u6709\u7528\u306a\u3082\u306e\u306b\u3059\u308b<\/strong>: \u30e6\u30fc\u30b6\u30fc\u304c\u4f55\u3092\u3059\u3079\u304d\u304b\u308f\u304b\u308b\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u5fc3\u304c\u3051\u307e\u3057\u3087\u3046\u3002<\/li>\n\n\n\n<li><strong>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3092\u8003\u616e\u3059\u308b<\/strong>: \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30af\u30a8\u30ea\u3092\u4f34\u3046\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306f\u614e\u91cd\u306b\u6271\u3044\u3001\u5fc5\u8981\u306b\u5fdc\u3058\u3066\u30ad\u30e3\u30c3\u30b7\u30e5\u3092\u6d3b\u7528\u3057\u307e\u3057\u3087\u3046\u3002<\/li>\n\n\n\n<li><strong>context\u3092\u6d3b\u7528\u3059\u308b<\/strong>: \u540c\u3058\u30e2\u30c7\u30eb\u3067\u7570\u306a\u308b\u30b7\u30ca\u30ea\u30aa\u306b\u5fdc\u3058\u305f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u304c\u5fc5\u8981\u306a\u5834\u5408\u306f\u3001<code>on: :context<\/code>\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u3092\u691c\u8a0e\u3057\u307e\u3057\u3087\u3046\u3002<\/li>\n\n\n\n<li><strong>i18n\u3092\u6d3b\u7528\u3059\u308b<\/strong>: \u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\u306f\u56fd\u969b\u5316\uff08i18n\uff09\u3092\u4f7f\u7528\u3057\u3066\u7ba1\u7406\u3059\u308b\u3068\u3001\u5f8c\u3005\u306e\u5909\u66f4\u3084\u591a\u8a00\u8a9e\u5bfe\u5fdc\u304c\u5bb9\u6613\u306b\u306a\u308a\u307e\u3059\u3002<\/li>\n<\/ol>\n\n\n\n<p>\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u9069\u5207\u306b\u5b9f\u88c5\u3059\u308b\u3053\u3068\u3067\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30c7\u30fc\u30bf\u6574\u5408\u6027\u3092\u9ad8\u3081\u3001\u30e6\u30fc\u30b6\u30fc\u4f53\u9a13\u3092\u5411\u4e0a\u3055\u305b\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<br>\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u3055\u3089\u306b\u9ad8\u5ea6\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30c6\u30af\u30cb\u30c3\u30af\u3068\u3057\u3066\u3001\u6761\u4ef6\u4ed8\u304d\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306b\u3064\u3044\u3066\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-23\">\u6761\u4ef6\u4ed8\u304d\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3067\u67d4\u8edf\u306a\u5236\u5fa1\u3092\u5b9f\u73fe\u3059\u308b<\/h2>\n\n\n\n<p>\u6761\u4ef6\u4ed8\u304d\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306f\u3001\u7279\u5b9a\u306e\u6761\u4ef6\u4e0b\u3067\u306e\u307f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u5b9f\u884c\u3059\u308b\u6a5f\u80fd\u3067\u3059\u3002<br>\u3053\u308c\u306b\u3088\u308a\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u8907\u96d1\u306a\u30d3\u30b8\u30cd\u30b9\u30ed\u30b8\u30c3\u30af\u306b\u5bfe\u5fdc\u3057\u305f\u67d4\u8edf\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u5236\u5fa1\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-24\">if\u3001unless\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u4f7f\u3063\u305f\u6761\u4ef6\u5206\u5c90\u306e\u5b9f\u88c5<\/h3>\n\n\n\n<p>\u6700\u3082\u4e00\u822c\u7684\u306a\u6761\u4ef6\u4ed8\u304d\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u65b9\u6cd5\u306f\u3001<code>if<\/code>\u3084<code>unless<\/code>\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u3067\u3059\u3002<br>\u3053\u308c\u3089\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u306b\u306f\u30b7\u30f3\u30dc\u30eb\u307e\u305f\u306f\u30e9\u30e0\u30c0\u5f0f\u3092\u6307\u5b9a\u3067\u304d\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=\"\">class Order &lt; ApplicationRecord\n  validates :card_number, presence: true, if: :paid_with_card?\n  validates :terms_of_service, acceptance: true, unless: :is_returning_customer?\n\n  private\n\n  def paid_with_card?\n    payment_method == 'card'\n  end\n\n  def is_returning_customer?\n    customer.orders.count &gt; 0\n  end\nend<\/pre>\n\n\n\n<div class=\"wp-block-sgb-message\"><div class=\"memo sng-shadow-0\" style=\"border-radius:0px;background-color:#b4e0fa;color:#009EF3\"><div class=\"memo_ttl dfont\"><span class=\"sng-box-msg__icon\" style=\"background:#009EF3\"><i class=\"far fa-thumbs-up\"><\/i><\/span><div class=\"sng-box-msg__title\">\u4e0a\u8a18\u624b\u6cd5\u306e\u30e1\u30ea\u30c3\u30c8<\/div><\/div><div class=\"sng-box-msg__contents\">\n<ul class=\"wp-block-list\">\n<li>\u30b7\u30f3\u30d7\u30eb\u3067\u76f4\u611f\u7684\u306a\u5b9f\u88c5<\/li>\n\n\n\n<li>\u65e2\u5b58\u306e\u30e2\u30c7\u30eb\u30e1\u30bd\u30c3\u30c9\u3092\u6d3b\u7528\u3067\u304d\u308b<\/li>\n\n\n\n<li>\u30b3\u30fc\u30c9\u306e\u53ef\u8aad\u6027\u304c\u9ad8\u3044<\/li>\n<\/ul>\n<\/div><\/div><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-25\">Proc\u3092\u6d3b\u7528\u3057\u305f\u52d5\u7684\u306a\u6761\u4ef6\u8a2d\u5b9a\u306e\u30c6\u30af\u30cb\u30c3\u30af<\/h3>\n\n\n\n<p>\u3088\u308a\u8907\u96d1\u306a\u6761\u4ef6\u3084\u3001\u52d5\u7684\u306b\u6761\u4ef6\u3092\u8a2d\u5b9a\u3057\u305f\u3044\u5834\u5408\u306f\u3001Proc\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u304c\u3067\u304d\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=\"\">class User &lt; ApplicationRecord\n  validates :name, presence: true, if: Proc.new { |user| user.registered? }\n  validates :age, numericality: { greater_than_or_equal_to: 18 },\n                  if: Proc.new { |user| user.country == 'USA' }\n\n  # \u8907\u6570\u306e\u6761\u4ef6\u3092\u7d44\u307f\u5408\u308f\u305b\u308b\n  with_options if: Proc.new { |u| u.active? &amp;&amp; u.age &gt;= 18 } do |active_adult|\n    active_adult.validates :driver_license, presence: true\n    active_adult.validates :insurance_number, presence: true\n  end\nend<\/pre>\n\n\n\n<div class=\"wp-block-sgb-message\"><div class=\"memo sng-shadow-0\" style=\"border-radius:0px;background-color:#b4e0fa;color:#009EF3\"><div class=\"memo_ttl dfont\"><span class=\"sng-box-msg__icon\" style=\"background:#009EF3\"><i class=\"far fa-thumbs-up\"><\/i><\/span><div class=\"sng-box-msg__title\">\u4e0a\u8a18\u624b\u6cd5\u306e\u30e1\u30ea\u30c3\u30c8<\/div><\/div><div class=\"sng-box-msg__contents\">\n<ul class=\"wp-block-list\">\n<li>\u8907\u96d1\u306a\u6761\u4ef6\u3092\u7c21\u6f54\u306b\u8868\u73fe\u3067\u304d\u308b<\/li>\n\n\n\n<li>\u518d\u5229\u7528\u6027\u304c\u9ad8\u3044<\/li>\n\n\n\n<li>\u52d5\u7684\u306b\u6761\u4ef6\u3092\u5909\u66f4\u3067\u304d\u308b<\/li>\n<\/ul>\n<\/div><\/div><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-26\">\u6761\u4ef6\u4ed8\u304d\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5177\u4f53\u7684\u306a\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u7279\u5b9a\u306e\u652f\u6255\u3044\u65b9\u6cd5\u304c\u9078\u629e\u3055\u308c\u305f\u5834\u5408\u306e\u307f\u3001\u95a2\u9023\u30d5\u30a3\u30fc\u30eb\u30c9\u3092\u5fc5\u9808\u306b\u3059\u308b<\/li>\n\n\n\n<li>\u30e6\u30fc\u30b6\u30fc\u306e\u7a2e\u985e\u306b\u3088\u3063\u3066\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30eb\u30fc\u30eb\u3092\u5909\u66f4\u3059\u308b<\/li>\n\n\n\n<li>\u7279\u5b9a\u306e\u72b6\u614b\u306e\u6642\u306e\u307f\u3001\u4e00\u90e8\u306e\u30d5\u30a3\u30fc\u30eb\u30c9\u3092\u5909\u66f4\u53ef\u80fd\u306b\u3059\u308b<\/li>\n<\/ol>\n\n\n\n<p>\u4f8b\u3048\u3070\u3001\u30e6\u30fc\u30b6\u30fc\u306e\u7a2e\u985e\u306b\u3088\u3063\u3066\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u5909\u66f4\u3059\u308b\u5834\u5408\u306f\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u306a\u308a\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=\"\">class User &lt; ApplicationRecord\n  validates :company_name, presence: true, if: :business_account?\n  validates :tax_id, presence: true, if: :business_account?\n  validates :date_of_birth, presence: true, unless: :business_account?\n\n  private\n\n  def business_account?\n    account_type == 'business'\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-27\">\u6761\u4ef6\u4ed8\u304d\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u30c6\u30b9\u30c8\u65b9\u6cd5<\/h3>\n\n\n\n<p>\u6761\u4ef6\u4ed8\u304d\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u30c6\u30b9\u30c8\u3059\u308b\u969b\u306f\u3001\u4ee5\u4e0b\u306e\u70b9\u306b\u6ce8\u610f\u3057\u307e\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u6761\u4ef6\u304c\u771f\u306e\u5834\u5408\u3068\u507d\u306e\u5834\u5408\u306e\u4e21\u65b9\u3092\u30c6\u30b9\u30c8\u3059\u308b<\/li>\n\n\n\n<li>\u5883\u754c\u5024\u306e\u30c6\u30b9\u30c8\u3092\u884c\u3046<\/li>\n\n\n\n<li>\u30e2\u30c3\u30af\u3084\u30b9\u30bf\u30d6\u3092\u4f7f\u7528\u3057\u3066\u6761\u4ef6\u3092\u30b3\u30f3\u30c8\u30ed\u30fc\u30eb\u3059\u308b<\/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=\"\">RSpec.describe User, type: :model do\n  describe 'validations' do\n    context 'when it is a business account' do\n      let(:user) { build(:user, account_type: 'business') }\n\n      it 'requires company_name' do\n        user.company_name = nil\n        expect(user).to be_invalid\n        expect(user.errors[:company_name]).to include(\"can't be blank\")\n      end\n    end\n\n    context 'when it is not a business account' do\n      let(:user) { build(:user, account_type: 'personal') }\n\n      it 'does not require company_name' do\n        user.company_name = nil\n        expect(user).to be_valid\n      end\n    end\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-28\">\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\u3068\u6ce8\u610f\u70b9<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u6761\u4ef6\u30ed\u30b8\u30c3\u30af\u3092\u8907\u96d1\u306b\u3057\u3059\u304e\u306a\u3044<\/strong>: \u53ef\u8aad\u6027\u3068\u4fdd\u5b88\u6027\u3092\u7dad\u6301\u3059\u308b\u305f\u3081\u3001\u8907\u96d1\u306a\u6761\u4ef6\u306f\u5225\u306e\u30e1\u30bd\u30c3\u30c9\u306b\u5207\u308a\u51fa\u3059\u3053\u3068\u3092\u691c\u8a0e\u3057\u307e\u3057\u3087\u3046\u3002<\/li>\n\n\n\n<li><strong>\u53ef\u8aad\u6027\u3092\u91cd\u8996\u3059\u308b<\/strong>: \u6761\u4ef6\u4ed8\u304d\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u4f7f\u7528\u3059\u308b\u969b\u306f\u3001\u305d\u306e\u610f\u56f3\u304c\u660e\u78ba\u306b\u306a\u308b\u3088\u3046\u306b\u30b3\u30fc\u30c9\u3092\u66f8\u304d\u307e\u3057\u3087\u3046\u3002<\/li>\n\n\n\n<li><strong>\u904e\u5ea6\u306b\u6761\u4ef6\u4ed8\u304d\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u4f7f\u7528\u3057\u306a\u3044<\/strong>: \u591a\u7528\u3059\u308b\u3068\u3001\u30e2\u30c7\u30eb\u306e\u632f\u308b\u821e\u3044\u304c\u4e88\u6e2c\u3057\u3065\u3089\u304f\u306a\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002<\/li>\n\n\n\n<li><strong>\u6761\u4ef6\u30e1\u30bd\u30c3\u30c9\u306f\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8\u30e1\u30bd\u30c3\u30c9\u3068\u3057\u3066\u5b9a\u7fa9\u3059\u308b<\/strong>: \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u6761\u4ef6\u306e\u30ed\u30b8\u30c3\u30af\u306f\u30e2\u30c7\u30eb\u306e\u5185\u90e8\u5b9f\u88c5\u306e\u8a73\u7d30\u3067\u3042\u308a\u3001\u5916\u90e8\u304b\u3089\u76f4\u63a5\u30a2\u30af\u30bb\u30b9\u3055\u308c\u308b\u3079\u304d\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002<\/li>\n<\/ol>\n\n\n\n<p>\u6761\u4ef6\u4ed8\u304d\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u9069\u5207\u306b\u4f7f\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u8981\u4ef6\u306b\u67d4\u8edf\u306b\u5bfe\u5fdc\u3057\u3064\u3064\u3001\u30c7\u30fc\u30bf\u306e\u6574\u5408\u6027\u3092\u4fdd\u3064\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<br>\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u3055\u3089\u306b\u9ad8\u5ea6\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30c6\u30af\u30cb\u30c3\u30af\u3068\u3057\u3066\u3001\u30a2\u30bd\u30b7\u30a8\u30fc\u30b7\u30e7\u30f3\u3092\u8003\u616e\u3057\u305f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5\u65b9\u6cd5\u306b\u3064\u3044\u3066\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-29\">\u30a2\u30bd\u30b7\u30a8\u30fc\u30b7\u30e7\u30f3\u3092\u8003\u616e\u3057\u305f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5\u65b9\u6cd5<\/h2>\n\n\n\n<p>Ruby on Rails\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3067\u306f\u3001\u30e2\u30c7\u30eb\u9593\u306e\u30a2\u30bd\u30b7\u30a8\u30fc\u30b7\u30e7\u30f3\u3092\u9069\u5207\u306b\u7ba1\u7406\u3057\u3001\u95a2\u9023\u3059\u308b\u30c7\u30fc\u30bf\u306e\u6574\u5408\u6027\u3092\u4fdd\u3064\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002<br>\u3053\u3053\u3067\u306f\u3001\u30a2\u30bd\u30b7\u30a8\u30fc\u30b7\u30e7\u30f3\u3092\u8003\u616e\u3057\u305f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5\u65b9\u6cd5\u3068\u3001\u305d\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\u306b\u3064\u3044\u3066\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-30\">accepts_nested_attributes_for\u3068validates\u306e\u4f75\u7528\u30c6\u30af\u30cb\u30c3\u30af<\/h3>\n\n\n\n<p><code>accepts_nested_attributes_for<\/code>\u306f\u3001\u89aa\u30e2\u30c7\u30eb\u304b\u3089\u95a2\u9023\u3059\u308b\u5b50\u30e2\u30c7\u30eb\u306e\u5c5e\u6027\u3092\u66f4\u65b0\u3067\u304d\u308b\u3088\u3046\u306b\u3059\u308b\u30e1\u30bd\u30c3\u30c9\u3067\u3059\u3002<br>\u3053\u306e\u30e1\u30bd\u30c3\u30c9\u3068\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3001\u8907\u96d1\u306a\u30d5\u30a9\u30fc\u30e0\u306e\u51e6\u7406\u3084\u95a2\u9023\u30e2\u30c7\u30eb\u306e\u4e00\u62ec\u66f4\u65b0\u3092\u52b9\u7387\u7684\u306b\u884c\u3046\u3053\u3068\u304c\u3067\u304d\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=\"\">class Order &lt; ApplicationRecord\n  has_many :order_items\n  accepts_nested_attributes_for :order_items, allow_destroy: true, reject_if: :all_blank\n\n  validates_associated :order_items\n  validate :at_least_one_item\n\n  private\n\n  def at_least_one_item\n    if order_items.empty? || order_items.all? { |item| item.marked_for_destruction? }\n      errors.add(:base, \"\u6ce8\u6587\u306b\u306f\u6700\u4f4e1\u3064\u306e\u30a2\u30a4\u30c6\u30e0\u304c\u5fc5\u8981\u3067\u3059\")\n    end\n  end\nend\n\nclass OrderItem &lt; ApplicationRecord\n  belongs_to :order\n  validates :quantity, presence: true, numericality: { greater_than: 0 }\nend<\/pre>\n\n\n\n<div class=\"wp-block-sgb-message\"><div class=\"memo sng-shadow-0\" style=\"border-radius:0px;background-color:#ffebeb;color:#f88080\"><div class=\"memo_ttl dfont\"><span class=\"sng-box-msg__icon\" style=\"background:#f88080\"><i class=\"fas fa-exclamation\"><\/i><\/span><div class=\"sng-box-msg__title\">\u4e0a\u8a18\u624b\u6cd5\u306e\u6ce8\u610f\u70b9<\/div><\/div><div class=\"sng-box-msg__contents\">\n<ol class=\"wp-block-list\">\n<li><code>accepts_nested_attributes_for<\/code>\u3092\u4f7f\u7528\u3057\u3066\u3001<code>Order<\/code>\u30e2\u30c7\u30eb\u304b\u3089<code>OrderItem<\/code>\u306e\u5c5e\u6027\u3092\u66f4\u65b0\u3067\u304d\u308b\u3088\u3046\u306b\u3057\u3066\u3044\u307e\u3059\u3002<\/li>\n\n\n\n<li><code>validates_associated<\/code>\u3092\u4f7f\u3063\u3066\u3001\u95a2\u9023\u3059\u308b<code>order_items<\/code>\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u5b9f\u884c\u3057\u3066\u3044\u307e\u3059\u3002<\/li>\n\n\n\n<li>\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3<code>at_least_one_item<\/code>\u3092\u8ffd\u52a0\u3057\u3066\u3001\u6ce8\u6587\u306b\u6700\u4f4e1\u3064\u306e\u30a2\u30a4\u30c6\u30e0\u304c\u542b\u307e\u308c<\/li>\n\n\n\n<li>\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3<code>at_least_one_item<\/code>\u3092\u8ffd\u52a0\u3057\u3066\u3001\u6ce8\u6587\u306b\u6700\u4f4e1\u3064\u306e\u30a2\u30a4\u30c6\u30e0\u304c\u542b\u307e\u308c\u3066\u3044\u308b\u304b\u3092\u78ba\u8a8d\u3057\u3066\u3044\u307e\u3059\u3002<\/li>\n<\/ol>\n<\/div><\/div><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-31\">\u95a2\u9023\u30e2\u30c7\u30eb\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u5236\u5fa1\u3059\u308bbest\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-32\">1. <strong><code>validates_associated<\/code>\u306e\u4f7f\u7528<\/strong><\/h4>\n\n\n\n<p><code>validates_associated<\/code>\u30e1\u30bd\u30c3\u30c9\u3092\u4f7f\u7528\u3059\u308b\u3068\u3001\u95a2\u9023\u30e2\u30c7\u30eb\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u7c21\u5358\u306b\u5b9f\u884c\u3067\u304d\u307e\u3059\u3002<br>\u305f\u3060\u3057\u3001\u5faa\u74b0\u53c2\u7167\u306b\u6ce8\u610f\u304c\u5fc5\u8981\u3067\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=\"\">   class Author &lt; ApplicationRecord\n     has_many :books\n     validates_associated :books\n   end<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-33\">2. <strong>\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30e1\u30bd\u30c3\u30c9\u306e\u6d3b\u7528<\/strong><\/h4>\n\n\n\n<p>\u3088\u308a\u8907\u96d1\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30ed\u30b8\u30c3\u30af\u304c\u5fc5\u8981\u306a\u5834\u5408\u306f\u3001\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30e1\u30bd\u30c3\u30c9\u3092\u4f7f\u7528\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=\"\">   class Project &lt; ApplicationRecord\n     has_many :tasks\n     validate :check_total_task_duration\n\n     private\n\n     def check_total_task_duration\n       total_duration = tasks.sum(&amp;:duration)\n       if total_duration &gt; 100\n         errors.add(:base, \"\u30bf\u30b9\u30af\u306e\u5408\u8a08\u6642\u9593\u304c100\u6642\u9593\u3092\u8d85\u3048\u3066\u3044\u307e\u3059\")\n       end\n     end\n   end<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-34\">3. <strong>\u30b3\u30fc\u30eb\u30d0\u30c3\u30af\u306e\u4f7f\u7528<\/strong><\/h4>\n\n\n\n<p>\u95a2\u9023\u30e2\u30c7\u30eb\u306e\u72b6\u614b\u306b\u57fa\u3065\u3044\u3066\u89aa\u30e2\u30c7\u30eb\u306e\u5c5e\u6027\u3092\u66f4\u65b0\u3059\u308b\u5834\u5408\u306f\u3001\u30b3\u30fc\u30eb\u30d0\u30c3\u30af\u304c\u6709\u7528\u3067\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=\"\">   class Order &lt; ApplicationRecord\n     has_many :order_items\n     before_save :update_total_amount\n\n     private\n\n     def update_total_amount\n       self.total_amount = order_items.sum(&amp;:subtotal)\n     end\n   end<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-35\">\u30a2\u30bd\u30b7\u30a8\u30fc\u30b7\u30e7\u30f3\u3092\u8003\u616e\u3057\u305f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u30c6\u30b9\u30c8\u65b9\u6cd5<\/h3>\n\n\n\n<p>\u30a2\u30bd\u30b7\u30a8\u30fc\u30b7\u30e7\u30f3\u3092\u542b\u3080\u30e2\u30c7\u30eb\u306e\u30c6\u30b9\u30c8\u3067\u306f\u3001\u4ee5\u4e0b\u306e\u30dd\u30a4\u30f3\u30c8\u306b\u6ce8\u610f\u3057\u307e\u3057\u3087\u3046\uff1a<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-36\">1. \u95a2\u9023\u30e2\u30c7\u30eb\u3092\u542b\u3080\u30d5\u30a1\u30af\u30c8\u30ea\u3092\u4f5c\u6210\u3059\u308b<\/h4>\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=\"\">   FactoryBot.define do\n     factory :order do\n       # order attributes\n\n       trait :with_items do\n         after(:build) do |order|\n           order.order_items &lt;&lt; build(:order_item, order: order)\n         end\n       end\n     end\n   end<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-37\">2. \u30cd\u30b9\u30c8\u3057\u305f\u5c5e\u6027\u3067\u30e2\u30c7\u30eb\u3092\u4f5c\u6210\u30fb\u66f4\u65b0\u3059\u308b\u30c6\u30b9\u30c8\u3092\u66f8\u304f<\/h4>\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 Order, type: :model do\n     it \"creates an order with nested order items\" do\n       order_attributes = attributes_for(:order).merge(\n         order_items_attributes: [attributes_for(:order_item)]\n       )\n       expect {\n         Order.create(order_attributes)\n       }.to change(Order, :count).by(1).and change(OrderItem, :count).by(1)\n     end\n   end<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-38\">3. \u30a8\u30c3\u30b8\u30b1\u30fc\u30b9\u306e\u30c6\u30b9\u30c8<\/h4>\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 Order, type: :model do\n     it \"is invalid without any order items\" do\n       order = build(:order, order_items: [])\n       expect(order).to be_invalid\n       expect(order.errors[:base]).to include(\"\u6ce8\u6587\u306b\u306f\u6700\u4f4e1\u3064\u306e\u30a2\u30a4\u30c6\u30e0\u304c\u5fc5\u8981\u3067\u3059\")\n     end\n   end<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-39\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3068\u30b9\u30b1\u30fc\u30e9\u30d3\u30ea\u30c6\u30a3\u306e\u89b3\u70b9\u304b\u3089\u306e\u6ce8\u610f\u70b9<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-40\">1. <strong>N+1\u30af\u30a8\u30ea\u554f\u984c\u306b\u6ce8\u610f<\/strong><\/h4>\n\n\n\n<p>\u95a2\u9023\u30e2\u30c7\u30eb\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u884c\u3046\u969b\u3001\u4e0d\u5fc5\u8981\u306a\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30af\u30a8\u30ea\u304c\u767a\u751f\u3057\u3066\u3044\u306a\u3044\u304b\u6ce8\u610f\u3057\u307e\u3057\u3087\u3046\u3002<br>\u5fc5\u8981\u306b\u5fdc\u3058\u3066<code>includes<\/code>\u3084<code>eager_load<\/code>\u3092\u4f7f\u7528\u3057\u3066\u30af\u30a8\u30ea\u3092\u6700\u9069\u5316\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=\"\">   class Order &lt; ApplicationRecord\n     has_many :order_items\n     validate :check_items_availability\n\n     private\n\n     def check_items_availability\n       order_items.includes(:product).each do |item|\n         unless item.product.available?\n           errors.add(:base, \"\u5546\u54c1\u300c#{item.product.name}\u300d\u306f\u73fe\u5728\u5229\u7528\u3067\u304d\u307e\u305b\u3093\")\n         end\n       end\n     end\n   end<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-41\">2. <strong>\u5927\u91cf\u306e\u95a2\u9023\u30ec\u30b3\u30fc\u30c9\u304c\u3042\u308b\u5834\u5408\u306f\u30d0\u30c3\u30c1\u51e6\u7406\u3092\u691c\u8a0e<\/strong><\/h4>\n\n\n\n<p>\u95a2\u9023\u30ec\u30b3\u30fc\u30c9\u304c\u591a\u3044\u5834\u5408\u3001\u5168\u3066\u306e\u30ec\u30b3\u30fc\u30c9\u3092\u4e00\u5ea6\u306b\u30e1\u30e2\u30ea\u306b\u8aad\u307f\u8fbc\u3080\u3068\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u554f\u984c\u304c\u767a\u751f\u3059\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002<br>\u3053\u306e\u3088\u3046\u306a\u5834\u5408\u306f\u3001\u30d0\u30c3\u30c1\u51e6\u7406\u3092\u691c\u8a0e\u3057\u307e\u3057\u3087\u3046\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=\"\">   class Order &lt; ApplicationRecord\n     has_many :order_items\n     validate :check_items_total_batch\n\n     private\n\n     def check_items_total_batch\n       total = 0\n       order_items.find_in_batches(batch_size: 100) do |batch|\n         total += batch.sum(&amp;:subtotal)\n       end\n       if total &gt; 1000000\n         errors.add(:base, \"\u6ce8\u6587\u7dcf\u984d\u304c100\u4e07\u5186\u3092\u8d85\u3048\u3066\u3044\u307e\u3059\")\n       end\n     end\n   end<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-42\">3. <strong>\u5fc5\u8981\u306b\u5fdc\u3058\u3066eager loading\u3092\u4f7f\u7528<\/strong><\/h4>\n\n\n\n<p>\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u6642\u306b\u95a2\u9023\u30e2\u30c7\u30eb\u306e\u5c5e\u6027\u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b\u5834\u5408\u306f\u3001eager loading\u3092\u4f7f\u7528\u3057\u3066\u30af\u30a8\u30ea\u3092\u6700\u9069\u5316\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=\"\">   class Author &lt; ApplicationRecord\n     has_many :books\n     validate :check_total_pages\n\n     private\n\n     def check_total_pages\n       total_pages = books.eager_load(:pages).sum('pages.count')\n       if total_pages &gt; 10000\n         errors.add(:base, \"\u8457\u8005\u306e\u5168\u66f8\u7c4d\u306e\u30da\u30fc\u30b8\u6570\u304c10000\u30da\u30fc\u30b8\u3092\u8d85\u3048\u3066\u3044\u307e\u3059\")\n       end\n     end\n   end<\/pre>\n\n\n\n<p>\u30a2\u30bd\u30b7\u30a8\u30fc\u30b7\u30e7\u30f3\u3092\u8003\u616e\u3057\u305f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u9069\u5207\u306b\u5b9f\u88c5\u3059\u308b\u3053\u3068\u3067\u3001\u30c7\u30fc\u30bf\u306e\u6574\u5408\u6027\u3092\u4fdd\u3061\u3064\u3064\u3001\u8907\u96d1\u306a\u30d3\u30b8\u30cd\u30b9\u30ed\u30b8\u30c3\u30af\u3092\u52b9\u7387\u7684\u306b\u8868\u73fe\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<br>\u305f\u3060\u3057\u3001\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3068\u30b9\u30b1\u30fc\u30e9\u30d3\u30ea\u30c6\u30a3\u306b\u3082\u5341\u5206\u6ce8\u610f\u3092\u6255\u3044\u3001\u5fc5\u8981\u306b\u5fdc\u3058\u3066\u6700\u9069\u5316\u3092\u884c\u3046\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002<\/p>\n\n\n\n<p>\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u624b\u6cd5\u306b\u3064\u3044\u3066\u3001\u3088\u308a\u8a73\u3057\u304f\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-sgb-headings sgb-heading\" id=\"i-43\"><span class=\"sgb-heading__inner sgb-heading--type1 with-icon\" style=\"background-color:transparent;border-color:transparent;font-size:1.2em\"><i class=\"fa fa-check\" style=\"color:var(--wp--preset--color--sango-main)\"><\/i><span class=\"sgb-heading__text\" style=\"color:#333\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3092\u8003\u616e\u3057\u305f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u6700\u9069\u5316\u624b\u6cd5<\/span><\/span><\/h2>\n\n\n\n<p>\u5927\u898f\u6a21\u306a\u30c7\u30fc\u30bf\u30bb\u30c3\u30c8\u3084\u9ad8\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3067\u306f\u3001\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u304c\u5168\u4f53\u306e\u30ec\u30b9\u30dd\u30f3\u30b9\u6642\u9593\u306b\u5927\u304d\u304f\u5f71\u97ff\u3057\u307e\u3059\u3002<br>\u3053\u3053\u3067\u306f\u3001Ruby on Rails\u306b\u304a\u3051\u308b\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u624b\u6cd5\u306b\u3064\u3044\u3066\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-44\">\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30ec\u30d9\u30eb\u3067\u306e\u5236\u7d04\u3068\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30ec\u30d9\u30eb\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u4f7f\u3044\u5206\u3051<\/h3>\n\n\n\n<p>\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u52b9\u7387\u7684\u306b\u884c\u3046\u306b\u306f\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30ec\u30d9\u30eb\u306e\u5236\u7d04\u3068\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30ec\u30d9\u30eb\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u9069\u5207\u306b\u4f7f\u3044\u5206\u3051\u308b\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-45\">1. <strong>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30ec\u30d9\u30eb\u306e\u5236\u7d04<\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u4e00\u610f\u6027\u5236\u7d04\u3001NOT NULL\u5236\u7d04\u306a\u3069\u306e\u57fa\u672c\u7684\u306a\u30c7\u30fc\u30bf\u6574\u5408\u6027\u30c1\u30a7\u30c3\u30af<\/li>\n\n\n\n<li>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u304c\u91cd\u8981\u306a\u5834\u5408\u3084\u3001\u8907\u6570\u306e\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u304c\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u5171\u6709\u3057\u3066\u3044\u308b\u5834\u5408\u306b\u6709\u52b9<\/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=\"\">   # \u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u30d5\u30a1\u30a4\u30eb\u3067\u306e\u4f8b\n   add_index :users, :email, unique: true\n   change_column_null :users, :name, false<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-46\">2. <strong>\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30ec\u30d9\u30eb\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3<\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u8907\u96d1\u306a\u30d3\u30b8\u30cd\u30b9\u30ed\u30b8\u30c3\u30af\u3084\u6761\u4ef6\u4ed8\u304d\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3<\/li>\n\n\n\n<li>\u30e6\u30fc\u30b6\u30fc\u30d5\u30ec\u30f3\u30c9\u30ea\u30fc\u306a\u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\u304c\u5fc5\u8981\u306a\u5834\u5408\u306b\u9069\u3057\u3066\u3044\u308b<\/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     validates :email, uniqueness: true, format: { with: \/\\A[\\w+\\-.]+@[a-z\\d\\-]+(\\.[a-z\\d\\-]+)*\\.[a-z]+\\z\/i }\n     validates :name, presence: true\n   end<\/pre>\n\n\n\n<p>\u91cd\u8981\u306a\u30c7\u30fc\u30bf\u6574\u5408\u6027\u306f\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u5236\u7d04\u3067\u3001\u67d4\u8edf\u6027\u304c\u5fc5\u8981\u306a\u691c\u8a3c\u306f\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30ec\u30d9\u30eb\u3067\u884c\u3046\u3068\u3044\u3046\u30d0\u30e9\u30f3\u30b9\u3092\u53d6\u308b\u3053\u3068\u3067\u3001\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3068\u6a5f\u80fd\u6027\u306e\u4e21\u7acb\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-47\">\u30d0\u30c3\u30c1\u51e6\u7406\u6642\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30b9\u30ad\u30c3\u30d7\u306b\u3088\u308b\u51e6\u7406\u901f\u5ea6\u306e\u5411\u4e0a<\/h3>\n\n\n\n<p>\u5927\u91cf\u306e\u30ec\u30b3\u30fc\u30c9\u3092\u4e00\u62ec\u3067\u51e6\u7406\u3059\u308b\u969b\u3001\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u30b9\u30ad\u30c3\u30d7\u3059\u308b\u3053\u3068\u3067\u51e6\u7406\u901f\u5ea6\u3092\u5927\u5e45\u306b\u5411\u4e0a\u3055\u305b\u308b\u3053\u3068\u304c\u3067\u304d\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=\"\"># \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u30b9\u30ad\u30c3\u30d7\u3057\u3066\u4fdd\u5b58\nUser.find_each do |user|\n  user.save(validate: false)\nend\n\n# update_all\u3092\u4f7f\u7528\u3057\u305f\u4e00\u62ec\u66f4\u65b0\nUser.where(active: true).update_all(last_login_at: Time.current)\n\n# insert_all\u3092\u4f7f\u7528\u3057\u305f\u4e00\u62ec\u633f\u5165\nUser.insert_all([\n  { name: 'Alice', email: 'alice@example.com' },\n  { name: 'Bob', email: 'bob@example.com' }\n])<\/pre>\n\n\n\n<p>\u305f\u3060\u3057\u3001\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u30b9\u30ad\u30c3\u30d7\u3059\u308b\u3053\u3068\u3067\u30c7\u30fc\u30bf\u306e\u6574\u5408\u6027\u304c\u640d\u306a\u308f\u308c\u308b\u53ef\u80fd\u6027\u304c\u3042\u308b\u305f\u3081\u3001\u614e\u91cd\u306b\u4f7f\u7528\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-48\">\u30e1\u30e2\u30ea\u4f7f\u7528\u91cf\u3092\u6291\u3048\u308b\u305f\u3081\u306e\u30c6\u30af\u30cb\u30c3\u30af<\/h3>\n\n\n\n<p>\u5927\u91cf\u306e\u30ec\u30b3\u30fc\u30c9\u3092\u51e6\u7406\u3059\u308b\u969b\u3001\u30e1\u30e2\u30ea\u4f7f\u7528\u91cf\u3092\u6291\u3048\u308b\u3053\u3068\u3082\u91cd\u8981\u3067\u3059\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-49\">1. <strong><code>find_each<\/code>\u3068<code>find_in_batches<\/code>\u306e\u4f7f\u7528<\/strong><\/h4>\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.find_in_batches(batch_size: 1000) do |group|\n     group.each { |user| user.process_some_data }\n   end<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-50\">2. <strong>\u5fc5\u8981\u306a\u5c5e\u6027\u306e\u307f\u3092\u9078\u629e\u3057\u3066\u30ed\u30fc\u30c9<\/strong><\/h4>\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.select(:id, :email).find_each do |user|\n     # \u51e6\u7406\n   end<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-51\">3. <strong>\u30ab\u30a6\u30f3\u30bf\u30fc\u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u5229\u7528<\/strong><\/h4>\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 :posts\n     has_many :comments\n   end\n\n   # \u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3067\u30ab\u30a6\u30f3\u30bf\u30fc\u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u30ab\u30e9\u30e0\u3092\u8ffd\u52a0\n   add_column :users, :posts_count, :integer, default: 0\n   add_column :users, :comments_count, :integer, default: 0<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-52\">\u975e\u540c\u671f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5<\/h3>\n\n\n\n<p>\u6642\u9593\u306e\u304b\u304b\u308b\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\uff08\u4f8b\uff1a\u5916\u90e8API\u3068\u306e\u9023\u643a\uff09\u306f\u3001\u975e\u540c\u671f\u3067\u5b9f\u884c\u3059\u308b\u3053\u3068\u3067\u30e6\u30fc\u30b6\u30fc\u4f53\u9a13\u3092\u5411\u4e0a\u3055\u305b\u308b\u3053\u3068\u304c\u3067\u304d\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=\"\">class User &lt; ApplicationRecord\n  after_create :async_validate_email\n\n  private\n\n  def async_validate_email\n    ValidateEmailJob.perform_later(self)\n  end\nend\n\nclass ValidateEmailJob &lt; ApplicationJob\n  def perform(user)\n    result = ExternalEmailValidator.validate(user.email)\n    if result.valid?\n      user.update(email_validated: true)\n    else\n      user.update(email_validated: false)\n      UserMailer.invalid_email(user).deliver_later\n    end\n  end\nend<\/pre>\n\n\n\n<p>\u3053\u306e\u4f8b\u3067\u306f\u3001\u30e6\u30fc\u30b6\u30fc\u4f5c\u6210\u5f8c\u306b\u975e\u540c\u671f\u30b8\u30e7\u30d6\u3092\u4f7f\u7528\u3057\u3066\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u306e\u691c\u8a3c\u3092\u884c\u3063\u3066\u3044\u307e\u3059\u3002<br>\u3053\u308c\u306b\u3088\u308a\u3001\u6642\u9593\u306e\u304b\u304b\u308b\u51e6\u7406\u3092\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u3067\u5b9f\u884c\u3057\u3001\u30e6\u30fc\u30b6\u30fc\u306e\u5f85\u3061\u6642\u9593\u3092\u77ed\u7e2e\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-53\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u306e\u5177\u4f53\u7684\u306a\u5b9f\u88c5\u4f8b\u3068\u30d9\u30f3\u30c1\u30de\u30fc\u30af\u7d50\u679c<\/h3>\n\n\n\n<p>\u4ee5\u4e0b\u306f\u3001\u5927\u91cf\u306e\u30e6\u30fc\u30b6\u30fc\u30c7\u30fc\u30bf\u3092\u51e6\u7406\u3059\u308b\u969b\u306e\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u4f8b\u3067\u3059\u3002<\/p>\n\n\n\n<p>\u6700\u9069\u5316\u524d<\/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=\"\">users = User.all\nusers.each { |user| user.validate! }<\/pre>\n\n\n\n<p>\u6700\u9069\u5316\u5f8c<\/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.find_in_batches(batch_size: 1000) do |group|\n  group.each { |user| user.validate! }\nend<\/pre>\n\n\n\n<p>\u30d9\u30f3\u30c1\u30de\u30fc\u30af\u7d50\u679c\uff0810\u4e07\u30ec\u30b3\u30fc\u30c9\u306e\u51e6\u7406\u6642\uff09<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u6700\u9069\u5316\u524d: 45.2\u79d2<\/li>\n\n\n\n<li>\u6700\u9069\u5316\u5f8c: 12.8\u79d2<\/li>\n<\/ul>\n\n\n\n<p>\u3053\u306e\u6700\u9069\u5316\u306b\u3088\u308a\u3001<strong>\u51e6\u7406\u6642\u9593\u3092\u7d0472%\u524a\u6e1b<\/strong>\u3067\u304d\u307e\u3057\u305f\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-54\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u6642\u306e\u6ce8\u610f\u70b9\u3068\u30c8\u30ec\u30fc\u30c9\u30aa\u30d5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u904e\u5ea6\u306a\u6700\u9069\u5316\u306b\u3088\u308b\u53ef\u8aad\u6027\u306e\u4f4e\u4e0b\u306b\u6ce8\u610f<\/strong><br>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3092\u8ffd\u6c42\u3059\u308b\u3042\u307e\u308a\u3001\u30b3\u30fc\u30c9\u306e\u53ef\u8aad\u6027\u304c\u4f4e\u4e0b\u3057\u306a\u3044\u3088\u3046\u6ce8\u610f\u304c\u5fc5\u8981\u3067\u3059\u3002<br>\u9069\u5207\u306a\u30b3\u30e1\u30f3\u30c8\u3084\u8aac\u660e\u3092\u8ffd\u52a0\u3057\u3001\u30c1\u30fc\u30e0\u30e1\u30f3\u30d0\u30fc\u304c\u7406\u89e3\u3057\u3084\u3059\u3044\u30b3\u30fc\u30c9\u3092\u7dad\u6301\u3057\u307e\u3057\u3087\u3046\u3002<\/li>\n\n\n\n<li><strong>\u30c6\u30b9\u30c8\u5bb9\u6613\u6027\u3068\u306e\u30d0\u30e9\u30f3\u30b9<\/strong><br>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u306b\u3088\u3063\u3066\u30c6\u30b9\u30c8\u304c\u8907\u96d1\u306b\u306a\u3063\u305f\u308a\u3001\u30ab\u30d0\u30ec\u30c3\u30b8\u304c\u4f4e\u4e0b\u3057\u305f\u308a\u3057\u306a\u3044\u3088\u3046\u6ce8\u610f\u304c\u5fc5\u8981\u3067\u3059\u3002<br>\u6700\u9069\u5316\u5f8c\u3082\u30c6\u30b9\u30c8\u304c\u5bb9\u6613\u306b\u66f8\u3051\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u307e\u3057\u3087\u3046\u3002<\/li>\n\n\n\n<li><strong>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3068\u30c7\u30fc\u30bf\u6574\u5408\u6027\u306e\u30c8\u30ec\u30fc\u30c9\u30aa\u30d5<\/strong><br>\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u30b9\u30ad\u30c3\u30d7\u3057\u305f\u308a\u3001\u975e\u540c\u671f\u3067\u5b9f\u884c\u3057\u305f\u308a\u3059\u308b\u5834\u5408\u3001\u30c7\u30fc\u30bf\u306e\u6574\u5408\u6027\u304c\u4e00\u6642\u7684\u306b\u640d\u306a\u308f\u308c\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002<br>\u3053\u306e\u30c8\u30ec\u30fc\u30c9\u30aa\u30d5\u3092\u5341\u5206\u306b\u7406\u89e3\u3057\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u8981\u4ef6\u306b\u9069\u3057\u305f\u65b9\u6cd5\u3092\u9078\u629e\u3059\u308b\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002<\/li>\n\n\n\n<li><strong>\u9069\u5207\u306a\u30e2\u30cb\u30bf\u30ea\u30f3\u30b0\u3068\u30d7\u30ed\u30d5\u30a1\u30a4\u30ea\u30f3\u30b0<\/strong><br>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u3092\u884c\u3046\u969b\u306f\u3001\u5b9f\u969b\u306e\u6539\u5584\u52b9\u679c\u3092\u6e2c\u5b9a\u3059\u308b\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002<br>New Relic\u3001Scout\u3001Skylight \u306a\u3069\u306e\u30c4\u30fc\u30eb\u3092\u4f7f\u7528\u3057\u3066\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3092\u7d99\u7d9a\u7684\u306b\u30e2\u30cb\u30bf\u30ea\u30f3\u30b0\u3057\u307e\u3057\u3087\u3046\u3002<\/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=\"\"># \u4f8b: \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u884c\u6642\u9593\u3092\u8a08\u6e2c\nrequire 'benchmark'\n\ntime = Benchmark.measure do\n  User.find_in_batches(batch_size: 1000) do |group|\n    group.each { |user| user.validate! }\n  end\nend\n\nputs \"Validation execution time: #{time.real} seconds\"<\/pre>\n\n\n\n<p>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3092\u8003\u616e\u3057\u305f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u6700\u9069\u5316\u306f\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u898f\u6a21\u304c\u5927\u304d\u304f\u306a\u308b\u306b\u3064\u308c\u3066\u307e\u3059\u307e\u3059\u91cd\u8981\u306b\u306a\u308a\u307e\u3059\u3002<br>\u305f\u3060\u3057\u3001\u6700\u9069\u5316\u3092\u884c\u3046\u969b\u306f\u5e38\u306b\u30c8\u30ec\u30fc\u30c9\u30aa\u30d5\u3092\u610f\u8b58\u3057\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u8981\u4ef6\u3068\u30d0\u30e9\u30f3\u30b9\u3092\u53d6\u308a\u306a\u304c\u3089\u9032\u3081\u308b\u3053\u3068\u304c\u5927\u5207\u3067\u3059\u3002<\/p>\n\n\n\n<p>\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3092\u5f37\u5316\u3059\u308b\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30c6\u30af\u30cb\u30c3\u30af\u306b\u3064\u3044\u3066\u89e3\u8aac\u3057\u307e\u3059\u3002<br>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3068\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u306e\u4e21\u7acb\u306f\u3001\u5805\u7262\u306a\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u958b\u767a\u306b\u304a\u3044\u3066\u975e\u5e38\u306b\u91cd\u8981\u306a\u89b3\u70b9\u3068\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-55\">\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3092\u5f37\u5316\u3059\u308b\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30c6\u30af\u30cb\u30c3\u30af<\/h2>\n\n\n\n<p>\u9069\u5207\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306f\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3092\u5f37\u5316\u3057\u3001\u69d8\u3005\u306a\u653b\u6483\u304b\u3089\u4fdd\u8b77\u3059\u308b\u91cd\u8981\u306a\u5f79\u5272\u3092\u679c\u305f\u3057\u307e\u3059\u3002<br>\u3053\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001Ruby on Rails\u306b\u304a\u3051\u308b\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3092\u8003\u616e\u3057\u305f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30c6\u30af\u30cb\u30c3\u30af\u306b\u3064\u3044\u3066\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-56\">Strong Parameters\u3068\u306e\u9023\u643a\u306b\u3088\u308b\u30de\u30b9\u30a2\u30b5\u30a4\u30f3\u30e1\u30f3\u30c8\u5bfe\u7b56<\/h3>\n\n\n\n<p>\u30de\u30b9\u30a2\u30b5\u30a4\u30f3\u30e1\u30f3\u30c8\u8106\u5f31\u6027\u306f\u3001\u653b\u6483\u8005\u304c\u4e88\u671f\u3057\u306a\u3044\u30d1\u30e9\u30e1\u30fc\u30bf\u3092\u9001\u4fe1\u3059\u308b\u3053\u3068\u3067\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u5185\u306e\u91cd\u8981\u306a\u5c5e\u6027\u3092\u5909\u66f4\u3067\u304d\u3066\u3057\u307e\u3046\u554f\u984c\u3067\u3059\u3002<br>Strong Parameters\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u3053\u306e\u8106\u5f31\u6027\u3092\u9632\u3050\u3053\u3068\u304c\u3067\u304d\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=\"\">class UsersController &lt; ApplicationController\n  def create\n    @user = User.new(user_params)\n    if @user.save\n      redirect_to @user, notice: 'User was successfully created.'\n    else\n      render :new\n    end\n  end\n\n  private\n\n  def user_params\n    params.require(:user).permit(:name, :email, :age)\n  end\nend<\/pre>\n\n\n\n<p>\u3053\u306e\u4f8b\u3067\u306f\u3001<code>user_params<\/code>\u30e1\u30bd\u30c3\u30c9\u3067\u8a31\u53ef\u3055\u308c\u305f\u30d1\u30e9\u30e1\u30fc\u30bf\u306e\u307f\u3092\u53d7\u3051\u5165\u308c\u308b\u3053\u3068\u3067\u3001\u4e0d\u6b63\u306a\u30d1\u30e9\u30e1\u30fc\u30bf\u306b\u3088\u308b\u653b\u6483\u3092\u9632\u3044\u3067\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-57\">\u30b5\u30cb\u30bf\u30a4\u30ba\u3068\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u7d44\u307f\u5408\u308f\u305b\u305fXSS\u5bfe\u7b56\u306e\u5b9f\u88c5<\/h3>\n\n\n\n<p>\u30af\u30ed\u30b9\u30b5\u30a4\u30c8\u30b9\u30af\u30ea\u30d7\u30c6\u30a3\u30f3\u30b0\uff08XSS\uff09\u653b\u6483\u3092\u9632\u3050\u306b\u306f\u3001\u30e6\u30fc\u30b6\u30fc\u5165\u529b\u3092\u30b5\u30cb\u30bf\u30a4\u30ba\u3057\u3001\u5371\u967a\u306aHTML\u30bf\u30b0\u3084JavaScript\u3092\u9664\u53bb\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\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=\"\">class Comment &lt; ApplicationRecord\n  include ActionView::Helpers::SanitizeHelper\n\n  before_validation :sanitize_content\n  validates :content, presence: true, length: { maximum: 1000 }\n\n  private\n\n  def sanitize_content\n    self.content = sanitize(content, tags: %w(p br))\n  end\nend<\/pre>\n\n\n\n<p>\u3053\u306e\u4f8b\u3067\u306f\u3001<code>before_validation<\/code>\u30b3\u30fc\u30eb\u30d0\u30c3\u30af\u3092\u4f7f\u7528\u3057\u3066\u3001\u30b3\u30f3\u30c6\u30f3\u30c4\u3092\u30b5\u30cb\u30bf\u30a4\u30ba\u3057\u3066\u3044\u307e\u3059\u3002<br>\u307e\u305f\u3001<code>sanitize<\/code>\u30e1\u30bd\u30c3\u30c9\u3067\u8a31\u53ef\u3059\u308bHTML\u30bf\u30b0\u3092\u660e\u793a\u7684\u306b\u6307\u5b9a\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-58\">SQL Injection\u3092\u9632\u3050\u305f\u3081\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30c6\u30af\u30cb\u30c3\u30af<\/h3>\n\n\n\n<p>SQL Injection\u306f\u3001\u60aa\u610f\u306e\u3042\u308bSQL\u30b3\u30fc\u30c9\u3092\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306b\u633f\u5165\u3059\u308b\u653b\u6483\u624b\u6cd5\u3067\u3059\u3002<br>\u3053\u308c\u3092\u9632\u3050\u306b\u306f\u3001\u30d7\u30ec\u30fc\u30b9\u30db\u30eb\u30c0\u3084\u30b9\u30b3\u30fc\u30d7\u3092\u4f7f\u7528\u3057\u3066\u30af\u30a8\u30ea\u3092\u69cb\u7bc9\u3059\u308b\u3053\u3068\u304c\u91cd\u8981\u3067\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=\"\">class User &lt; ApplicationRecord\n  # \u60aa\u3044\u4f8b\uff08SQL Injection\u306e\u5371\u967a\u6027\u3042\u308a\uff09\n  # def self.search(name)\n  #   where(\"name = '#{name}'\")\n  # end\n\n  # \u826f\u3044\u4f8b\uff08\u30d7\u30ec\u30fc\u30b9\u30db\u30eb\u30c0\u3092\u4f7f\u7528\uff09\n  def self.search(name)\n    where(\"name = ?\", name)\n  end\n\n  # \u3055\u3089\u306b\u826f\u3044\u4f8b\uff08\u30b9\u30b3\u30fc\u30d7\u3092\u6d3b\u7528\uff09\n  scope :with_name, -&gt;(name) { where(name: name) }\nend<\/pre>\n\n\n\n<p>\u30d7\u30ec\u30fc\u30b9\u30db\u30eb\u30c0\u3084\u30b9\u30b3\u30fc\u30d7\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u3067\u3001SQL\u30af\u30a8\u30ea\u304c\u5b89\u5168\u306b\u69cb\u7bc9\u3055\u308c\u3001SQL Injection\u306e\u30ea\u30b9\u30af\u3092\u8efd\u6e1b\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-59\">\u6a5f\u5bc6\u60c5\u5831\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3068\u4fdd\u8b77<\/h3>\n\n\n\n<p>\u6a5f\u5bc6\u60c5\u5831\uff08\u30d1\u30b9\u30ef\u30fc\u30c9\u3001\u30af\u30ec\u30b8\u30c3\u30c8\u30ab\u30fc\u30c9\u756a\u53f7\u3001\u793e\u4f1a\u4fdd\u969c\u756a\u53f7\u306a\u3069\uff09\u3092\u6271\u3046\u969b\u306f\u3001\u7279\u5225\u306a\u6ce8\u610f\u304c\u5fc5\u8981\u3067\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=\"\">class User &lt; ApplicationRecord\n  attr_encrypted :social_security_number, key: ENV['ENCRYPTION_KEY']\n\n  validates :social_security_number, format: { with: \/\\A\\d{3}-\\d{2}-\\d{4}\\z\/, message: \"must be in the format XXX-XX-XXXX\" }\n\n  def masked_ssn\n    \"XXX-XX-#{social_security_number.last(4)}\"\n  end\nend<\/pre>\n\n\n\n<p>\u3053\u306e\u4f8b\u3067\u306f\u3001<code>attr_encrypted<\/code>gem\u3092\u4f7f\u7528\u3057\u3066\u793e\u4f1a\u4fdd\u969c\u756a\u53f7\u3092\u6697\u53f7\u5316\u3057\u3066\u3044\u307e\u3059\u3002<br>\u307e\u305f\u3001\u30de\u30b9\u30ad\u30f3\u30b0\u3055\u308c\u305f\u7248\u3092\u8868\u793a\u3059\u308b\u30e1\u30bd\u30c3\u30c9\u3082\u63d0\u4f9b\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-60\">\u30bb\u30ad\u30e5\u30a2\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5\u4f8b\u3068\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-61\">1. <strong>\u5165\u529b\u5024\u306e\u9577\u3055\u5236\u9650<\/strong><\/h4>\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=\"\">   validates :username, length: { maximum: 50 }\n   validates :bio, length: { maximum: 1000 }<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-62\">2. <strong>\u9069\u5207\u306a\u6b63\u898f\u8868\u73fe\u306e\u4f7f\u7528<\/strong><\/h4>\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=\"\">   VALID_EMAIL_REGEX = \/\\A[\\w+\\-.]+@[a-z\\d\\-]+(\\.[a-z\\d\\-]+)*\\.[a-z]+\\z\/i\n   validates :email, format: { with: VALID_EMAIL_REGEX }<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-63\">3. <strong>\u30db\u30ef\u30a4\u30c8\u30ea\u30b9\u30c8\u30a2\u30d7\u30ed\u30fc\u30c1\u306e\u63a1\u7528<\/strong><\/h4>\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=\"\">   validates :status, inclusion: { in: %w(pending approved rejected) }<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-64\">4. <strong>\u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\u306e\u9069\u5207\u306a\u8868\u793a<\/strong><\/h4>\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=\"\">   validates :password, presence: { message: \"\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\" },\n                        length: { minimum: 8, message: \"\u306f8\u6587\u5b57\u4ee5\u4e0a\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\" }<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-65\">\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u95a2\u9023\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u30c6\u30b9\u30c8\u3059\u308b\u65b9\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30da\u30cd\u30c8\u30ec\u30fc\u30b7\u30e7\u30f3\u30c6\u30b9\u30c8\u306e\u5b9f\u65bd<\/strong><br>\u5b9a\u671f\u7684\u306b\u30da\u30cd\u30c8\u30ec\u30fc\u30b7\u30e7\u30f3\u30c6\u30b9\u30c8\u3092\u884c\u3044\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u8106\u5f31\u6027\u3092\u6d17\u3044\u51fa\u3057\u307e\u3059\u3002<\/li>\n\n\n\n<li><strong>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30b9\u30ad\u30e3\u30ca\u30fc\u306e\u4f7f\u7528<\/strong><br>Brakeman \u306a\u3069\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30b9\u30ad\u30e3\u30ca\u30fc\u3092\u4f7f\u7528\u3057\u3066\u3001\u6f5c\u5728\u7684\u306a\u8106\u5f31\u6027\u3092\u81ea\u52d5\u7684\u306b\u691c\u51fa\u3057\u307e\u3059\u3002<\/li>\n\n\n\n<li><strong>\u30a8\u30c3\u30b8\u30b1\u30fc\u30b9\u306e\u30c6\u30b9\u30c8<\/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=\"\">   RSpec.describe User, type: :model do\n     it \"rejects overly long usernames\" do\n       user = build(:user, username: \"a\" * 51)\n       expect(user).to be_invalid\n     end\n\n     it \"sanitizes HTML in the bio\" do\n       user = create(:user, bio: \"&lt;script&gt;alert('XSS')&lt;\/script&gt;\")\n       expect(user.bio).not_to include(\"&lt;script&gt;\")\n     end\n   end<\/pre>\n\n\n\n<p>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3092\u8003\u616e\u3057\u305f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u5b9f\u88c5\u3059\u308b\u3053\u3068\u3067\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u5805\u7262\u6027\u304c\u5927\u5e45\u306b\u5411\u4e0a\u3057\u307e\u3059\u3002<br>\u305f\u3060\u3057\u3001\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u306f\u5e38\u306b\u9032\u5316\u3059\u308b\u5206\u91ce\u3067\u3042\u308a\u3001\u65b0\u305f\u306a\u8105\u5a01\u306b\u5bfe\u5fdc\u3059\u308b\u305f\u3081\u306b\u7d99\u7d9a\u7684\u306a\u6ce8\u610f\u3068\u66f4\u65b0\u304c\u5fc5\u8981\u3067\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-66\">\u8ffd\u52a0\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5f37\u5316\u30c6\u30af\u30cb\u30c3\u30af<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-67\">1. <strong>CSRF\uff08\u30af\u30ed\u30b9\u30b5\u30a4\u30c8\u30ea\u30af\u30a8\u30b9\u30c8\u30d5\u30a9\u30fc\u30b8\u30a7\u30ea\uff09\u5bfe\u7b56<\/strong><\/h4>\n\n\n\n<p>Ruby on Rails\u306b\u306f\u3001CSRF\u5bfe\u7b56\u304c\u7d44\u307f\u8fbc\u307e\u308c\u3066\u3044\u307e\u3059\u304c\u3001\u9069\u5207\u306b\u4f7f\u7528\u3059\u308b\u3053\u3068\u304c\u91cd\u8981\u3067\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=\"\">   class ApplicationController &lt; ActionController::Base\n     protect_from_forgery with: :exception\n   end<\/pre>\n\n\n\n<p>\u30d5\u30a9\u30fc\u30e0\u306b\u306f\u81ea\u52d5\u7684\u306bCSRF\u30c8\u30fc\u30af\u30f3\u304c\u542b\u307e\u308c\u307e\u3059\u304c\u3001JavaScript\u3092\u4f7f\u7528\u3059\u308b\u5834\u5408\u306f\u660e\u793a\u7684\u306b\u8ffd\u52a0\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\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=\"\">   &lt;%= csrf_meta_tags %&gt;<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-68\">2. <strong>\u30bb\u30c3\u30b7\u30e7\u30f3\u7ba1\u7406\u306e\u5f37\u5316<\/strong><\/h4>\n\n\n\n<p>\u30bb\u30c3\u30b7\u30e7\u30f3\u30cf\u30a4\u30b8\u30e3\u30c3\u30af\u3092\u9632\u3050\u305f\u3081\u306b\u3001\u30bb\u30c3\u30b7\u30e7\u30f3ID\u3092\u5b9a\u671f\u7684\u306b\u518d\u751f\u6210\u3059\u308b\u3053\u3068\u304c\u63a8\u5968\u3055\u308c\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=\"\">   class ApplicationController &lt; ActionController::Base\n     before_action :regenerate_session_id\n\n     private\n\n     def regenerate_session_id\n       if session[:last_regenerated_at].nil? || session[:last_regenerated_at] &lt; 1.hour.ago\n         session.regenerate\n         session[:last_regenerated_at] = Time.current\n       end\n     end\n   end<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-69\">3. <strong>\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u5f37\u5ea6\u30c1\u30a7\u30c3\u30af<\/strong><\/h4>\n\n\n\n<p>\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u5f37\u5ea6\u3092\u78ba\u4fdd\u3059\u308b\u305f\u3081\u306b\u3001\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30bf\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u304c\u3067\u304d\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=\"\">   class PasswordStrengthValidator &lt; ActiveModel::EachValidator\n     def validate_each(record, attribute, value)\n       unless value =~ \/^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&amp;])[A-Za-z\\d@$!%*?&amp;]{8,}$\/\n         record.errors.add attribute, (options[:message] || \"\u306f\u5c11\u306a\u304f\u3068\u30828\u6587\u5b57\u3067\u3001\u5927\u6587\u5b57\u3001\u5c0f\u6587\u5b57\u3001\u6570\u5b57\u3001\u7279\u6b8a\u6587\u5b57\u3092\u542b\u3080\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\")\n       end\n     end\n   end\n\n   class User &lt; ApplicationRecord\n     validates :password, password_strength: true\n   end<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-70\">4. <strong>\u30ec\u30fc\u30c8\u5236\u9650\u306e\u5b9f\u88c5<\/strong><\/h4>\n\n\n\n<p>\u30d6\u30eb\u30fc\u30c8\u30d5\u30a9\u30fc\u30b9\u653b\u6483\u3092\u9632\u3050\u305f\u3081\u306b\u3001\u30ed\u30b0\u30a4\u30f3\u3084\u91cd\u8981\u306a\u30a2\u30af\u30b7\u30e7\u30f3\u306b\u30ec\u30fc\u30c8\u5236\u9650\u3092\u8a2d\u3051\u308b\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002<br><code>rack-attack<\/code> gem\u3092\u4f7f\u7528\u3057\u3066\u5b9f\u88c5\u3067\u304d\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=\"\">   # config\/initializers\/rack_attack.rb\n   class Rack::Attack\n     throttle('req\/ip', limit: 5, period: 1.second) do |req|\n       req.ip\n     end\n\n     throttle(\"logins\/email\", limit: 5, period: 20.seconds) do |req|\n       if req.path == '\/login' &amp;&amp; req.post?\n         req.params['email'].to_s.downcase.gsub(\/\\s+\/, \"\")\n       end\n     end\n   end<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-71\">5. <strong>\u6a5f\u5bc6\u30c7\u30fc\u30bf\u306e\u9069\u5207\u306a\u6271\u3044<\/strong><\/h4>\n\n\n\n<p>\u6a5f\u5bc6\u30c7\u30fc\u30bf\u3092\u30ed\u30b0\u306b\u51fa\u529b\u3057\u306a\u3044\u3088\u3046\u6ce8\u610f\u304c\u5fc5\u8981\u3067\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=\"\">   class User &lt; ApplicationRecord\n     def self.login(email, password)\n       user = find_by(email: email)\n       if user&amp;.authenticate(password)\n         Rails.logger.info \"User #{user.id} logged in\"\n      else\n         Rails.logger.info \"Failed login attempt for email: [FILTERED]\"\n      end\n      user\n    end\n   end<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-72\">\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u7d99\u7d9a\u7684\u306a\u6539\u5584<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u5b9a\u671f\u7684\u306a\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u76e3\u67fb<\/strong><br>\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3092\u5b9a\u671f\u7684\u306b\u898b\u76f4\u3057\u3001\u65b0\u3057\u3044\u8106\u5f31\u6027\u3084\u653b\u6483\u624b\u6cd5\u306b\u5bfe\u5fdc\u3059\u308b\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002<\/li>\n\n\n\n<li><strong>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u306e\u9069\u7528<\/strong><br>Ruby\u3001Rails\u3001\u304a\u3088\u3073\u4f7f\u7528\u3057\u3066\u3044\u308bgem\u306e\u6700\u65b0\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3092\u5e38\u306b\u9069\u7528\u3059\u308b\u3088\u3046\u306b\u3057\u307e\u3057\u3087\u3046\u3002<\/li>\n\n\n\n<li><strong>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30c8\u30ec\u30fc\u30cb\u30f3\u30b0<\/strong><br>\u958b\u767a\u30c1\u30fc\u30e0\u5168\u4f53\u3067\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u610f\u8b58\u3092\u9ad8\u3081\u308b\u305f\u3081\u306b\u3001\u5b9a\u671f\u7684\u306a\u30c8\u30ec\u30fc\u30cb\u30f3\u30b0\u3084\u30ef\u30fc\u30af\u30b7\u30e7\u30c3\u30d7\u3092\u5b9f\u65bd\u3059\u308b\u3053\u3068\u304c\u6709\u52b9\u3067\u3059\u3002<\/li>\n\n\n\n<li><strong>\u30a4\u30f3\u30b7\u30c7\u30f3\u30c8\u5bfe\u5fdc\u8a08\u753b\u306e\u7b56\u5b9a<\/strong><br>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30a4\u30f3\u30b7\u30c7\u30f3\u30c8\u304c\u767a\u751f\u3057\u305f\u5834\u5408\u306e\u5bfe\u5fdc\u624b\u9806\u3092\u4e8b\u524d\u306b\u7b56\u5b9a\u3057\u3001\u5b9a\u671f\u7684\u306b\u898b\u76f4\u3057\u3068\u66f4\u65b0\u3092\u884c\u3044\u307e\u3057\u3087\u3046\u3002<\/li>\n<\/ol>\n\n\n\n<p>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3092\u8003\u616e\u3057\u305f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306f\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u4fdd\u8b77\u3059\u308b\u4e0a\u3067\u975e\u5e38\u306b\u91cd\u8981\u306a\u8981\u7d20\u3067\u3059\u3002<br>\u305f\u3060\u3057\u3001\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3060\u3051\u3067\u306a\u304f\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u5168\u4f53\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u3092\u5e38\u306b\u898b\u76f4\u3057\u3001\u6539\u5584\u3057\u3066\u3044\u304f\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002<br>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u306f\u7d99\u7d9a\u7684\u306a\u30d7\u30ed\u30bb\u30b9\u3067\u3042\u308a\u3001\u65b0\u305f\u306a\u8105\u5a01\u306b\u5bfe\u5fdc\u3059\u308b\u305f\u3081\u306b\u3001\u5e38\u306b\u8b66\u6212\u3068\u66f4\u65b0\u304c\u5fc5\u8981\u3067\u3059\u3002<\/p>\n\n\n\n<p>\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u3053\u308c\u307e\u3067\u5b66\u3093\u3060\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30c6\u30af\u30cb\u30c3\u30af\u3092\u7dcf\u62ec\u3057\u3001\u52b9\u679c\u7684\u306avalidate\u306e\u6d3b\u7528\u65b9\u6cd5\u306b\u3064\u3044\u3066\u307e\u3068\u3081\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-73\">\u307e\u3068\u3081\uff1a\u52b9\u679c\u7684\u306avalidate\u306e\u6d3b\u7528\u3067\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u54c1\u8cea\u3092\u5411\u4e0a\u3055\u305b\u3088\u3046<\/h2>\n\n\n\n<p>\u672c\u8a18\u4e8b\u3067\u306f\u3001Ruby on Rails\u306b\u304a\u3051\u308b\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u91cd\u8981\u6027\u3068\u3001\u305d\u306e\u52b9\u679c\u7684\u306a\u6d3b\u7528\u65b9\u6cd5\u306b\u3064\u3044\u3066\u6df1\u304f\u6398\u308a\u4e0b\u3052\u3066\u304d\u307e\u3057\u305f\u3002<br>\u3053\u3053\u3067\u3001\u5b66\u3093\u3060\u4e3b\u8981\u30dd\u30a4\u30f3\u30c8\u3092\u632f\u308a\u8fd4\u308a\u3001\u4eca\u5f8c\u306e\u5b9f\u8df5\u306b\u5411\u3051\u305f\u30a2\u30c9\u30d0\u30a4\u30b9\u3092\u307e\u3068\u3081\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-74\">\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u91cd\u8981\u6027\u3068\u5b66\u3093\u30607\u3064\u306e\u30c6\u30af\u30cb\u30c3\u30af<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u57fa\u672c\u6982\u5ff5<\/strong>: \u30c7\u30fc\u30bf\u306e\u6574\u5408\u6027\u3092\u4fdd\u3061\u3001\u30e6\u30fc\u30b6\u30fc\u4f53\u9a13\u3092\u5411\u4e0a\u3055\u305b\u308b\u91cd\u8981\u306a\u6a5f\u80fd<\/li>\n\n\n\n<li><strong>\u4e3b\u8981\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30d8\u30eb\u30d1\u30fc\u306e\u6d3b\u7528<\/strong>: \u7d44\u307f\u8fbc\u307f\u30d8\u30eb\u30d1\u30fc\u3092\u4f7f\u7528\u3057\u3066\u52b9\u7387\u7684\u306b\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u5b9f\u88c5<\/li>\n\n\n\n<li><strong>\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5<\/strong>: \u8907\u96d1\u306a\u30d3\u30b8\u30cd\u30b9\u30ed\u30b8\u30c3\u30af\u306b\u5bfe\u5fdc\u3059\u308b\u305f\u3081\u306e\u67d4\u8edf\u306a\u65b9\u6cd5<\/li>\n\n\n\n<li><strong>\u6761\u4ef6\u4ed8\u304d\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3<\/strong>: \u7279\u5b9a\u306e\u6761\u4ef6\u4e0b\u3067\u306e\u307f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u5b9f\u884c\u3059\u308b\u9ad8\u5ea6\u306a\u30c6\u30af\u30cb\u30c3\u30af<\/li>\n\n\n\n<li><strong>\u30a2\u30bd\u30b7\u30a8\u30fc\u30b7\u30e7\u30f3\u3092\u8003\u616e\u3057\u305f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3<\/strong>: \u95a2\u9023\u3059\u308b\u30e2\u30c7\u30eb\u9593\u3067\u306e\u30c7\u30fc\u30bf\u306e\u6574\u5408\u6027\u3092\u78ba\u4fdd<\/li>\n\n\n\n<li><strong>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316<\/strong>: \u5927\u898f\u6a21\u306a\u30c7\u30fc\u30bf\u30bb\u30c3\u30c8\u3067\u3082\u52b9\u7387\u7684\u306b\u52d5\u4f5c\u3059\u308b\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3<\/li>\n\n\n\n<li><strong>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5f37\u5316<\/strong>: \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u901a\u3058\u3066\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3092\u5411\u4e0a<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-75\">\u52b9\u679c\u7684\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u6d3b\u7528\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u9069\u5207\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u9078\u629e\u3068\u7d44\u307f\u5408\u308f\u305b<\/li>\n\n\n\n<li>\u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\u306e\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\u306b\u3088\u308b\u30e6\u30fc\u30b6\u30fc\u4f53\u9a13\u306e\u5411\u4e0a<\/li>\n\n\n\n<li>\u5305\u62ec\u7684\u306a\u30c6\u30b9\u30c8\u306b\u3088\u308b\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u4fe1\u983c\u6027\u78ba\u4fdd<\/li>\n\n\n\n<li>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3068\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u306e\u30d0\u30e9\u30f3\u30b9\u3092\u8003\u616e\u3057\u305f\u5b9f\u88c5<\/li>\n\n\n\n<li>\u65b0\u3057\u3044\u8981\u4ef6\u3084\u8105\u5a01\u306b\u5bfe\u5fdc\u3059\u308b\u305f\u3081\u306e\u7d99\u7d9a\u7684\u306a\u6539\u5584\u3068\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-76\">\u4eca\u5f8c\u306e\u5b66\u7fd2\u3068\u5b9f\u8df5\u306b\u5411\u3051\u3066<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u65e2\u5b58\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3092\u898b\u76f4\u3059<\/strong>: \u5b66\u3093\u3060\u30c6\u30af\u30cb\u30c3\u30af\u3092\u9069\u7528\u3057\u3001\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u6539\u5584\u3057\u307e\u3057\u3087\u3046\u3002<\/li>\n\n\n\n<li><strong>\u65b0\u3057\u3044\u30c6\u30af\u30cb\u30c3\u30af\u306b\u6311\u6226<\/strong>: \u672c\u8a18\u4e8b\u3067\u7d39\u4ecb\u3057\u305f\u4e2d\u304b\u30891\u3064\u9078\u3073\u3001\u5b9f\u969b\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3067\u5b9f\u88c5\u3057\u3066\u307f\u307e\u3057\u3087\u3046\u3002<\/li>\n\n\n\n<li><strong>\u30c1\u30fc\u30e0\u5185\u3067\u77e5\u8b58\u3092\u5171\u6709<\/strong>: \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\u306b\u3064\u3044\u3066\u3001\u30c1\u30fc\u30e0\u30e1\u30f3\u30d0\u30fc\u3068\u8b70\u8ad6\u3057\u5171\u6709\u3057\u307e\u3057\u3087\u3046\u3002<\/li>\n\n\n\n<li><strong>\u30c6\u30b9\u30c8\u3092\u5145\u5b9f\u3055\u305b\u308b<\/strong>: \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306b\u95a2\u3059\u308b\u5305\u62ec\u7684\u306a\u30e6\u30cb\u30c3\u30c8\u30c6\u30b9\u30c8\u3092\u66f8\u304d\u3001\u4fe1\u983c\u6027\u3092\u9ad8\u3081\u307e\u3057\u3087\u3046\u3002<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-77\">\u3055\u3089\u306a\u308b\u5b66\u7fd2\u30ea\u30bd\u30fc\u30b9<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/guides.rubyonrails.org\/active_record_validations.html\">Ruby on Rails\u516c\u5f0f\u30ac\u30a4\u30c9 \u2013 \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3<\/a><\/li>\n\n\n\n<li>RailsConf\u306e\u767a\u8868\u52d5\u753b\uff1a\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3084\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u306b\u95a2\u3059\u308b\u30bb\u30c3\u30b7\u30e7\u30f3\u3092\u63a2\u3057\u3066\u307f\u307e\u3057\u3087\u3046\u3002<\/li>\n\n\n\n<li>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u95a2\u9023\u306e\u30d6\u30ed\u30b0\u3084\u30cb\u30e5\u30fc\u30b9\u30ec\u30bf\u30fc\u3092\u5b9a\u671f\u7684\u306b\u30c1\u30a7\u30c3\u30af\u3057\u3001\u6700\u65b0\u306e\u8105\u5a01\u3068\u5bfe\u7b56\u3092\u5b66\u3073\u307e\u3057\u3087\u3046\u3002<\/li>\n\n\n\n<li>GitHub\u4e0a\u306e\u4eba\u6c17\u306e\u3042\u308bRails\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u30b3\u30fc\u30c9\u3092\u8aad\u307f\u3001\u5b9f\u969b\u306e\u5b9f\u88c5\u4f8b\u3092\u5b66\u3073\u307e\u3057\u3087\u3046\u3002<\/li>\n<\/ul>\n\n\n\n<p>\u52b9\u679c\u7684\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5\u306f\u3001\u9ad8\u54c1\u8cea\u306aRuby on Rails\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u958b\u767a\u3059\u308b\u4e0a\u3067\u4e0d\u53ef\u6b20\u3067\u3059\u3002<br>\u672c\u8a18\u4e8b\u3067\u5b66\u3093\u3060\u30c6\u30af\u30cb\u30c3\u30af\u3092\u6d3b\u7528\u3057\u3001\u7d99\u7d9a\u7684\u306b\u5b66\u7fd2\u3068\u6539\u5584\u3092\u91cd\u306d\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u5805\u7262\u3067\u4fe1\u983c\u6027\u306e\u9ad8\u3044\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u69cb\u7bc9\u3067\u304d\u308b\u3067\u3057\u3087\u3046\u3002<br>\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306f\u5358\u306a\u308b\u30c7\u30fc\u30bf\u30c1\u30a7\u30c3\u30af\u4ee5\u4e0a\u306e\u4fa1\u5024\u304c\u3042\u308a\u307e\u3059\u3002<br>\u30e6\u30fc\u30b6\u30fc\u4f53\u9a13\u306e\u5411\u4e0a\u3001\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u306e\u5f37\u5316\u3001\u305d\u3057\u3066\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u5168\u4f53\u306e\u54c1\u8cea\u5411\u4e0a\u306b\u3064\u306a\u304c\u308b\u91cd\u8981\u306a\u8981\u7d20\u306a\u306e\u3067\u3059\u3002<\/p>\n\n\n\n<p>\u3055\u3042\u3001\u5b66\u3093\u3060\u3053\u3068\u3092\u5b9f\u8df5\u306b\u79fb\u3057\u3001\u3042\u306a\u305f\u306eRails\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u6b21\u306e\u30ec\u30d9\u30eb\u3078\u3068\u5f15\u304d\u4e0a\u3052\u307e\u3057\u3087\u3046\uff01<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ruby on Rails\u306evalidate\u306f\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30c7\u30fc\u30bf\u6574\u5408\u6027\u3092\u4fdd\u3061\u3001\u30e6\u30fc\u30b6\u30fc\u4f53\u9a13\u3092\u5411\u4e0a\u3055\u305b\u308b\u91cd\u8981\u306a\u6a5f\u80fd\u3067\u3059\u3002\u672c\u8a18\u4e8b\u3067\u306f\u3001\u57fa\u790e\u304b\u3089\u5fdc\u7528\u307e\u3067\u3001validate\u306e\u52b9\u679c\u7684\u306a\u6d3b\u7528\u6cd5\u30927\u3064\u306e\u30c6\u30af\u30cb\u30c3\u30af\u3092\u901a\u3058\u3066\u89e3\u8aac\u3057 &#8230; <\/p>\n","protected":false},"author":1,"featured_media":3089,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,44],"tags":[],"class_list":{"0":"post-140","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-ruby","8":"category-ruby-rails"},"_links":{"self":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/140","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=140"}],"version-history":[{"count":1,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/140\/revisions"}],"predecessor-version":[{"id":141,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/140\/revisions\/141"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/media\/3089"}],"wp:attachment":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=140"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=140"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=140"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}