suzu_ryuya
@suzu_ryuya (suzu ryu)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

テーブル同士の紐付けでuser_idを追加すると、動作しない

解決したいこと

RailsでTodoアプリを作っており、ユーザーとタスクを紐づけようとしています。タスクテーブルにuser_idカラムを追加したところ、タスクの追加ができなくなりました。エラーは出ないのですが、バリデーションに引っかかります。
解決方法を教えていただけますでしょうか.

発生している問題・エラー

入力をしているのに、空白で入力していることになりバリデーションに引っかかります。
カテゴリとタスクには、空白と最大文字にバリデーションを指定しています。
・入力するとき
スクリーンショット 2021-08-26 13.52.59.png
・入力後
スクリーンショット 2021-08-26 13.53.07.png

該当するソースコード

該当コードを以下に掲載します。

app/controllers/tasks_controller.rb
#投稿に関するコントローラー
class TasksController < ApplicationController
  #タスク一覧を表示するアクション
  def index
    #order:取得したレコードを特定のキーで並び替える。desc:大きい方から小さい方に並べる(降順)
    @tasks = Task.all.order(created_at: :desc)
  end

  #タスク追加画面にアクセスする時に呼ばれる
  def new
    @task = Task.new
  end

  #タスク追加時に呼ばれる。Create Taskボタンを押したときに実行されるアクション
  def create
    #.createはモデルの生成から保存をまとめて実行する。.newの場合は、.saveメソッドの処理も必要になる。
    #.newは生成したインスタンスを用いて処理を行いたい場合に用いることができる。if文とか
    @task = Task.new(
      title:    task_params[:title],
      category: task_params[:category],
      user_id:  current_user.id
    )
    if @task.save
      flash[:notice] = "Successful addition of task!"     #追加が成功した際に、flashメッセージを表示する。
      redirect_to tasks_path                              #_pathでトップ画面へのリンクを表す。
    else
      #エラーメッセージを表示するViewファイルを指定する。
      render 'tasks/new'
    end
  end

  #タスク編集画面にアクセスするときに呼ばれる。/tasks/:id/edit
  def edit
    @task = Task.find_by(id:params[:id]) #idカラムがparams[:id]である投稿データを取得
  end

  #タスク編集時に呼ばれる。Update Taskボタンを押したときに実行されるアクション
  def update
    #インスタンス変数にタスクをセットする。更新したいレコード(タスク)を代入する
    @task = Task.find_by(id:params[:id])
    #updateメソッドの実行 task_paramsメソッドを実行して、その戻り値をupdateメソッドの引数として使用する。
    @task.update(task_params)
    if @task.save
      flash[:notice] = "Successful edited the task!"    #追加が成功した際に、flashメッセージを表示する。
      redirect_to tasks_path                            #変更したら、トップ画面へ移動する。
    else
      flash[:alert] = "Please enter at least one character."
      redirect_to edit_task_path
    end
  end

  #タスクの削除
  def destroy
    @task = Task.find_by(id:params[:id])
    @task.destroy
    flash[:notice] = "Deleted the task!"
    redirect_to tasks_path
  end

  #外部から使えないようにする。
  #Taskモデルのtitle(タスク名)パラメータが渡ってきたときのみタスク追加を行う。
  private
  #ユーザーから悪意のある(指定したデータ以外など)パラメータが渡ってきても、安全に処理してくれる。
  #requireメソッド:データのオブジェクトを定める
  #permitメソッド:変更を加えられるキーを指定する。許可していない項目の変更はしない。
  def task_params
    params.permit(:title,:category)
  end
end
app/models/task.rb
#ApplicationRecordを継承する
class Task < ApplicationRecord
  validates :category,  presence: true, length: { maximum: 50 }
  validates :title,     presence: true, length: { maximum: 50 }
  validates :user_id,   presence: true
