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

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

ただいまの
回答率

89.10%

ユーザー情報を編集する際にエラーメッセージを表示させたいです。

解決済

回答 3

投稿 編集

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

ikt_erk122

score 29

<やりたいこと>
アコーディオンの編集フォームで誤ったユーザー情報で更新した際にエラーメッセージを表示させたい

<困っていること>
正しい情報での更新はできるのですが誤った情報だとエラーメッセージは表示されずエラーになる

<質問>
フォームの書き方が悪いのかコントローラが悪いのかわからないのですが参考サイトやアドバイスいただけないでしょうか?

users_contoller.rb

def index
    if params[:q] && params[:q].reject { |key, value| value.blank? }.present?
      @q = User.ransack(search_params, activated_true: true)
      @title = "検索結果"
    else
      @q = User.ransack(activated_true: true)
      @title = "ユーザー一覧"
    end
    @users = @q.result.paginate(page: params[:page])
  enddef update_basic_info
    @user = User.find(params[:id])
    if @user.update_attributes(user_params)
      flash[:success] = "基本情報を更新しました。"
      redirect_to users_path 
    else
      @users = User.paginate(page: params[:page])
      flash[:danger] = "#{@user.name}さんの基本情報の更新に失敗しました。"
      render 'index'
    end
  end


index.html.erb

<% provide(:title, @title) %>
<% provide(:button_text, '更新') %>

<h1><%= @title %></h1>

<div class="row">
  <div class="search_form">
    <%= render 'users/search_form' %>
  </div>
</div>

<%= will_paginate %>

<% unless @users.empty? %>
  <ul class="users">
    <li>
      <% @users.each do |user| %>
        <%= user.name %>
        <% if current_user.admin? %><br>
          <% if !current_user?(user) %>
            <%= link_to "削除", user, method: :delete, data: { confirm: "削除してよろしいですか?" },class: "btn btn-primary" %><br>
          <% end %>
          <div class="userslist">
            <a class="btn btn-primary" data-toggle="collapse" href="#collapse<%= user.id %>">編集</a>
            <div class="collapse" id="collapse<%= user.id %>">
              <div class="panel-body">
                <%= render "user",user: user %>
              </div>
            </div>
          </div>
        <% end %>
      <% end %>
    </li>
  </ul>
<% else %>
  <p class="search">
    ユーザーが見つかりませんでした。<br>
    探しているユーザー名を確認してください。
  </p>
<% end %>

<%= will_paginate %>


_user.html.erb

<%= form_with model: user, url: update_basic_info_path(params: {id: user.id}), local: true, data: {remote: 'true'} do |f| %>

  <% if user.errors.any? %>
    <div class="alert alert-danger">
      <ul>
      <% user.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <%= f.label :name %>
  <%= f.text_field :name, class: 'form-control' %>

  <%= f.label :email %>
  <%= f.email_field :email, class: 'form-control' %>

  <%= f.label :department %>
  <%= f.text_field :department, class: 'form-control' %>

  <%= f.label :uid %>
  <%= f.text_field :uid, class: 'form-control' %>

  <%= f.label :employee_number %>
  <%= f.text_field :employee_number, class: 'form-control' %>

  <%= f.label :basic_time %>
  <%= f.time_field :basic_time, class: 'form-control' %>

  <%= f.label :work_time %>
  <%= f.time_field :work_time, class: 'form-control' %>

  <%= f.label :work_end_time %>
  <%= f.time_field :work_end_time, class: 'form-control' %>

  <%= f.label :password %>
  <%= f.password_field :password, class: 'form-control' %>

  <%= f.label :password_confirmation %>
  <%= f.password_field :password_confirmation, class: 'form-control' %>

  <%= f.submit yield(:button_text), class: "btn btn-primary" %>
<% end %>

routes.rb

