質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

1回答

1398閲覧

cocoonで複製した項目がforbid_login_userに引っ掛かり保存されない

punchan36

総合スコア105

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2020/04/11 05:18

編集2020/04/12 10:36

前提・実現したいこと

Railsでユーザーのプロフィール画面を作っています。
ユーザーが「今勉強中の言語」を選択出来るよう、language-selectと言うgemを使用し実装しました。またユーザーは複数の言語を勉強中の可能性もある為、今度はcocoonと言うgemを使用し、言語選択のセレクトタグを非同期で追加・削除出来るようにしました。

しかしここからが問題で、ユーザーが最初に選んだ言語はしっかり保存されるのですが、cocoonにより追加し選択した言語はうまく保存されません。
ユーザーが追加・選択した情報もうまく保存し、プロフィール画面に表示させたいです。

問題に至るまでの流れ

cocoonの実装はgithubのREADMEこちらのページを参考に行いました。
しかし同じコードでは「保存」ボタンを押しても何も反応が無かったので、該当しているであろうform_forのメソッドをpostにしました。

Rails

1<%= form_for @user, method: :post do |f| %> 2 <div id='languages'> 3 <%= f.fields_for :languages do |language| %> 4 <%= render 'language_fields', :f => language %> 5 <% end %> 6 <div class='links'> 7 <%= link_to_add_association 'add language', f, :languages %> 8 </div> 9 </div> 10<% end %>

すると反応はするようになりましたが今度は以下のエラーが表示されました。

ActionController::InvalidAuthenticityToken in UsersController#update ActionController::InvalidAuthenticityToken Extracted source (around line #211): def handle_unverified_request raise ActionController::InvalidAuthenticityToken end end end

こちらはapplication_controller.rbに「protect_from_forgery with: :null_session」の一文を追加する事で解消されました。
ようやく実装の確認が出来るかと思ったのですが、ここで上記で触れたように、ユーザーが最初に選んだ言語は保存されるが、cocoonにより追加し選択した言語は保存されない、と言う問題が発生しました。

該当のソースコード(users#show.html.erb)

rails

1<h2><%= @user.language %></h2>

該当のソースコード(users#edit.html.erb)

rails

1 <%= form_tag("/users/#{@user.id}/update", {multipart: true}) do %> 2 <table> 3 <p>言語</p> 4 <%= select_tag(:language,options_for_select(languages)) %> 5 <%= render 'users/form' %> 6 <input type="submit" value="保存"> 7 </table> 8 <% end %>

該当のソースコード(users#_form.html.erb)

cocoonのパーシャルです。

rails

1<%= form_for @user, method: :post do |f| %> 2 <div id='languages'> 3 <%= f.fields_for :languages do |language| %> 4 <%= render 'language_fields', :f => language %> 5 <% end %> 6 <div class='links'> 7 <%= link_to_add_association 'add language', f, :languages %> 8 </div> 9 </div> 10<% end %>

該当のソースコード(users#_language.html.erb)

cocoonのパーシャルの2つ目です。

rails

1<div class='nested-fields'> 2 <div class="field"> 3 <%= select_tag(:language,options_for_select(languages)) %> 4 </div> 5 <%= link_to_remove_association "remove language", f %> 6</div>

該当のソースコード(users_controller.rb)

またここで「redirect_to("/users/#{@user.id}")」と設定しているのですが、application_controller.rbに「protect_from_forgery with: :null_session」の一文を入れた直後は該当ページにリダイレクトされますが、それ以降は「/posts/index」にリダイレクトされてしまいます。その際、application_controller.rbのforbid_login_userで設定した"すでにログインしています"のフラッシュも表示されます。

rails

1 before_action :authenticate_user, {only: [:index, :show, :edit, :update]} 2 before_action :forbid_login_user, {only: [:new, :create, :login_form, :login]} 3 before_action :ensure_correct_user, {only: [:edit, :update]} 4 5 def edit 6 @user = User.find_by(id: params[:id]) 7 end 8 9 def user_params 10 params.require(:user).permit(:name, :description, languages_attributes: [:id, :description, :done, :_destroy]) 11 end 12 13 def update 14 @user = User.find_by(id: params[:id]) 15 @user.language = params[:language] 16 if params[:image] 17 @user.image_name = "#{@user.id}.jpg" 18 image = params[:image] 19 File.binwrite("public/user_images/#{@user.image_name}", image.read) 20 end 21 if params[:cover_image] 22 @user.cover_image_name = "#{@user.id}_cover.jpg" 23 cover_image = params[:cover_image] 24 File.binwrite("public/user_cover_images/#{@user.cover_image_name}", cover_image.read) 25 end 26 if @user.save 27 flash[:notice] = "ユーザー情報を編集しました" 28 redirect_to("/users/#{@user.id}") 29 else 30 render("users/edit") 31 end 32 end

該当のソースコード(application_controller.rb)

rails

1class ApplicationController < ActionController::Base 2 protect_from_forgery with: :null_session 3 before_action :set_current_user 4 5 def set_current_user 6 @current_user = User.find_by(id: session[:user_id]) 7 end 8 9 def authenticate_user 10 if @current_user == nil 11 flash[:notice] = "ログインが必要です" 12 redirect_to("/login") 13 end 14 end 15 16 def forbid_login_user 17 if @current_user 18 flash[:notice] = "すでにログインしています" 19 redirect_to("/posts/index") 20 end 21 end 22end

他に必要なコードがありましたら追記致します。どなたかお知恵を拝借頂けると幸いです。

補足情報(FW/ツールのバージョンなど)

ruby 2.6.4p104
RubyGems 3.0.3
Rails 5.2.3

追記

まだ解決していない為、問題のあったcocoonで複製した部分はコメントアウトで一旦消して、form_tagをform_withに変える作業を先に進めておりました。するとここでも、保存ボタンを押しても内容が保存されず、「/posts/index」にリダイレクトされる問題が発生しました(おそらくforbid_login_userによるもの)。
ログイン中にはアクセスできないページ(新規登録ページ等)に行こうとしている訳ではないにも関わらず、なぜこのようなリダイレクトになってしまうのかが分かりません…。

該当のソースコード(users#edit.html.erb)

Rails

1 <%= form_with(model: User, local: true) do |f| %> 2 <p> 3 <%= f.label :ユーザー名 %> 4 <%= f.text_field :name, value: @user.name %> 5 </p> 6 <p> 7 <%= f.label :画像 %> 8 <%= f.file_field :image %> 9 </p> 10 <p> 11 <%= f.label :カバー画像 %> 12 <%= f.file_field :cover_image %> 13 </p> 14 <p> 15 <%= f.label :メールアドレス %> 16 <%= f.email_field :email, value: @user.email %> 17 </p> 18 <p> 19 <%= f.label :性別 %> 20 <%= f.radio_button :sex, :Male %>男 21 <%= f.radio_button :sex, :Female %>女 22 </p> 23 <p> 24 <%= f.label :国籍 %> 25 <%= f.country_select :country, selected: @user.country %> 26 </p> 27 <p> 28 <%= f.label :言語 %> 29 <%= select_tag(:language, options_for_select(languages)) %> 30 </p> 31 <p> 32 <%= f.label :自己紹介 %> 33 <%= f.text_area :introduction, rows: "10", cols: "100", value: @user.introduction %> 34 </p> 35 <%= f.submit "保存" %> 36 <% end %>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

自己解決しました。
解決までの過程をQiitaにまとめましたのでリンクから閲覧可能です。

投稿2020/10/23 07:16

punchan36

総合スコア105

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問