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

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

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

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

Q&A

解決済

1回答

735閲覧

Railsのシンボル変数の取得順序を制御したい

crossism

総合スコア16

Ruby on Rails 5

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

0グッド

1クリップ

投稿2019/02/16 07:09

編集2019/02/17 08:56

前提・実現したいこと

Railsで編集フォームを作っています。すでに登録されている値があればformをそれで埋めて、さらに書き換えたり追加・削除ができるような構造を想定しています。
データ構造は

  • Template と Question は1:N
  • Questionにはid,qtext,qdetail,exampleと外部キーtemplate_idがある

といった形になっています。
現状、ローカルでは以下のコードでうまくいっています。

html.erb

1class TemplatesController < ApplicationController 2 before_action :logged_in_user 34中略 56 7 def edit 8 @template=Template.find(params[:id]) 9 @category=Category.find(@template.category.id) 10 @questions=Question.where(template_id: @template.id).order(:id) 11 @submit='更新' 12 end 13 14 def update 15 @template=Template.find(params[:id]) 16 @category=Category.find(@template.category_id) 17 @questions=Question.where(template_id: @template.id).order(:id) 18 @document=Document.new 19 if @category.update_attributes(category_params) 20 if @template.update_attributes(template_params) 21 render 'show' 22 else 23 render :edit 24 # redirect_to edit_template_path, alert: "アシスタントのタイトル、概要、カテゴリ全てを入力してください。" 25 end 26 else 27 render :edit 28 # redirect_to edit_template_path, alert: "アシスタントのタイトル、概要、カテゴリ全てを入力してください。" 29 end 30 end 31 32 def destroy 33 if Template.find(params[:id]).destroy 34 redirect_to templates_path 35 else 36 render 'show' 37 end 38 end 39 40 private 41 42 def template_params 43 params.require(:template).permit(:title,:topic,:category_id,:picture,questions_attributes: [:id, :qtext, :qdetail, :example, :_destroy]).merge(user_id: current_user.id) 44 end 45 46 def category_params 47 params.require(:category).permit(:name) 48 end 49 50 # ログイン済みユーザーかどうか確認 51 def logged_in_user 52 unless logged_in? 53 flash[:danger] = "ログインしてください" 54 redirect_to login_url 55 end 56 end 57 58end

html.erb

1<%= form_for @template do |f| %> 2<%= render 'shared/temp_error_messages' %> 34中略 56<h3>質問</h3> 7<div id="questions"> 8 <%= f.fields_for :questions do |question| %> 9 <%= render 'question_fields', f: question %> 10 <% end %> 11 <div class="links"> 12 <%= link_to_add_association '+質問を追加', f, :questions, class: 'btn btn-light mb-5'%> 13 </div> 14</div> 15 16<div class="actions"> 17 <%= f.submit @submit, class: "btn btn-primary mb-5"%> 18</div> 19<% end %>

html.erb

1<div class="nested-fields"> 2 <div class="form-group"> 3 <%= f.label :qtext, "質問" ,class: 'font-weight-bold' %> 4 <%= f.text_field :qtext, class: 'form-control' %> 5 <br/> 6 <%= f.label :qdetail, "質問の意図や意味" ,class: 'font-weight-bold'%> 7 <%= f.text_field :qdetail, class: 'form-control' %> 8 <br/> 9 <%= f.label :example, "回答例" ,class: 'font-weight-bold'%> 10 <%= f.text_field :example, class: 'form-control' %> 11 <br/> 12 </div> 13 <%= link_to_remove_association "この質問を削除", f ,class: 'btn btn-danger mb-5'%> 14</div>

発生している問題・エラーメッセージ

これをHerokuでデプロイすると、なぜか編集画面でオートフィルされているぶんの質問の順序がidの逆順になります。他にもいくつか逆順になっているところがあったのですが、大部分はorder(:id)を明示的に指定することで解決したので、ローカルとHerokuで何かデフォルトの取得方法が違うのではないかと仮定しています。しかし、この編集画面だけ解決方法がわかりません。

試したこと

  • :questionsにorderを指定する→Symbolにそのメソッドはない。
  • blockを@questionsをついて使う→qtextが存在しない。
  • blockをやめてrenderにcollectionを使う→collection: @questionsにしてもquestion.qtextが使えない(render先でquestionがないと言われる)
  • params.requireを元にブラウザでソースを確認。template[questions_attributes]の引数は0,1,2…の順になっていたのに対し各formのvalue(questionのidと思われる?)は新しい順になっていたため、そこの取得順序を制御しようと試みる→変化なし(以下のコードにしました)

ruby

1questions_attributes: [:id, :qtext, :qdetail, :example, :_destroy].sort_by!{|q| q[:id]}

では変化しませんでした。

この順番を変える方法を教えていただけると助かります。
正直、問題への焦点の当て方から間違っているような気もしています。本当にこれはシンボルから取得しているのか?シンボルの対象として配列のようなインスタンスはありえるのか?など本題以外での知見、アドバイスでもありがたいです。よろしくお願いします。

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

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答1

0

ベストアンサー

fields_forの第二引数にレコードオブジェクトを指定できます。
https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-fields_for

この場合は、<%= f.fields_for :questions, @template.questions.order(:id) do |question| %>でしょうか。

ローカルと本番環境で順序が違う問題は、orderを付けなければ順序は不定になるので、使用しているDBの仕様やデータの保存状況等で違っていると思われます。

投稿2019/02/18 01:28

Kta-M

総合スコア456

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

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

crossism

2019/02/18 02:32

回答ありがとうございます。解決しました。 やはり順序は不定なのですね。 そして、fields_forの第二引数には気がつきませんでした。ドキュメントはしっかり読まないといけませんね。初期値としてインスタンスが渡せるということ、一つ勉強になりました。 お時間をいただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問