end
app/views/tasks/new/html.erb
<div class="container">
  <div class="form-head">
    <h1>新規タスク</h1>
  </div>
  <!--フラッシュ通知を表示させる。-->
  <% if flash[:alert] %>
  <div class="alert alert-danger">
    <%= flash[:alert] %>
  </div>
  <% end %>
  <!--特定のモデルに特化したフォームを作る:form_for-->
  <!--中身はモデルオブジェクトを書く。Taskモデルなら、@taskを渡す。(インスタンス変数)-->
  <%= form_for(@task) do |f| %>
  <!--エラーメッセージの表示 error_messages_task.html.erbにメッセージ内容を記載-->
  <%= render 'shared/error_messages_task' %>
  <form class="contact" action="index.html" method="post">
    <dl>
      <dt><%= f.label :category ,"カテゴリ"%></dt>
      <dd><%= f.text_field :category ,:size=>"60"%></dd>
      <dt><%= f.label :title ,"新規タスク"%></dt>
      <dd><%= f.text_field :title,:size=>"60" %></dd>
    </dl>
    <div class = "submit"><%= f.submit %></div>                     <!--create taskボタン-->
  </form>
  <!--create taskが押されたら、tasksコントローラーのcreateアクションが実行される。-->
  <% end %>
  <!--link_to(リンクのテキスト、パスやURL) 戻るページへのリンクをパスを用いて書いたもの-->
  <%= link_to(tasks_path) do %>
  <div class="d-grid gap-2 d-md-flex justify-content-md-center">
    <button type="button" class="btn btn-outline-primary">戻る</button>
  </div>
  <%end%>
</div>

自分で試したこと

マイグレーションファイルを確認しましたが、user_idは追加されています。

add_userid_to_tasks.rb
class AddUseridToTasks < ActiveRecord::Migration[6.1]
  def change
    add_column :tasks, :user_id, :integer
  end
end
0

1Answer

  def task_params
Rails.logger.debug "#"*20
Rails.logger.debug params.to_unsafe_hash
Rails.logger.debug "#"*20
    params.permit(:title,:category)
  end

こうするとどういう値が表示されるか確認してみて、.permitがあってるかどうか見てみるとか?

因みに.erbは

```erb
<% if flash[:alert] %>

<%= flash[:alert] %>
<% end %> \`\`\`

こう書くと綺麗に表示される。

  <% if flash[:alert] %>
  <div class="alert alert-danger">
    <%= flash[:alert] %>
  </div>
  <% end %>
0Like

Comments

  1. @suzu_ryuya

    Questioner

    返信ありがとうございます。
    実行して、ターミナルで確認したところ以下の文が出力されました。


    ```
    Started POST "/tasks" for ::1 at 2021-08-26 17:45:43 +0900
    Processing by TasksController#create as HTML
    Parameters: {"authenticity_token"=>"[FILTERED]", "task"=>{"category"=>"hello", "title"=>"hello"}, "commit"=>"Create Task"}
    ####################
    {"authenticity_token"=>"FqBqf8FbYwtgtzfMdBKZFxCfN4I_RZuiyEAqK2nJLif3qJcpirph2dfWKe4yQfqF-Qyywe3Jl7aBvXOhzZ07bA", "task"=>{"category"=>"hello", "title"=>"hello"}, "commit"=>"Create Task", "controller"=>"tasks", "action"=>"create"}
    ####################
    Unpermitted parameters: :authenticity_token, :task, :commit
    ####################
    {"authenticity_token"=>"FqBqf8FbYwtgtzfMdBKZFxCfN4I_RZuiyEAqK2nJLif3qJcpirph2dfWKe4yQfqF-Qyywe3Jl7aBvXOhzZ07bA", "task"=>{"category"=>"hello", "title"=>"hello"}, "commit"=>"Create Task", "controller"=>"tasks", "action"=>"create"}
    ####################
    Unpermitted parameters: :authenticity_token, :task, :commit
    User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 12], ["LIMIT", 1]]
    ↳ app/helpers/sessions_helper.rb:13:in `current_user'
    Rendering layout layouts/application.html.erb
    Rendering tasks/new.html.erb within layouts/application
    Rendered shared/_error_messages_task.html.erb (Duration: 0.9ms | Allocations: 861)
    Rendered tasks/new.html.erb within layouts/application (Duration: 2.8ms | Allocations: 2576)
    [Webpacker] Everything's up-to-date. Nothing to do
    Rendered layout layouts/application.html.erb (Duration: 11.1ms | Allocations: 10781)
    Completed 200 OK in 14ms (Views: 11.5ms | ActiveRecord: 0.1ms | Allocations: 12678)
    ```


    Unpermitted parameters: :authenticity_token, :task, :commitなので、taskに問題があるのでしょうか?
  2. @suzu_ryuya

    Questioner

    "task"=>{"category"=>"hello", "title"=>"hello"}
    キーがtask、値を{"category"=>"hello", "title"=>"hello"}に持つハッシュでよろしいでしょうか?

    また、params.permit(:title,:category)は、
    taskテーブルに、{"category"=>"hello", "title"=>"hello"}のデータを追加することを許可すると言う解釈でよろしいでしょうか?
  3. @suzu_ryuya

    Questioner

    わかりました。回答いただきありがとうございました。

Your answer might help someone💌