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

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

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

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

Ruby

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

1回答

2282閲覧

Rails部分テンプレートcollectionで変数名_counterが反応してるのにjsエラーに

Romay

総合スコア40

Ruby on Rails 5

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

Ruby

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

1グッド

2クリップ

投稿2019/02/03 19:51

編集2022/01/12 10:55

前提・実現したいこと

Railsアプリ作成中です。
edit.html.erbでユーザー入力機能をAjaxで実装しています。
ユーザーが文を入力するとそのページで遷移せずに部分テンプレートが一つ追加される形です。

edit.html.erbで入力

item_controllerのcreate作動

create.js.erbを返す

create.js.erbでAjax処理

部分テンプレートを1つ追加しedit.html.erbに帰る

おそらく、部分テンプレートを1つ追加しedit.html.erbを表示する最後の動作で、変数名_counterが定義されていないと出ているのだと思います。

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

chromeの開発者ツールnetworkのPreviewに出てきたエラーです。
item_counterが違うとのこと。
しかし、edit.html.erbでは、ちゃんと連番でitem_counterが機能しています。

NameError in Items#create Showing /Users/onoryouma/projects/bucket_list/app/views/users/_item.html.erb where line #3 raised: undefined local variable or method `item_counter' for #<#<Class:0x007fe96bf14ee0>:0x007fe96f8e7af0> Did you mean? item_url Trace of template inclusion: app/views/items/create.js.erb

該当のソースコード

edit.html.erbの入力フォームと部分テンプレート呼び出し元です。

erb

1<!-- 入力フォーム--> 2<div class="content content-item"> 3 <ol> 4 <%= form_tag('/items', method: :post, remote: true) do %> 5 <input type="text" name="text" pattern=".*\S+.*" required placeholder="23文字以内で" size="23" maxlength="23" autocomplete="off" class="header-btn"> 6 <%= submit_tag "追加" ,:class => "header-btn margin-top10px" %> 7 <% end %> 8 </ol> 9</div> 10<!-- テンプレート呼び出し--> 11<div class="content content-item"> 12 <ol> 13 <% if @items.present? %> 14 <div id="item-content"> 15 <%= render partial: "item", collection: @items %> 16 </div> 17 <% end %> 18 </ol> 19</div>

item_controller該当部

rb

1def create 2 @item = Item.new(text: item_params[:text], user_id: current_user.id) 3 #Ajax仕様 4 respond_to do |format| 5 if @item.save 6 format.html { redirect_to @item, notice: '作成完了'} 7 format.json { render :show, status: :created, location: @item } 8 9 format.js 10 else 11 format.html { render :new } 12 format.json { render json: @item.errors, status: :unprocessable_entity } 13 end 14 end 15 end

create.js.erbの全部

javascript

1$("<%= escape_javascript(render partial: '/users/item', locals: { item: @item }) %>").appendTo("#item-content"); 2 3//二重送信防止のためのdisabledを取り除く 4$('form').find(':submit').removeAttr("disabled"); 5 6//submitの後に、フォームの中身を空にする 7$('form').find("textarea, :text, select").val("").end().find(":checked").prop("checked", false);

以下部分テンプレートです。
_item.html.erb

<li class="idea"> <div class="idea-text"> <div class="checked-item_<%= "#{item_counter}"%>" > <% if item.check == true %> <div class="delete-text"> <%= item.text %> </div> <% else %> <%= item.text %> <% end %> </div> </div> <div class="item-menu-right"> <%= link_to item_path(item), method: :delete , data:{ confirm: '本当によろしいですか?'}, remote: true do %> <i class="fa fa-trash fa-fw" aria-hidden="true"></i> <% end %> <!-- ここをモーダルにする --> <%= link_to edit_item_path(item), method: :get ,class: "fa-edit-margin", item_id: item.id do %> <i class="fa fa-edit fa-fw" aria-hidden="true" ></i> <% end %> <%= check_box_tag '', '', item.check, {'data-id' => item.id, 'data-user-id' => item.user_id ,class: "check_#{item_counter} option-input"} %> </div> </li> <!-- idからclass指定に変えた --> <!-- チェックつけたらdelete-textつける --> <!-- item_counterを使い、各テンプレートに連番を振っている --> <script> $(function() { $('.check_<%= "#{item_counter}"%>').on('click', function() { if ( $(this).prop('checked') == false ) { $('.checked-item_<%= "#{item_counter}"%>').removeClass("delete-text"); } else { $('.checked-item_<%= "#{item_counter}"%>').addClass("delete-text"); } }); }); </script>

試したこと

item_counterに関するviewを消したところ動きましたが、機能として必要なのでどうにかしたいです。

DrqYuto👍を押しています

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

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

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

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

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

maisumakun

2019/02/04 00:30

肝心の「item_counter」が書かれたapp/views/users/_item.html.erbのコードがないようです。
Romay

2019/02/04 05:22

忘れておりました。。。一番下に追加いたしましたのでご確認いただけますと大変嬉しいです。
perpouh

2019/02/08 06:58

_item.html.erbに渡している引数の型が違うように見えます。どこかで.classとかprintしてみてはいかがでしょう?
Romay

2019/02/09 07:36

@perpouhさん コメントありがとうございます。引数の型が違うとはどういうことでしょうか。item で渡しているのですが、これはどこかで型定義されているということでしょうか。恥ずかしながら自分で調べてみても検討がつかずにいます。
Romay

2019/02/09 07:54

今回の場合ですと、<%= item.class %>で「Item」と表示され、<%= item.text.class %>で「string」と表示されました。<%= item_counter.class %>では、「Fixnum」となりました。この型が怪しいのでしょうか。。。
perpouh

2019/02/12 01:17

`undefined local variable or method `item_counter' for #<#<Class:0x007fe96bf14ee0>:0x007fe96f8e7af0>` ここを見ると、表示されていない方(追加された部分テンプレート)に渡されている変数のクラスがItemじゃないんじゃないかと思ったのですが……読みを外しましたかね。追加もしてみましたか?
guest

回答1

0

edit.html.erbで定義している

<%= render partial: "item", collection: @items %>

のときは、collectionなので、item_counterが定義されていると思うのですが、
create.js.erbで定義している

<%= escape_javascript(render partial: '/users/item', locals: { item: @item }) %>

のときは、collectionではなく、単体のitemを使って呼び出しているので、item_counterが定義されないのではないでしょうか?

投稿2019/02/12 05:25

KNaito

総合スコア376

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

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

Romay

2019/02/12 21:44

コメントありがとうございます。おっしゃる通り、<%= escape_javascript(render partial: '/users/item', collection: @item ) %>にすることで、item_counterのエラーはでず送信される様になりました! ただ、Ajaxの表示が機能していません。。。データは保存されていますが、部分テンプレートが追加されていないようです。collectionだとこのようなことが起きるということはあるのでしょうか。
KNaito

2019/02/13 02:35

すみません、ちょっとどういう実装が良いかなかなか思いつかないのですが、例えば、呼び出す側を、<%= escape_javascript(render partial: '/users/item', locals: {item: @item, icount: @items.size+1}); %>のような感じにして、呼び出される側(_item.html.erb)では、icountが定義されていたら、item_counterの代わりにicountを使う、といった実装はどうでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問