Rails.application.routes.draw do
  root 'static_pages#home'
  get  '/signup',   to: 'users#new'
  get    '/login',  to: 'sessions#new'
  post   '/login',  to: 'sessions#create'
  delete '/logout', to: 'sessions#destroy'
  # get '/edit-basic-info/:id', to: 'users#edit_basic_info', as: :basic_info
  #patch 'update-basic-info',  to: 'users#update_basic_info'
  get 'users/:id/attendances/:date/edit', to: 'attendances#edit', as: :edit_attendances
  patch 'users/:id/attendances/:date/update', to: 'attendances#update', as: :update_attendances
  resources :users do
    member do
      patch 'update_basic_info'
    end
    resources :attendances, only: :create
  end
end


schema.rb

create_table "users", force: :cascade do |t|
    t.string "name"
    t.string "email"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "password_digest"
    t.boolean "admin", default: false
    t.string "department"
    t.datetime "basic_time", default: "2019-02-19 22:30:00"
    t.datetime "work_time", default: "2019-02-19 23:00:00"
    t.string "remember_digest"
    t.datetime "work_end_time", default: "2019-02-20 08:00:00"
    t.string "employee_number"
    t.string "uid"
    t.boolean "superior", default: false
    t.index ["email"], name: "index_users_on_email", unique: true
  end

イメージ説明

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • 8zca

    2019/08/20 22:39

    バリデーションをしたいということであっているでしょうか?
    例えば email にメールアドレスのフォーマット以外の文字列が入ったときにエラーにしたい等

    キャンセル

  • ikt_erk122

    2019/08/21 11:22

    はい、そうです。schemaとuserモデルを追加しておきました

    キャンセル

回答 3

check解決した方法

0

usersコントローラーのStrongParametersを変えたら解決できました

def update_basic_info
    @user = User.find(params[:id])
    if @user.update_attributes(basic_info_params)
      flash[:success] = "#{@user.name}さんの基本情報を更新しました。"
    else
      @user = User.find(params[:id])
      flash[:danger] = "#{@user.name}さんの更新は失敗しました。<br>" + @user.errors.full_messages.join("<br>")
    end
    redirect_to users_url
  end

 private
    〜 
  
    def basic_info_params
      params.require(:user).permit(:name, :email, :department, :uid, :employee_number, :password, :password_confirmation, :basic_time, :work_time, :work_end_time)
    end

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

解決するにあたっていくつか問題があります。

  • エラーメッセージを表示するところがない。
<% if model.errors.any? %>
  <div class="alert alert-warning">
    <ul>
      <% model.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
    </ul>
  </div>
<% end %>
  • flashrenderする前に用意する必要がある
render 'index'
flash[:danger] = "更新に失敗しました。"
flash.now[:danger] = "更新に失敗しました。"
render 'index'
  • render :indexした後、indexのviewで使う@usersが用意されていない
def update_basic_info
  @user = User.find(params[:id])
  if @user.update_attributes(user_params)
    flash[:success] = "基本情報を更新しました。"
    redirect_to users_path 
  else
    # @users = ...
    # @userのエラー情報を維持したまま@userを含む@usersを用意する必要があるのでやや複雑
    render 'index'
    flash[:danger] = "更新に失敗しました。"
  end
end


ひとつずつ潰していってみてください。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

Mugheatさんのに追加
form が remote: 'true' になっているので、defaultでは JSでの戻りが期待されてます。それが用意されていない。

それを用意するか remote: 'true' を削除する。
削除すると view update_basic_info がないというエラーになります。
エラーの時にどういう画面にしたいのか、redirect_to users_path がそれ?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/08/21 12:26

    回答ありがとうございます。
    remote: 'true'は消しました。
    エラー時はユーザー一覧(users_path)画面上部にエラーメッセージを表示させたいです。

    キャンセル

  • 2019/08/21 12:27

    あ、render :index 見落としてました。
    自分の習慣的に、rennder類は最後に書いているものだから。

    キャンセル

  • 2019/08/21 12:30

    > ikt_erk122 さん
    > エラー時はユーザー一覧(users_path)画面上部にエラーメッセージを表示させたいです。
    と言われてもここはあなたのために僕たちがコードを書いてあげる場ではないです。
    サンプルコードも用意していますので、自分の力で取り組んでみてください。

    キャンセル

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

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