0

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.

この関数を開発して以来、何度も何度も検索を行ってきましたが、このエラーが言及されたことはありません。私が覚えているすべての例は、最初にレコードを表示してからエラーを表示するために、人が編集ビューを連続してレンダリングしているネストされた属性の状況を示しているわけではありません。

ネストされた属性をもう一度ビューに戻すにはどうすればよいですか?

どんな助けでも大歓迎です。

4

1 に答える 1

0

私はさらに調査を行っており、フォームでfields_forを使用すると、アプリケーションにある fields_for ではなく、 f.fields_forとして指定されることに気付きました。f.fields_forを使用するようにビューを変更したところ、選択したオプションが Topic モデルのドロップダウン リストに表示されていることに気付きました。これで、他の質問で抱えていた問題が解決されることを願っています。少なくとも、500 エラーが発生しなくなりました。ビューで media_topic_attributes を使用しているため、コントローラーの MediaTopic 行を更新するためのコードをおそらく書き直します。

于 2013-08-08T21:44:58.467 に答える