Ruby on Rails 3.2.13 アプリケーションがあり、複数のモデルに関連する 1 つのモデルがあります。シナリオを説明するために、それらの関連モデルの 1 つに関する情報を提供します。メンテナンス画面で使用する新しいビューと編集ビューがあります。私はネストされた属性を扱うのにまだかなり慣れていません。私のメンテナンス画面では、関連付けられた属性を持つ行をメンテナンスできます。選択した行を手動で取得し、親行に関連付けて書き出します。collection_select ドロップダウン リスト ボックスの一番上のリストに表示します。しかし、500 エラーのいくつかの問題の後にいくつかの最近のチェックを行ったところ、修正が必要なソフトウェアの問題がいくつかあることに気付きました。
エラーを見つけた後に編集をレンダリングする update メソッドにエラー チェック コードがあります。編集ビューを表示しようとすると、ネストされた属性の配列を見つけようとして 500 エラーが発生します。ここに私が最近得たエラーがあります。
Completed 500 Internal Server Error in 24ms
ActionView::Template::Error (undefined method `topic_id' for {"topic_id"=>[""]}:ActiveSupport::HashWithIndifferentAccess):
56: <p style="padding-left: 150px; color: #f8ee5f;"><%= display_topics @media_library %></p>
57: <% end %>
58: <%= fields_for :media_topics do |media_topic| %>
59: <%= media_topic.label :topic, "Topics" %><%= media_topic.collection_select(:topic_id, Topic.order("name_en"), :id, :name_en, {}, {multiple: true}) %>
60: <% end %><br>
61:
62: <% if @media_library.media_targets.count > 0 %>
app/views/media_libraries/_media_library_fields.html.erb:59:in `block in _app_views_media_libraries__media_library_fields_html_erb___4316101037373251257_70115028003400'
app/views/media_libraries/_media_library_fields.html.erb:58:in `_app_views_media_libraries__media_library_fields_html_erb___4316101037373251257_70115028003400'
app/views/media_libraries/edit.html.erb:7:in `block in _app_views_media_libraries_edit_html_erb__2448603971022600459_70115028733680'
app/views/media_libraries/edit.html.erb:6:in `_app_views_media_libraries_edit_html_erb__2448603971022600459_70115028733680'
app/controllers/media_libraries_controller.rb:115:in `update'
MediaTopic モデルに関連して MediaLibrary モデルを定義する方法を次に示します。私の質問に関連するモデルの部分のみを含めています。
class MediaLibrary < ActiveRecord::Base
attr_accessible :media_topics_attributes
has_many :media_topics, dependent: :destroy
accepts_nested_attributes_for :media_topics
class MediaTopic < ActiveRecord::Base
belongs_to :media_library
これが私の編集方法です:
def edit
@media_library = MediaLibrary.find(params[:id])
@edit_page = true
end
このステートメントは、Topic モデルの collection_select から選択した media_topics の配列を取得する場所です (ここで、media_topics は MediaLibrary モデルに関連する topic_id 値を取得します)。
@media_topics = params[:media_topics]
update メソッドでのエラー チェックのサンプルを次に示します。
case
when params[:link].blank? && params[:link_video].blank? && params[:link_pdf].blank? && params[:resource].blank? && params[:resource2].blank? && params[:resource3].blank?
flash.now[:error] = "You must enter at least one link before creating a Media Library Item."
render 'edit'
else
some update logic here
end
これが私の編集ビューのコードです。display_topics ヘルパーは、トピックのドロップダウン リストの上に関連するトピック行のリストを表示します。
<% if @media_library.media_topics.count > 0 %>
<p style="padding-left: 150px; color: #f8ee5f;"><%= display_topics @media_library %></p>
<% end %>
<%= fields_for :media_topics do |media_topic| %>
<%= media_topic.label :topic, "Topics" %><%= media_topic.collection_select(:topic_id, Topic.order("name_en"), :id, :name_en, {}, {multiple: true}) %>
<% end %><br>
これが display_topics ヘルパーです。
def display_topics(media_library)
media_library_topics = MediaTopic.where("media_library_id = ?", media_library.id).all
topic_list = nil;
if media_library_topics
i = 1
media_library_topics.each do |mltopic|
topic_row = Topic.find(mltopic.topic_id)
case I18n.locale.to_s
when "fr"
topic_name = topic_row.name_fr
when "pt"
topic_name = topic_row.name_pt
when "es"
topic_name = topic_row.name_es
else
topic_name = topic_row.name_en
end
if i == 1
if media_library_topics.size == 1
topic_list = "#{t :media_label_topic}: "+topic_name
else
topic_list = "#{t :media_label_topics}: "+topic_name
end
else
topic_list = topic_list+" | "+topic_name
end
i += 1
end
"#{topic_list}"
end
end
手動で追加するか、削除/再追加する以外に、nested_attributes を操作する別の方法を知りません。
私が知らないのは、「編集」をもう一度レンダリングすると、フォームからネストされた属性に何が起こるかということです。このエラーで私が見ていることから、これが消えているように見えるため、未定義のメソッド:topic_id.
この関数を開発して以来、何度も何度も検索を行ってきましたが、このエラーが言及されたことはありません。私が覚えているすべての例は、最初にレコードを表示してからエラーを表示するために、人が編集ビューを連続してレンダリングしているネストされた属性の状況を示しているわけではありません。
ネストされた属性をもう一度ビューに戻すにはどうすればよいですか?
どんな助けでも大歓迎です。