こんにちは、nishi_talk(@nishi_talk)です。
Railsで投稿できる画面を作っていて似た投稿があった場合、コピーできると便利ですよね!
今回はdeep_cloneableを使って投稿や記事をコピー(複製)する方法をご紹介します。
前提条件
- ruby 2.5.1
- Rails 5.2.0
データベース構造
(1)User <-> (多)Post(1)
mysql> show columns from users; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(255) | NO | | NULL | | | created_at | datetime(6) | NO | | NULL | | | updated_at | datetime(6) | NO | | NULL | | +------------+--------------+------+-----+---------+----------------+ mysql> show columns from post; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | created_at | datetime(6) | NO | | NULL | | | updated_at | datetime(6) | NO | | NULL | | | user_id | int(11) | NO | MUL | NULL | | +------------+--------------+------+-----+---------+----------------+
deep_cloneableをインストール
Gemfileに以下を追記。
gem 'deep_cloneable'
$ bundle install
routesの設定
routes.rbにコピー用のURLを用意します。
resources :posts do get 'copy' end
追加されたか確認します。
$ rails routes ・ ・ ・ # ↓追加されるはず post_copy POST /posts/:post_id/copy(.:format) posts#copy ・ ・ ・
Controllerの設定
対象の投稿IDを取得して、deep_cloneで複製します。
複製した投稿を保存します。
今回は例として、posts_controller.rbに追加します。
def copy @old_post = Post.find_by(id: params[:post_id]) @post = @old_post.deep_clone @post.save redirect_to posts_path(@post.id), notice: 'コピーしました。' end
Viewの設定
<%= link_to post_copy_path(@post.id), data: { confirm: 'コピーしますか?' } do %> コピーする <% end %>
表示されたコピーボタンを選択すると対象の投稿がコピーできます。