{"id":514304,"date":"2024-10-01T02:59:06","date_gmt":"2024-10-01T01:59:06","guid":{"rendered":"https:\/\/blog.jetbrains.com\/ruby\/2024\/07\/how-to-use-stimulus-in-your-rails-apps-with-rubymine\/"},"modified":"2024-11-18T18:43:01","modified_gmt":"2024-11-18T17:43:01","slug":"how-to-use-stimulus-in-your-rails-apps-with-rubymine","status":"publish","type":"ruby","link":"https:\/\/blog.jetbrains.com\/ja\/ruby\/2024\/10\/how-to-use-stimulus-in-your-rails-apps-with-rubymine\/","title":{"rendered":"RubyMine \u3067 Stimulus \u3092 Rails \u30a2\u30d7\u30ea\u306b\u4f7f\u7528\u3059\u308b"},"content":{"rendered":"<p>\u7686\u3055\u3093\u3001\u3053\u3093\u306b\u3061\u306f\uff01<\/p>\n<p>RubyMine \u30c1\u30fc\u30e0\u306f Ruby \u3068 Rails \u306e\u65b0\u3057\u3044\u30c6\u30af\u30ce\u30ed\u30b8\u30fc\u306e\u30b5\u30dd\u30fc\u30c8\u3092\u63d0\u4f9b\u3059\u308b\u305f\u3081\u306e\u7d99\u7d9a\u7684\u306a\u53d6\u308a\u7d44\u307f\u3092\u884c\u3063\u3066\u3044\u307e\u3059\u3002 Rails \u306b\u6700\u8fd1\u8ffd\u52a0\u3055\u308c\u305f\u6700\u3082\u753b\u671f\u7684\u306a\u624b\u6cd5\u306e 1 \u3064\u306f\u9593\u9055\u3044\u306a\u304f <strong>Hotwire<\/strong> \u3060\u3068\u8a00\u3048\u307e\u3059\u3002\u305d\u3053\u3067\u3001\u3053\u306e\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u4e00\u5f0f\u306e\u6982\u8981\u3068 RubyMine \u3067\u6700\u3082\u91cd\u8981\u306a <strong>Turbo<\/strong> \u6a5f\u80fd\u3068 <strong>Stimulus<\/strong> \u6a5f\u80fd\u3092 Rails \u30a2\u30d7\u30ea\u306b\u4f7f\u7528\u3059\u308b\u305f\u3081\u306e\u30c1\u30e5\u30fc\u30c8\u30ea\u30a2\u30eb\u3092\u7528\u610f\u3057\u307e\u3057\u305f\u3002 \u3053\u306e\u8a18\u4e8b\u3067\u306f <strong>Stimulus<\/strong> \u306b\u3064\u3044\u3066\u8aac\u660e\u3057\u307e\u3059\u3002<strong>Turbo<\/strong> \u306b\u3064\u3044\u3066\u306f\u3001<a href=\"https:\/\/blog.jetbrains.com\/ja\/ruby\/2024\/07\/how-to-use-turbo-in-your-rails-apps-with-rubymine\/\">\u524d\u306e\u30d6\u30ed\u30b0\u8a18\u4e8b<\/a>\u3092\u3054\u89a7\u304f\u3060\u3055\u3044\u3002<\/p>\n<h2 class=\"wp-block-heading\"><strong>Hotwire \u3068 Stimulus<\/strong><\/h2>\n<h3 class=\"wp-block-heading\">Hotwire \u3068\u306f\uff1f<\/h3>\n<p><a href=\"https:\/\/hotwired.dev\/\" target=\"_blank\" rel=\"noopener\"><strong>Hotwire<\/strong><\/a> \u306f JSON \u306e\u4ee3\u308f\u308a\u306b HTML \u3092\u30ef\u30a4\u30e4\u30fc\u8d8a\u3057\u306b\u9001\u4fe1\u3059\u308b\u3053\u3068\u3067\u30a6\u30a7\u30d6\u958b\u767a\u3092\u5358\u7d14\u5316\u3057\u307e\u3059\uff08\u540d\u79f0\u306f\u300cHTML over the wire\u300d\u306e\u7565\u79f0\u3067\u3059\uff09\u3002 \u3053\u308c\u306b\u3088\u308a\u3001JavaScript \u958b\u767a\u8005\u306e\u30b3\u30fc\u30c7\u30a3\u30f3\u30b0\u91cf\u3068\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u304b\u3089\u30d6\u30e9\u30a6\u30b6\u30fc\u3078\u306e\u9001\u4fe1\u30c7\u30fc\u30bf\u91cf\u3092\u6e1b\u3089\u3057\u3064\u3064\u3001\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u30ec\u30f3\u30c0\u30ea\u30f3\u30b0\u3092\u30b5\u30fc\u30d0\u30fc\u5074\u3067\u5b9f\u884c\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002 <strong>Hotwire<\/strong> \u306f <a href=\"https:\/\/turbo.hotwired.dev\/\" target=\"_blank\" rel=\"noopener\">Turbo<\/a>\u3001<a href=\"https:\/\/stimulus.hotwired.dev\/\" target=\"_blank\" rel=\"noopener\">Stimulus<\/a>\u3001\u304a\u3088\u3073 <a href=\"https:\/\/strada.hotwired.dev\/\" target=\"_blank\" rel=\"noopener\">Strada<\/a> \u3068\u3044\u3046\u8907\u6570\u306e\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3067\u69cb\u6210\u3055\u308c\u3066\u3044\u307e\u3059\u3002 \u3053\u306e\u8a18\u4e8b\u3067\u306f\u3001<strong>Stimulus<\/strong> \u306b\u3064\u3044\u3066\u8aac\u660e\u3057\u307e\u3059\u3002<\/p>\n<h3 class=\"wp-block-heading\"><strong>Stimulus \u3068\u306f\uff1f<\/strong><\/h3>\n<p><strong>Stimulus<\/strong> \u306f\u9759\u7684 HTML \u3068\u305d\u306e\u65e2\u5b58\u306e DOM \u8981\u7d20\u3068\u9023\u643a\u3059\u308b\u3088\u3046\u306b\u8a2d\u8a08\u3055\u308c\u305f JavaScript \u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3067\u3059\u3002 \u30e6\u30fc\u30b6\u30fc\u306f DOM \u64cd\u4f5c\u306b\u4f7f\u7528\u3067\u304d\u308b Stimulus \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306b\u8981\u7d20\u3092\u63a5\u7d9a\u3059\u308b\u3053\u3068\u3067\u3001JavaScript \u306e\u6a5f\u80fd\u3092 DOM \u306b\u8ffd\u52a0\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002 \u3053\u308c\u306f\u5b8c\u5168\u306a JavaScript \u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3092\u63d0\u4f9b\u3059\u308b\u3053\u3068\u3067\u306f\u306a\u304f\u3001\u65e2\u5b58 HTML \u8981\u7d20\u306e\u6a5f\u80fd\u3092\u5f37\u5316\u3059\u308b\u3053\u3068\u3092\u76ee\u7684\u3068\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n<p><code>stimulus-rails<\/code> gem \u306f Rails 7 \u306b\u30c7\u30d5\u30a9\u30eb\u30c8\u3067\u540c\u68b1\u3055\u308c\u3066\u3044\u308b\u305f\u3081\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3067\u3059\u3050\u306b\u4f7f\u7528\u3057\u59cb\u3081\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\uff01<\/p>\n<p><a href=\"https:\/\/www.jetbrains.com\/ja-jp\/ruby\/\" target=\"_blank\" rel=\"noopener\">RubyMine<\/a> \u306f\u30b3\u30fc\u30c9\u88dc\u5b8c\u3001\u79fb\u52d5\u64cd\u4f5c\u3001Rename\uff08\u540d\u524d\u306e\u5909\u66f4\uff09\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u306a\u3069\u306e Stimulus \u306e\u30b5\u30dd\u30fc\u30c8\u3092\u63d0\u4f9b\u3057\u3066\u3044\u307e\u3059\u3002\u305c\u3072\u3053\u306e\u30c1\u30e5\u30fc\u30c8\u30ea\u30a2\u30eb\u3092\u8aad\u307f\u306a\u304c\u3089\u304a\u8a66\u3057\u304f\u3060\u3055\u3044\u3002<\/p>\n<h2 class=\"wp-block-heading\"><strong>\u30c1\u30e5\u30fc\u30c8\u30ea\u30a2\u30eb: RubyMine \u3067 Stimulus \u3092 Rails \u30a2\u30d7\u30ea\u306b\u4f7f\u7528\u3059\u308b<\/strong><\/h2>\n<p>\u3053\u306e\u30c1\u30e5\u30fc\u30c8\u30ea\u30a2\u30eb\u3067\u306f\u3001\u57fa\u672c\u7684\u306a Stimulus \u306e\u30d3\u30eb\u30c7\u30a3\u30f3\u30b0\u30d6\u30ed\u30c3\u30af\u3092\u4f7f\u7528\u3057\u3066 JavaScript \u3092\u7c21\u5358\u306b\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306b\u7d71\u5408\u3059\u308b\u65b9\u6cd5\u3092\u8aac\u660e\u3057\u307e\u3059\u3002 \u30e6\u30fc\u30b6\u30fc\u304c\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u4f5c\u6210\u3057\u3001\u30df\u30cb\u6295\u7a3f\u3092\u4f5c\u6210\u3057\u3001\u76f8\u4e92\u30d5\u30a9\u30ed\u30fc\u3092\u884c\u3044\u3001\u30d5\u30a3\u30fc\u30c9\u3067\u30df\u30cb\u6295\u7a3f\u3092\u8aad\u3080\u3053\u3068\u306e\u3067\u304d\u308b\u30b5\u30f3\u30d7\u30eb Rails \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u4f7f\u7528\u3057\u307e\u3059\u3002<\/p>\n<h3 class=\"wp-block-heading\">\u30b5\u30f3\u30d7\u30eb Rails \u30a2\u30d7\u30ea\u3092\u30af\u30ed\u30fc\u30f3\u3059\u308b<\/h3>\n<p>\u4ee5\u4e0b\u306e\u624b\u9806\u306b\u5f93\u3063\u3066\u30b5\u30f3\u30d7\u30eb\u30a2\u30d7\u30ea\u3092\u30af\u30ed\u30fc\u30f3\u3057\u3001\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\n<ol>\n<li><a href=\"https:\/\/github.com\/JetBrains\/sample_rails_app_7th_ed\/tree\/hotwire_setup\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/JetBrains\/sample_rails_app_7th_ed\/tree\/hotwire_setup<\/a> \u306b\u3042\u308b\u30b5\u30f3\u30d7\u30eb\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u30c1\u30a7\u30c3\u30af\u30a2\u30a6\u30c8\u3057\u307e\u3059\uff08\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3092\u30af\u30ed\u30fc\u30f3\u3057\u305f\u3089\u5fc5\u305a <code>hotwire_setup<\/code> \u30d6\u30e9\u30f3\u30c1\u306b\u5207\u308a\u66ff\u3048\u3066\u304f\u3060\u3055\u3044\uff09\u3002 Git \u30ea\u30dd\u30b8\u30c8\u30ea\u3092\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u3059\u308b\u65b9\u6cd5\u306e\u8a73\u7d30\u306b\u3064\u3044\u3066\u306f\u3001<a href=\"https:\/\/pleiades.io\/help\/ruby\/set-up-a-git-repository.html#clone-repo\" target=\"_blank\" rel=\"noopener\">\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8<\/a>\u3092\u3054\u89a7\u304f\u3060\u3055\u3044\u3002<\/li>\n<li>Ruby \u30a4\u30f3\u30bf\u30fc\u30d7\u30ea\u30bf\u30fc\u3092\u6307\u5b9a\u3057\u3066 <a href=\"https:\/\/pleiades.io\/help\/ruby\/get-started.html#interpreter\" target=\"_blank\" rel=\"noopener\">gem \u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb<\/a>\u3057\u307e\u3059\u3002<\/li>\n<\/ol>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-495889\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/07\/feed-1.png\" alt=\"\" width=\"1180\" height=\"610\" \/><figcaption class=\"wp-element-caption\"><em>\u30b5\u30f3\u30d7\u30eb\u30a2\u30d7\u30ea\u5185\u306e Alice \u3055\u3093\u306e\u30d5\u30a3\u30fc\u30c9<\/em><\/figcaption><\/figure>\n<p>\u7c21\u5358\u306a <em>Copy to clipboard<\/em>\uff08\u30af\u30ea\u30c3\u30d7\u30dc\u30fc\u30c9\u306b\u30b3\u30d4\u30fc\uff09\u30dc\u30bf\u30f3\u3092\u4f5c\u6210\u3057\u3066\u3001Stimulus \u306e\u5b9f\u969b\u306e\u52d5\u4f5c\u3092\u8a73\u3057\u304f\u898b\u3066\u307f\u307e\u3057\u3087\u3046\u3002<\/p>\n<h3 class=\"wp-block-heading\"><strong><em>Copy to clipboard<\/em> \u30dc\u30bf\u30f3<\/strong><\/h3>\n<p><em>Delete<\/em>\uff08\u524a\u9664\uff09\u30ea\u30f3\u30af\u306e\u6a2a\u306b <em>Copy to clipboard<\/em> \u30dc\u30bf\u30f3\u3092\u8ffd\u52a0\u3057\u307e\u3057\u3087\u3046\u3002 \u3053\u306e\u65b0\u3057\u3044\u30dc\u30bf\u30f3\u304c\u610f\u56f3\u3059\u308b\u6a5f\u80fd\u306f\u3001\u30af\u30ea\u30c3\u30af\u3057\u305f\u3068\u304d\u306b\u30df\u30cb\u6295\u7a3f\u306e\u30c6\u30ad\u30b9\u30c8\u3092\u30b3\u30d4\u30fc\u3059\u308b\u3053\u3068\u3067\u3059\u3002<\/p>\n<p>1. <code>_micropost.html.erb<\/code> \u30d5\u30a1\u30a4\u30eb\u3092\u958b\u304d\u3001\u30dc\u30bf\u30f3\u3092\u30d3\u30e5\u30fc\u306b\u8ffd\u52a0\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"EnlighterJSRAW\">&lt;% if current_user?(micropost.user) %&gt;\n  &lt;%= link_to \"delete\", micropost, data: { \"turbo-method\": :delete,\n                                           turbo_confirm: \"You sure?\" } %&gt;\n&lt;% end %&gt;\n\n&lt;%= button_tag \"copy\", class: \"btn btn-link button-link-aligned\" %&gt;<\/pre>\n<p>1 \u56de\u306e\u30de\u30a6\u30b9\u30af\u30ea\u30c3\u30af\u3067\u30c6\u30ad\u30b9\u30c8\u3092\u30b3\u30d4\u30fc\u3059\u308b\u306b\u306f\u3001JavaScript \u3092\u4f7f\u7528\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 \u3053\u308c\u3092\u884c\u3046\u305f\u3081\u306b\u3001\u30dc\u30bf\u30f3\u3092 Stimulus \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306b\u63a5\u7d9a\u3057\u307e\u3057\u3087\u3046\u3002<\/p>\n<p>2. RubyMine \u306e <em>Run Anything<\/em>\uff08\u4f55\u3067\u3082\u5b9f\u884c\uff09\u6a5f\u80fd\uff08<em>Ctrl+Ctrl<\/em>\uff09\u3092\u4f7f\u3063\u3066\u3001\u6b21\u306e\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3057\u307e\u3059: <code>rails generate stimulus clipboard<\/code><\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-495950\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/07\/rails-generate-stimulus.png\" alt=\"\" width=\"1920\" height=\"1200\" \/><\/p>\n<figcaption class=\"wp-element-caption\"><em>Run Anything\uff08\u4f55\u3067\u3082\u5b9f\u884c\uff09\u3067 Stimulus \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3092\u751f\u6210\u3059\u308b<\/em><\/figcaption>\n<\/figure>\n<p>\u3053\u306e\u30b3\u30de\u30f3\u30c9\u306f DOM \u8981\u7d20\u3068 JavaScript \u9593\u306e\u63a5\u7d9a\u3092\u4f5c\u6210\u3067\u304d\u308b\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3067\u3042\u308b Stimulus <a href=\"https:\/\/stimulus.hotwired.dev\/reference\/controllers\" target=\"_blank\" rel=\"noopener\"><strong>\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc<\/strong><\/a>\u3092\u751f\u6210\u3057\u307e\u3059\u3002<\/p>\n<p>\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u540d\u524d\u3092 <code>clipboard<\/code> \u3068\u3057\u307e\u3059\u3002 \u3053\u306e\u30b3\u30de\u30f3\u30c9\u306f <code>app\/javascript\/controllers<\/code> \u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b <code>clipboard_controller.js<\/code> \u3068\u3044\u3046\u30d5\u30a1\u30a4\u30eb\u3092\u751f\u6210\u3057\u307e\u3059\u3002 \u3053\u306e\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306f\u81ea\u52d5\u7684\u306b\u8aad\u307f\u8fbc\u307e\u308c\u307e\u3059\uff08\u30d5\u30a1\u30a4\u30eb <code>index.js<\/code> \u3092\u3054\u89a7\u304f\u3060\u3055\u3044\uff09\u3002<\/p>\n<p>3. \u30d5\u30a1\u30a4\u30eb <code>_micropost.html.erb<\/code> \u306b <code>data-controller<\/code> \u5c5e\u6027\u3092\u8ffd\u52a0\u3057\u307e\u3059\u3002<\/p>\n<ul>\n<li id=\"micropost-&lt;%= micropost.id %&gt;\" data-controller=\"clipboard\">&#8230;<\/li>\n<\/ul>\n<pre class=\"EnlighterJSRAW\">\u00a0<\/pre>\n<p>\u3053\u308c\u306b\u3088\u308a\u3001\u30df\u30cb\u6295\u7a3f\u3092 clipboard \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306b\u63a5\u7d9a\u3067\u304d\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3059\u3002 \u30c7\u30d0\u30c3\u30b0\u30ed\u30b0\u306e\u8a18\u9332\u3092 connect \u30e1\u30bd\u30c3\u30c9\u306b\u8ffd\u52a0\u3057\u3066\u304b\u3089\u30da\u30fc\u30b8\u306e\u8aad\u307f\u8fbc\u307f\u6642\u306b\u30d6\u30e9\u30a6\u30b6\u30fc\u30b3\u30f3\u30bd\u30fc\u30eb\u3092\u78ba\u8a8d\u3059\u308b\u3068\u3001\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306b\u6b63\u5e38\u306b\u63a5\u7d9a\u3057\u305f\u304b\u3069\u3046\u304b\u3092\u78ba\u8a8d\u3067\u304d\u307e\u3059\u3002<\/p>\n<p>4. <code>_micropost.html.erb<\/code> \u306e <em>copy<\/em> \u30dc\u30bf\u30f3\u3092\u66f4\u65b0\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"EnlighterJSRAW\">&lt;%=button_tag \"copy\", class: \"btn btn-link button-link-aligned\", data: { action: \"clipboard#copy\"} %&gt;<\/pre>\n<p>\u30dc\u30bf\u30f3\u3092\u30af\u30ea\u30c3\u30af\u3057\u305f\u3068\u304d\u306b\u30c6\u30ad\u30b9\u30c8\u3092\u30b3\u30d4\u30fc\u3059\u308b\u3068\u3044\u3046\u7279\u5b9a\u306e\u30a2\u30af\u30b7\u30e7\u30f3\u3092\u5b9f\u884c\u3059\u308b\u3088\u3046\u306b\u3057\u307e\u3059\u3002 \u3053\u306e\u30c6\u30ad\u30b9\u30c8\u306f\u7279\u5b9a\u306e\u30bf\u30fc\u30b2\u30c3\u30c8\u3001\u3064\u307e\u308a\u30df\u30cb\u6295\u7a3f\u306e\u672c\u6587\u304b\u3089\u53d6\u5f97\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 \u30a2\u30af\u30b7\u30e7\u30f3\u3068\u30bf\u30fc\u30b2\u30c3\u30c8\u306f Stimulus \u306e\u57fa\u672c\u6982\u5ff5\u3067\u3059\u3002<\/p>\n<p><a href=\"https:\/\/stimulus.hotwired.dev\/reference\/actions\" target=\"_blank\" rel=\"noopener\"><strong>\u30a2\u30af\u30b7\u30e7\u30f3<\/strong><\/a>\u306f\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u30e1\u30bd\u30c3\u30c9\u3068 DOM \u30a4\u30d9\u30f3\u30c8\u306b\u63a5\u7d9a\u3057\u307e\u3059\u3002 <code>data-action<\/code> \u5c5e\u6027\u3092\u4f7f\u7528\u3057\u3066\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u30e1\u30bd\u30c3\u30c9\u3092\u6307\u5b9a\u3059\u308b\u3053\u3068\u3067\u3001\u8981\u7d20\u3092\u30af\u30ea\u30c3\u30af\u3057\u305f\u308a\u3001\u30c6\u30ad\u30b9\u30c8\u3092\u5165\u529b\u3057\u305f\u308a\u3001\u30d5\u30a9\u30fc\u30e0\u3092\u9001\u4fe1\u3057\u305f\u308a\u3059\u308b\u969b\u306b JavaScript \u30b3\u30fc\u30c9\u3092\u547c\u3073\u51fa\u3059\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002 \u4e0a\u8a18\u306e\u30b3\u30fc\u30c9\u306e\u30dc\u30bf\u30f3\u3067\u306f\u307e\u3055\u306b\u3053\u308c\u3092\u884c\u3044\u307e\u3057\u305f\u3002<\/p>\n<p>5. clipboard \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306b copy \u30e1\u30bd\u30c3\u30c9\u3092\u8ffd\u52a0\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"EnlighterJSRAW\">export default class extends Controller {\n  connect() {\n  }\n  \n  copy() {    \n  }\n}<\/pre>\n<p>\u30c6\u30ad\u30b9\u30c8\u3092\u30b3\u30d4\u30fc\u3059\u308b\u306b\u306f <code>navigator.clipboard.writeText<\/code> \u30e1\u30bd\u30c3\u30c9\u3092\u4f7f\u7528\u3067\u304d\u307e\u3059\u304c\u3001\u30c6\u30ad\u30b9\u30c8\u304c\u30b3\u30d4\u30fc\u3055\u308c\u308b\u8981\u7d20\u3092\u53d6\u5f97\u3059\u308b\u65b9\u6cd5\u304c\u5fc5\u8981\u3067\u3059\u3002 \u305d\u3053\u3067\u30bf\u30fc\u30b2\u30c3\u30c8\u306e\u51fa\u756a\u3067\u3059\u3002<\/p>\n<p>6. \u4ee5\u4e0b\u306e\u884c\u3092\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u30af\u30e9\u30b9\u306b\u8cbc\u308a\u4ed8\u3051\u3066\u3001\u30bf\u30fc\u30b2\u30c3\u30c8\u3092\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306b\u8ffd\u52a0\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"EnlighterJSRAW\">static targets = [\"source\"];<\/pre>\n<p><a href=\"https:\/\/stimulus.hotwired.dev\/reference\/targets\" target=\"_blank\" rel=\"noopener\"><strong>\u30bf\u30fc\u30b2\u30c3\u30c8<\/strong><\/a>\u3092\u4f7f\u3046\u3053\u3068\u3067\u3001\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3067\u64cd\u4f5c\u3059\u308b DOM \u8981\u7d20\u3092\u53c2\u7167\u3067\u304d\u307e\u3059\u3002<\/p>\n<p>\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u30af\u30e9\u30b9\u306e\u9759\u7684\u30d5\u30a3\u30fc\u30eb\u30c9\u5185\u3067\u306f\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u304c\u4f7f\u7528\u3059\u308b\u30bf\u30fc\u30b2\u30c3\u30c8\u3092\u6307\u5b9a\u3067\u304d\u307e\u3059\u3002<\/p>\n<p>7. <code>_micropost.html.erb<\/code> \u3067\u30df\u30cb\u6295\u7a3f\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u3092 <code>div<\/code> \u30bf\u30b0\u3067\u56f2\u307f\u307e\u3059\u3002<\/p>\n<div data-clipboard-target=\"source\">\u00a0 &lt;%= micropost.content %&gt;<\/div>\n<p>HTML \u5185\u3067\u306f\u6b21\u306e\u4f8b\u306e\u3088\u3046\u306b <code>data-[controller-name]-target<\/code> \u5c5e\u6027\u3092\u4f7f\u7528\u3057\u3066\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u30bf\u30fc\u30b2\u30c3\u30c8\u3092\u53c2\u7167\u3067\u304d\u307e\u3059: <code>data-clipboard-target = \"source\"<\/code>\u3002<\/p>\n<p>8. <code>copy<\/code> \u30e1\u30bd\u30c3\u30c9\u306e\u672c\u4f53\u3092\u5b8c\u6210\u3055\u305b\u307e\u3059\u3002<\/p>\n<pre class=\"EnlighterJSRAW\">\/\/ clipboard_controller.js\n\ncopy() {\n\u00a0 navigator.clipboard.writeText(this.sourceTarget.textContent);\n}<\/pre>\n<p>JavaScript \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u5185\u3067\u306f <code>this.sourceTarget<\/code> \u3092\u4f7f\u7528\u3057\u3066\u30bf\u30fc\u30b2\u30c3\u30c8\u3092\u53c2\u7167\u3067\u304d\u307e\u3059\u3002<\/p>\n<p><code>navigator.clipboard<\/code> \u306f<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Clipboard\" target=\"_blank\" rel=\"noopener\">\u5b89\u5168\u306a\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u5185<\/a>\u3067\u3057\u304b\u4f7f\u7528\u3067\u304d\u306a\u3044\u3053\u3068\u306b\u6ce8\u610f\u3057\u3066\u304f\u3060\u3055\u3044\u3002 \u30ed\u30fc\u30ab\u30eb\u958b\u767a\u306e\u5834\u5408\u306f localhost \u3067\u30a2\u30d7\u30ea\u3092\u5b9f\u884c\u3067\u304d\u307e\u3059\u3002<\/p>\n<p>\u4ee5\u4e0a\u3067\u3059\uff01\u3000 \u30dc\u30bf\u30f3\u3092 1 \u56de\u30af\u30ea\u30c3\u30af\u3059\u308b\u3060\u3051\u3067\u30df\u30cb\u6295\u7a3f\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u3092\u30af\u30ea\u30c3\u30d7\u30dc\u30fc\u30c9\u306b\u30b3\u30d4\u30fc\u3067\u304d\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3057\u305f\u3002<\/p>\n<h3 class=\"wp-block-heading\"><strong>\u30d5\u30a3\u30fc\u30c9\u304b\u3089\u30df\u30cb\u6295\u7a3f\u3092\u975e\u8868\u793a\u306b\u3059\u308b<\/strong><\/h3>\n<p>Stimulus \u306e\u4ed6\u306e\u91cd\u8981\u306a\u6982\u5ff5\u306b\u306f\u3001\u5024\u3001\u30af\u30e9\u30b9\u3001\u304a\u3088\u3073\u30a2\u30a6\u30c8\u30ec\u30c3\u30c8\u304c\u3042\u308a\u307e\u3059\u3002<\/p>\n<p>\u5024\u3092\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u8981\u7d20\u306e\u5c5e\u6027\u3068\u3057\u3066\u6e21\u3057\u3001\u305d\u306e\u5024\u3092 JavaScript \u30b3\u30fc\u30c9\u3067\u4f7f\u7528\u3057\u305f\u3044\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002 Stimulus \u306e<strong><a href=\"https:\/\/stimulus.hotwired.dev\/reference\/values\" target=\"_blank\" rel=\"noopener\">\u5024<\/a><\/strong>\u306f\u307e\u3055\u306b\u3053\u306e\u52d5\u4f5c\u3092\u5b9f\u73fe\u3059\u308b\u305f\u3081\u306b\u8a2d\u8a08\u3055\u308c\u3066\u3044\u307e\u3059\u3002 \u6b21\u306e\u3088\u3046\u306b <code>data-controller<\/code> \u5c5e\u6027\u306e\u6a2a\u306b\u5024\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002<\/p>\n<ul>\n<li id=\"micropost-&lt;%= micropost.id %&gt;\" data-controller=\"clipboard\" data-clipboard-copyable-value=\"true\">\u00a0<\/li>\n<\/ul>\n<p>\u3053\u3053\u3067\u3001<code>clipboard<\/code> \u306f\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u540d\u524d\u3067\u3042\u308a\u3001<code>copyable<\/code> \u306f\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3067\u8aad\u307f\u53d6\u308b\uff08\u307e\u305f\u306f\u66f8\u304d\u8fbc\u3080\uff09\u30d7\u30ed\u30d1\u30c6\u30a3\u306e\u540d\u524d\u3067\u3059\u3002 \u6b21\u306b\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u7279\u6b8a\u306a\u9759\u7684\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3067\u5024\u306e\u540d\u524d\u3068\u578b\u3092\u5b9a\u7fa9\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"EnlighterJSRAW\">\/\/ clipboard_controller.js\n\nstatic values = { copyable: Boolean };<\/pre>\n<p>\u4f7f\u7528\u3067\u304d\u308b\u578b\u306b\u3064\u3044\u3066\u306e\u8a73\u7d30\u306f\u3001<a href=\"https:\/\/stimulus.hotwired.dev\/reference\/values#types\" target=\"_blank\" rel=\"noopener\">\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8<\/a>\u3092\u3054\u89a7\u304f\u3060\u3055\u3044\u3002<\/p>\n<p>JavaScript \u3067\u306f\u5024\u3092 <code>this.[valueName]Value<\/code> \u306a\u3069\u306e\u3088\u3046\u306b\u53c2\u7167\u3067\u304d\u307e\u3059\u3002<\/p>\n<pre class=\"EnlighterJSRAW\">\/\/ clipboard_controller.js\n\nif (!this.copyableValue) {\n\u00a0 ...\n}<\/pre>\n<p><a href=\"https:\/\/stimulus.hotwired.dev\/reference\/outlets\" target=\"_blank\" rel=\"noopener\"><strong>\u30a2\u30a6\u30c8\u30ec\u30c3\u30c8<\/strong><\/a>\u3067\u306f\u3001\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u5185\u304b\u3089\u4ed6\u306e Stimulus \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3068\u8981\u7d20\u3092\u53c2\u7167\u3067\u304d\u307e\u3059\u3002\u3053\u3046\u3059\u308b\u3053\u3068\u3067\u3001\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u5185\u306e\u69d8\u3005\u306a\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u304c\u76f8\u4e92\u306b\u901a\u4fe1\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n<p><strong><a href=\"https:\/\/stimulus.hotwired.dev\/reference\/css-classes\" target=\"_blank\" rel=\"noopener\">\u30af\u30e9\u30b9<\/a><\/strong>\u306f CSS \u30af\u30e9\u30b9\u3092\u53c2\u7167\u3057\u3066\u304a\u308a\u3001JavaScript \u30b3\u30fc\u30c9\u304b\u3089\u30d7\u30ed\u30b0\u30e9\u30e0\u3067\u30af\u30e9\u30b9\u3092\u64cd\u4f5c\u3067\u304d\u307e\u3059\u3002 \u30ef\u30f3\u30af\u30ea\u30c3\u30af\u3067\u30d5\u30a3\u30fc\u30c9\u306e\u30df\u30cb\u6295\u7a3f\u3092\u975e\u8868\u793a\u306b\u3067\u304d\u308b\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3092\u5b9f\u88c5\u3057\u3001\u30af\u30e9\u30b9\u3068\u3069\u306e\u3088\u3046\u306b\u9023\u643a\u3059\u308b\u306e\u304b\u3092\u8a73\u3057\u304f\u898b\u3066\u307f\u307e\u3057\u3087\u3046\u3002 \u8981\u7d20\u306e\u30b9\u30bf\u30a4\u30eb\u3092\u76f4\u63a5\u64cd\u4f5c\u3059\u308b\uff08<code>target.style.display = \"none\"<\/code>\uff09\u3053\u3068\u3067\u540c\u3058\u52b9\u679c\u3092\u5f97\u3089\u308c\u307e\u3059\u304c\u3001\u3053\u3053\u3067\u306f\u3001\u8981\u7d20\u306e CSS \u30af\u30e9\u30b9\u3092\u8a2d\u5b9a\u3057\u3066\u9054\u6210\u3057\u3066\u307f\u307e\u3057\u3087\u3046\u3002 \u3053\u306e\u624b\u6cd5\u306f\u305d\u306e\u4ed6\u591a\u6570\u306e\u8996\u899a\u7684\u52b9\u679c\u306b\u3082\u518d\u5229\u7528\u3067\u304d\u307e\u3059\u3002<\/p>\n<p>1. <code>custom.scss<\/code> \u30d5\u30a1\u30a4\u30eb\u3092\u958b\u304d\u3001\u6b21\u306e\u30af\u30e9\u30b9\u3092\u8ffd\u52a0\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"EnlighterJSRAW\">.invisible {\n\u00a0 display: none\n}<\/pre>\n<p>2. \u6295\u7a3f\u306e\u8868\u793a\u72b6\u614b\u3092\u64cd\u4f5c\u3059\u308b\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3092\u751f\u6210\u3057\u307e\u3059: <code>rails generate stimulus visibility<\/code>\u3002<\/p>\n<p>3. \u30d5\u30a1\u30a4\u30eb <code>visibility_controller.js<\/code> \u3092\u958b\u304d\u3001\u30af\u30e9\u30b9\u3068\u30bf\u30fc\u30b2\u30c3\u30c8\u3092\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306b\u8ffd\u52a0\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"EnlighterJSRAW\">import { Controller } from \"@hotwired\/stimulus\"\n\nexport default class extends Controller {\n\u00a0 static classes = [\"hidden\"];\n\u00a0 static targets = [\"hide\"];\n}<\/pre>\n<p>4. \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306b <code>hide<\/code> \u30e1\u30bd\u30c3\u30c9\u3092\u8ffd\u52a0\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"EnlighterJSRAW\">export default class extends Controller {\n\u00a0 ...\n\u00a0 \u00a0\n\u00a0 hide() {\n\u00a0 \u00a0 this.hideTarget.classList.add(this.hiddenClass);\n\u00a0 }\n}<\/pre>\n<p>\u3059\u308b\u3068\u3053\u306e\u30e1\u30bd\u30c3\u30c9\u306f CSS \u30af\u30e9\u30b9 <code>hidden<\/code> \u3092\u30bf\u30fc\u30b2\u30c3\u30c8\u306e <code>hide<\/code> \u306b\u8ffd\u8a18\u3057\u307e\u3059\u3002<\/p>\n<p>5. \u6b21\u306e HTML \u5c5e\u6027\u3092\u8ffd\u52a0\u3057\u3066\u3001\u65b0\u3057\u3044\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3068\u30af\u30e9\u30b9\u3092\u30df\u30cb\u6295\u7a3f\u30d3\u30e5\u30fc\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306b\u8ffd\u52a0\u3057\u307e\u3059\u3002<\/p>\n<ul>\n<li id=\"micropost-&lt;%= micropost.id %&gt;\" data-controller=\"clipboard visibility\" data-visibility-hidden-class=\"invisible\" data-visibility-target=\"hide\">\u00a0<\/li>\n<\/ul>\n<p>\u307e\u305a\u3001\u5225\u306e\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\uff08<code>data-controller=\"clipboard visibility\"<\/code>\uff09\u3092\u8ffd\u52a0\u3057\u307e\u3059\u3002 \u6b21\u306b\u3001\u5b9f\u969b\u306b\u3069\u306e CSS \u30af\u30e9\u30b9\u304c\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u8ad6\u7406\u30af\u30e9\u30b9\u306b\u5bfe\u5fdc\u3059\u308b\u304b\u3092\u6307\u5b9a\u3057\u307e\u3059: <code>data-visibility-hidden-class=\"invisible\"<\/code>\u3002 \u30af\u30e9\u30b9\u306f\u305d\u308c\u304c\u5c5e\u3059\u308b\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3068\u540c\u3058\u8981\u7d20\u306b\u6307\u5b9a\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 \u3055\u3089\u306b\u3001\u975e\u8868\u793a\u306b\u3059\u308b\u30bf\u30fc\u30b2\u30c3\u30c8\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002\u3053\u3053\u3067\u306f\u30df\u30cb\u6295\u7a3f\u5168\u4f53\u304c\u30bf\u30fc\u30b2\u30c3\u30c8\u3067\u3059\u3002<\/p>\n<p>6. <code>_micropost.html.erb<\/code> \u3067\u5404\u30df\u30cb\u6295\u7a3f\u306e\u53f3\u306b <em>hide<\/em> \u30dc\u30bf\u30f3\u3092\u8ffd\u52a0\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"EnlighterJSRAW\"><span class=\"timestamp\">\n\u00a0 ...\n\u00a0 &lt;%= button_tag \"hide\", class: \"btn btn-link button-link-aligned\", data: { action: \"visibility#hide\" }, style: \"float: right;\" %&gt;\n<\/span><\/pre>\n<p>\u3053\u306e\u30dc\u30bf\u30f3\u306f Stimulus \u30a2\u30af\u30b7\u30e7\u30f3\u3092\u4f7f\u7528\u3057\u3066\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u30e1\u30bd\u30c3\u30c9\u306e hide \u306b\u63a5\u7d9a\u3057\u307e\u3059\u3002<\/p>\n<p>\u3053\u306e\u30dc\u30bf\u30f3\u3092\u30af\u30ea\u30c3\u30af\u3059\u308b\u3068\u3001\u5bfe\u5fdc\u3059\u308b\u30df\u30cb\u6295\u7a3f\u304c\u975e\u8868\u793a\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>\u2026\u30da\u30fc\u30b8\u304c\u518d\u8aad\u307f\u8fbc\u307f\u3055\u308c\u308b\u307e\u3067\u3067\u3059\u3002<\/p>\n<p>\u3053\u3053\u3067\u3001\u30df\u30cb\u6295\u7a3f\u306e\u975e\u8868\u793a\u306e\u72b6\u614b\u3092\u6c38\u7d9a\u5316\u3059\u308b\u65b9\u6cd5\u306f\u305f\u304f\u3055\u3093\u3042\u308a\u307e\u3059\u3002 \u305f\u3068\u3048\u3070\u3001Stimulus \u306e\u5024\u3092\u4f7f\u7528\u3057\u3066 <code>hidden<\/code>\u3068\u3044\u3046\u30d6\u30fc\u30eb\u5024\u3092\u4f5c\u6210\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002 \u3059\u308b\u3068\u3001\u3053\u306e\u5024\u304c true \u3067\u3042\u308b\u8981\u7d20\u306b hidden \u30af\u30e9\u30b9\u304c\u81ea\u52d5\u7684\u306b\u8ffd\u52a0\u3055\u308c\u307e\u3059\u3002 \u307e\u305f\u306f\u3001\u5358\u306b\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304b\u3089\u305d\u306e\u3088\u3046\u306a\u30df\u30cb\u6295\u7a3f\u3092\u8aad\u307f\u8fbc\u307e\u306a\u3044\u3088\u3046\u306b\u3059\u308b\u3053\u3068\u3082\u53ef\u80fd\u3067\u3059\u3002 \u3053\u308c\u3092\u884c\u3046\u306b\u306f Rails \u30a2\u30d7\u30ea\u306b\u4f55\u304b\u3092\u9001\u308a\u8fd4\u3059\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u304c\u3001\u3053\u308c\u306f\u5358\u7d14\u306a\u30ea\u30af\u30a8\u30b9\u30c8\u3092\u9001\u4fe1\u3059\u308b\u3053\u3068\u3067\u5b9f\u73fe\u3067\u304d\u307e\u3059\u3002 Stimulus \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e <code>hide<\/code> \u30e1\u30bd\u30c3\u30c9\u3092\u3082\u3046\u4e00\u5ea6\u78ba\u8a8d\u3057\u307e\u3057\u3087\u3046\u3002<\/p>\n<p>7. \u6b21\u306e\u30b3\u30fc\u30c9\u3092 <code>visibility_controller.js<\/code> \u306e <code>hide<\/code> \u30e1\u30bd\u30c3\u30c9\u306b\u8ffd\u52a0\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"EnlighterJSRAW\">hide(e) {\n\u00a0 this.hideTarget.classList.add(this.hiddenClass);\n\u00a0\n\u00a0 const id = e.target.dataset.id\n\u00a0 const csrfToken = document.querySelector(\"[name='csrf-token']\").content\n\u00a0 fetch(`\/microposts\/${id}\/hide`, {\n\u00a0 \u00a0 method: 'POST',\n\u00a0 \u00a0 headers: {\n\u00a0 \u00a0 \u00a0 'Content-Type': 'application\/json',\n\u00a0 \u00a0 \u00a0 'X-CSRF-Token': csrfToken\n\u00a0 \u00a0 },\n\u00a0 \u00a0 body: JSON.stringify({ hidden: true })\n\u00a0 }).then(response =&gt; response.json())\n}<\/pre>\n<p>\u3053\u308c\u3067\u975e\u5e38\u306b\u57fa\u672c\u7684\u306a <code>microposts\/:id\/hide<\/code> \u3078\u306e POST \u30ea\u30af\u30a8\u30b9\u30c8\u3092\u9001\u4fe1\u3059\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3057\u305f\u3002 \u30ea\u30af\u30a8\u30b9\u30c8\u306e\u672c\u6587\u3067\u306f\u4f55\u3067\u3082\u9001\u4fe1\u3067\u304d\u307e\u3059\u304c\u3001\u3053\u3053\u3067\u306f <code>hidden<\/code> \u304c true \u3067\u3042\u308b\u3053\u3068\u3092\u8a18\u8ff0\u3057\u307e\u3057\u3087\u3046\u3002<\/p>\n<p>\u3053\u306e\u30b3\u30fc\u30c9\u306f\u30d3\u30e5\u30fc\u304b\u3089\u53d7\u4fe1\u3059\u308b\u5fc5\u8981\u306e\u3042\u308b\u30df\u30cb\u6295\u7a3f\u306e ID \u3092\u4f7f\u7528\u3057\u3066\u3044\u308b\u3053\u3068\u306b\u6ce8\u610f\u3057\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\n<p>8. \u3053\u306e ID \u3092 <code>_micropost.html.erb<\/code> \u3067\u30a2\u30af\u30b7\u30e7\u30f3\u306e\u6a2a\u306e\u30c7\u30fc\u30bf\u30cf\u30c3\u30b7\u30e5\u306b\u6e21\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"EnlighterJSRAW\">&lt;%= button_tag \"hide\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 class: \"btn btn-link button-link-aligned\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 data: { action: \"visibility#hide\", id: micropost.id },\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 style: \"float: right;\" %&gt;<\/pre>\n<p>9. \u6b21\u306e\u30eb\u30fc\u30c8\u3092 <code>routes.rb<\/code> \u306b\u8ffd\u52a0\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"EnlighterJSRAW\">post 'microposts\/:id\/hide', to: 'microposts#hide'<\/pre>\n<p>10. <code>hide<\/code> \u30e1\u30bd\u30c3\u30c9\u3092 <code>microposts_controller.rb<\/code> \u306b\u8ffd\u52a0\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"EnlighterJSRAW\">def hide\n\u00a0 @micropost = Micropost.find(params[:id])\n\u00a0 hidden_post = HiddenPost.new\n\u00a0 hidden_post.user = current_user\n\u00a0 hidden_post.micropost = @micropost\n\u00a0 hidden_post.save\nend<\/pre>\n<p>11. <em>Run Anything<\/em>\uff08\u4f55\u3067\u3082\u5b9f\u884c\uff09\u3092\u4f7f\u7528\u3057\u3066\u3001\u7279\u5b9a\u306e\u30e6\u30fc\u30b6\u30fc\u306b\u5bfe\u3057\u3066\u975e\u8868\u793a\u306e\u6295\u7a3f\u306b\u95a2\u3059\u308b\u60c5\u5831\u3092\u4fdd\u5b58\u3059\u308b\u30e2\u30c7\u30eb\u3092\u751f\u6210\u3057\u307e\u3059\u3002<\/p>\n<p><code>rails generate model HiddenPost user:references micropost:references<\/code><\/p>\n<p>12. <code>user.rb<\/code> \u30d5\u30a1\u30a4\u30eb\u3067 <code>User#feed<\/code> \u30e1\u30bd\u30c3\u30c9\u3092\u66f4\u65b0\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"EnlighterJSRAW\"># user.rb\n\ndef feed\n\u00a0 following_ids = \"SELECT followed_id FROM relationships\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 WHERE\u00a0 follower_id = :user_id\"\n\u00a0 hidden_posts_for_user = \"SELECT micropost_id FROM hidden_posts WHERE user_id = :user_id OR user_id IN (#{following_ids})\"\n\u00a0 Micropost.where(\"user_id IN (#{following_ids})\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 OR user_id = :user_id\", user_id: id)\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 .where(\"id NOT IN (#{hidden_posts_for_user})\", user_id: id)\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 .includes(:user, image_attachment: :blob)\nend<\/pre>\n<p>\u975e\u8868\u793a\u306e\u6295\u7a3f\u306b\u95a2\u3059\u308b\u60c5\u5831\u3092\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u4fdd\u5b58\u3057\u305f\u306e\u3067\u3001\u8a72\u5f53\u3059\u308b\u6295\u7a3f\u306f\u30da\u30fc\u30b8\u304c\u518d\u8aad\u307f\u8fbc\u307f\u3055\u308c\u305f\u5f8c\u3067\u3082\u30e6\u30fc\u30b6\u30fc\u30d5\u30a3\u30fc\u30c9\u306b\u8868\u793a\u3055\u308c\u306a\u304f\u306a\u308a\u307e\u3059\u3002<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-496050\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/07\/stimulus_hide2.gif\" alt=\"\" width=\"1643\" height=\"799\" \/><\/p>\n<figcaption class=\"wp-element-caption\"><em>Hide \u30dc\u30bf\u30f3\u306e\u52d5\u4f5c<\/em><\/figcaption>\n<\/figure>\n<h2 class=\"wp-block-heading\">\u307e\u3068\u3081<\/h2>\n<p>\u3053\u306e\u30c1\u30e5\u30fc\u30c8\u30ea\u30a2\u30eb\u3067\u306f\u3001Stimulus \u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3068\u305d\u306e\u57fa\u672c\u6982\u5ff5\u3067\u3042\u308b\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3001\u30bf\u30fc\u30b2\u30c3\u30c8\u3001\u304a\u3088\u3073\u30a2\u30af\u30b7\u30e7\u30f3\u3092\u8a73\u3057\u304f\u8aac\u660e\u3057\u307e\u3057\u305f\u3002 Rails \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3067 Stimulus \u3092\u4f7f\u3063\u3066 DOM \u8981\u7d20\u3092 JavaScript \u306b\u7c21\u5358\u306b\u63a5\u7d9a\u3059\u308b\u65b9\u6cd5\u3092\u5b66\u7fd2\u3057\u307e\u3057\u305f\u3002<\/p>\n<p>Ruby \u304a\u3088\u3073 Rails \u7528\u306e JetBrains IDE \u3067 Hotwire \u306e\u30b5\u30dd\u30fc\u30c8\u3092\u6d3b\u7528\u3057\u307e\u3057\u3087\u3046\u3002 \u6700\u65b0\u306e RubyMine \u30d0\u30fc\u30b8\u30e7\u30f3\u306f\u5f0a\u793e\u30a6\u30a7\u30d6\u30b5\u30a4\u30c8\u304b\u7121\u6599\u306e <a href=\"https:\/\/www.jetbrains.com\/ja-jp\/toolbox\/app\/\" target=\"_blank\" rel=\"noopener\">Toolbox App<\/a> \u304b\u3089<a href=\"https:\/\/www.jetbrains.com\/ja-jp\/ruby\/download\/\" target=\"_blank\" rel=\"noopener\">\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9<\/a>\u3067\u304d\u307e\u3059\u3002<\/p>\n<p>\u6700\u65b0\u6a5f\u80fd\u306e\u30ea\u30ea\u30fc\u30b9\u6642\u306b\u305d\u306e\u5185\u5bb9\u3092\u8a73\u3057\u304f\u77e5\u308b\u306b\u306f\u3001<a href=\"https:\/\/twitter.com\/rubymine\" target=\"_blank\" rel=\"noopener\">RubyMine<\/a>\u00a0\u306e <a href=\"https:\/\/twitter.com\/rubymine\" target=\"_blank\" rel=\"noopener\">X<\/a> \u3092\u30d5\u30a9\u30ed\u30fc\u3057\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\n<p>\u4ee5\u4e0b\u306e\u30b3\u30e1\u30f3\u30c8\u6b04\u3067\u7686\u3055\u3093\u306e\u3054\u611f\u60f3\u3092\u304a\u805e\u304b\u305b\u304f\u3060\u3055\u3044\u3002\u307e\u305f\u3001\u65b0\u6a5f\u80fd\u306e\u63d0\u6848\u3068\u6295\u7968\u306f<a href=\"https:\/\/youtrack.jetbrains.com\/issues\/ruby\" target=\"_blank\" rel=\"noopener\">\u8ab2\u984c\u30c8\u30e9\u30c3\u30ab\u30fc<\/a>\u3092\u3054\u5229\u7528\u304f\u3060\u3055\u3044\u3002<\/p>\n<p><strong>\u30aa\u30ea\u30b8\u30ca\u30eb\uff08\u82f1\u8a9e\uff09\u30d6\u30ed\u30b0\u6295\u7a3f\u8a18\u4e8b\u306e\u4f5c\u8005\uff1a<\/strong><\/p>\n\n    <div class=\"about-author \">\n        <div class=\"about-author__box\">\n            <div class=\"row\">\n                <div class=\"about-author__box-img\">\n                    <img decoding=\"async\" src=\"https:\/\/secure.gravatar.com\/avatar\/8cb061b71090680564ac09be5e4061e1?s=200&#038;r=g\" width=\"200\" height=\"200\" alt=\"Darya Sharkova\" loading=\"lazy\"  class=\"avatar avatar-200 wp-user-avatar wp-user-avatar-200 photo avatar-default\">\n                <\/div>\n                <div class=\"about-author__box-text\">\n                                            <h4>Darya Sharkova<\/h4>\n                                                        <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n","protected":false},"author":1394,"featured_media":515284,"comment_status":"closed","ping_status":"closed","template":"","categories":[1401,1264,4093,4156],"tags":[217,8636],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/ja\/wp-json\/wp\/v2\/ruby\/514304"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/ja\/wp-json\/wp\/v2\/ruby"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/ja\/wp-json\/wp\/v2\/types\/ruby"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/ja\/wp-json\/wp\/v2\/users\/1394"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/ja\/wp-json\/wp\/v2\/comments?post=514304"}],"version-history":[{"count":10,"href":"https:\/\/blog.jetbrains.com\/ja\/wp-json\/wp\/v2\/ruby\/514304\/revisions"}],"predecessor-version":[{"id":518435,"href":"https:\/\/blog.jetbrains.com\/ja\/wp-json\/wp\/v2\/ruby\/514304\/revisions\/518435"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/ja\/wp-json\/wp\/v2\/media\/515284"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/ja\/wp-json\/wp\/v2\/media?parent=514304"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/ja\/wp-json\/wp\/v2\/categories?post=514304"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/ja\/wp-json\/wp\/v2\/tags?post=514304"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/ja\/wp-json\/wp\/v2\/cross-post-tag?post=514304"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}