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

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

ただいまの
回答率

90.51%

  • Ruby

    7703questions

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

  • Ruby on Rails

    7298questions

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

  • Ruby on Rails 5

    1793questions

Ruby on Railsのエラーに関して NoMethodError in Tasks#index

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 153

dal

score 8

 前提・実現したいこと

Ruby on RailsでToDoアプリを制作しています。初心者です。
index.html.erbにて、「TODOにする」「DONEにする」をクリックすると、データベースのフラグが切り替わり(0→1または1→0)、TODO一覧にあったタスクはDONE一覧へ、DONE一覧にあったタスクはTODO一覧へ切り替わるように動作させたいです。
patchでの処理実装が上手くいかず、立ち止まっています。

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

NoMethodError in Tasks#index

Showing /home/ec2-user/environment/todo_app/app/views/tasks/index.html.erb where line #22 raised:

undefined method `toggle_status_task_path' for #<#<Class:0x0000000236d678>:0x007f3c0c01a0c8>

 該当のソースコード

index.html.erb↓

<% provide(:name, "作成") %>

<p id="notice"><%= notice %></p>

<h1>TODOアプリ</h1>
<div class="index-page">
  <%= render 'form', task: @task %>
  <div class="index-page__tasks">

    <div class="index-page__task-list">
      <h2>TODO</h2>
      <div class="task-list">
        <% @task_todo.each do |task| %>
          <div class="task-list__item task">  
            <div class="task__name"><%= task.name %></div>
            <div class="task__body"><%= task.body %></div>
            <div class="task__buttons">
              <div class="task__edit">
                <%= link_to '編集', edit_task_path(task) %>
              </div>
              <div class="task__toggle">
                <%= link_to 'DONEにする', toggle_status_task_path(task), method: :patch  %>
              </div>          
            </div>
          </div>
        <% end %>
      </div>
    </div>

    <div class="index-page__task-list">
      <h2>DONE</h2>
      <div class="task-list">
        <% @task_done.each do |task| %>
          <div class="task-list__item task">
            <div class="task__name"><%= task.name %></div>
            <div class="task__body"><%= task.body %></div>
            <div class="task__buttons">
              <div class="task__edit">
                <%= link_to '編集', edit_task_path(task) %>
              </div>
              <div class="task__toggle">
                <%= link_to 'TODOにする', toggle_status_task_path(task), method: :patch %>
              </div>          
            </div>
          </div>
        <% end %>
      </div>
    </div>
  </div>
</div>

tasks_controller.rb↓

class TasksController < ApplicationController
  before_action :set_task, only: [:show, :edit, :update, :destroy]

  # GET /tasks
  # GET /tasks.json
  def index
    # @tasks = Task.all
    @task_todo = Task.where(flag: 0)
    @task_done = Task.where(flag: 1)
    @task = Task.new
  end

  # GET /tasks/1
  # GET /tasks/1.json
  def show
  end

  # GET /tasks/new
  def new
    @task = Task.new
  end

  # GET /tasks/1/edit
  def edit
  end

  # POST /tasks
  # POST /tasks.json
  def create
    @task = Task.new(task_params)

    respond_to do |format|
      if @task.save
        # format.html { redirect_to @task, notice: 'Task was successfully created.' }
        format.html { redirect_to tasks_path, notice: 'success : 作成しました' }
        format.json { render :show, status: :created, location: @task }
      else
        format.html { render :new }
        format.json { render json: @task.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /tasks/1
  # PATCH/PUT /tasks/1.json
  def update
    respond_to do |format|
      if @task.update(task_params)
        format.html { redirect_to tasks_path, notice: 'success : 更新しました' }
        format.json { render :show, status: :ok, location: @task }
      else
        format.html { render :edit }
        format.json { render json: @task.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /tasks/1
  # DELETE /tasks/1.json
  def destroy
    @task.destroy
    respond_to do |format|
      format.html { redirect_to tasks_url, notice: 'Task was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  def toggle_status
    @task = Task.find(params[:id])
    if @task.flag == 0
      @task.update_attribute(:flag, 1)
    else
      @task.update_attribute(:flag, 0)
    end
    redirect_to tasks_path, notice: 'success : 更新しました'
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_task
      @task = Task.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def task_params
      params.require(:task).permit(:name, :body, :flag)
    end

end

routes.rb↓

Rails.application.routes.draw do
  resources :tasks
  root 'tasks#index'
  patch '/tasks/:id/toggle_status', to: 'tasks#toggle_status'
end

 試したこと

index.html.erbの
<%= link_to 'DONEにする', toggle_status_task_path(task), method: :patch  %>
や、
<%= link_to 'TODOにする', toggle_status_task_path(task), method: :patch %>
にある、toggle_status_task_path(task)を edit_task_path(task)に変えると上手くいく(挙動はこれで良い)のですが、/tasks/:id/editではなく、/tasks/:id/toggle_statusでこの処理を行いたいです。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

コマンドラインからrake routes、あるいはブラウザから/rails/info/routesにアクセスして、ルートの一覧表を確認してみましょう。

URLとセットで、そこにアクセスするためのヘルパーメソッド名が明記されています。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/11 11:32

    確認しました。
    PATCH /tasks/:id/edit(.:format) tasks#toggle_status
    と表記されています。

    キャンセル

  • 2018/06/11 11:33 編集

    同じ行の、PATCHの前にprefix(ヘルパーの名前のベースになる部分)が表示されますが、そこは空欄でしょうか。

    キャンセル

  • 2018/06/11 11:40

    空欄になってます。

    キャンセル

  • 2018/06/11 11:43

    ルーティングで「as: :something」のように、自力指定する必要があるかもしれません(そうすれば、something_pathのようにできます)。

    https://railsguides.jp/routing.html#%E5%90%8D%E5%89%8D%E4%BB%98%E3%81%8D%E3%83%AB%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0

    キャンセル

  • 2018/06/11 11:52

    試してみます。

    また、はじめにアドバイスいただいた、rake routesの結果ですが、
    PATCH /tasks/:id/edit(.:format) tasks#toggle_status
    の1行上が、
    root GET / tasks#index
    になっています。これはPATCHのprefix部分がrootということなのでしょうか?

    キャンセル

  • 2018/06/11 14:03

    as: :toggle_status_taskを指定したら、求めていた動作になりました!
    本当にありがとうございました。

    キャンセル

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

  • ただいまの回答率 90.51%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Ruby

    7703questions

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

  • Ruby on Rails

    7298questions

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

  • Ruby on Rails 5

    1793questions