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

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

ただいまの
回答率

88.63%

User.find(params[:id]) でエラーになってしまいます。

解決済

回答 1

投稿 編集

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

muraishi

score 17

やりたいこと

ユーザー名をUser.find(params[:id])取得し、form_forでユーザー名をDBに保存したいです。

なぜできない?

下記のエラーが出てしまいます。

ActiveRecord::RecordNotFound in StaticPagesController#home
Couldn't find User with 'id'=
Extracted source (around line #8):

6
7
8
9
10
11




  end
    @timetable = Timetable.new
    @user = User.find(params[:id])
    @username = @user.name
  end


Rails.root: /home/ec2-user/environment/portfolio
Application Trace | Framework Trace | Full Trace

app/controllers/static_pages_controller.rb:8:in `home'

Request

Parameters:

None

Toggle session dump
Toggle env dump
Response

Headers:

None

記述したコード

※バリューの中にユーザー名を表示して、ユーザーに自分の名前をいちいち打たなくてもそのままデフォルトで送信すればユーザーの名前がDBに保存されるようにしたいです。
<%= form_for(@timetable) do |f| %>
  <%= f.text_field :reservation1, value: @username  %>

  <%= f.submit %>
<% end %>
lass StaticPagesController < ApplicationController
  def home
    if logged_in_as_staff?
      @micropost  = current_staff.microposts.build
      @feed_items = current_staff.feed.paginate(page: params[:page])
    end
    @timetable = Timetable.new
    @user = User.find(params[:id])
    @username = @user.name
  end

  def contact
  end

  def campaign
  end

  def new

  end
end
Rails.application.routes.draw do



  root 'static_pages#home' # => root_path
  get    '/contact',      to: 'static_pages#contact'
  get    '/campaign',     to: 'static_pages#campaign'
  get    '/signup',       to: 'users#new'
  get    '/timetable',    to: 'users#timetable'
  post   '/signup',       to: 'users#create'

  get    '/login',        to: 'sessions#new'
  post   '/login',        to: 'sessions#create'
  delete '/logout',       to: 'sessions#destroy'

  get    '/staffsignup',  to: 'staffs#new'
  post   '/staffsignup',  to: 'staffs#create'

  get    '/stafflogin',   to: 'sessions_for_staff#new'
  post   '/stafflogin',   to: 'sessions_for_staff#create'
  delete '/stafflogout',  to: 'sessions_for_staff#destroy'

  get    '/stafftimetable', to: 'timetables#timetable_index'

  resources :users
  resources :staffs
  resources :account_activations, only: [:edit]
  resources :microposts,          only: [:create, :destroy]
  resources :timetables
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

ちなみに。。。コントローラーを下記のように変更したら、無事にユーザーの名前だけ表示されました。
汚いコードだとはわかっていますが、この場合、どうすればきれいに書けるのかも教えていただきたいです!

class StaticPagesController < ApplicationController
  def home
    if logged_in_as_staff?
      @micropost  = current_staff.microposts.build
      @feed_items = current_staff.feed.paginate(page: params[:page])
    end
    @timetable = Timetable.new
    @user = User.find(1)  ←これならちゃんと取得し、名前がvalueに表示されます!
    @username = @user.name
  end

  def contact
  end

  def campaign
  end

  def new

  end
end


この下から追記です!

class TimetablesController < ApplicationController
  def timetable_index
    @timetables = Timetable.all
  end

  def new
    @timetable = Timetable.new 
  end 

  def create
  end

  def destroy
  end 

end
<% if logged_in_as_staff? %>
  <div class="row">
    <aside class="col-md-4">
      <section class="staff_info">
        <%= render 'helpers/staff_info' %>
      </section>
      <section class="micropost_form">
        <%= render 'helpers/micropost_form' %>
      </section>
    </aside>
    <div class="col-md-8">
      <h3>Micropost Feed</h3>
      <%= render 'helpers/feed' %>
    </div>
  </div>
<% else %><div class="center jumbotron">
  <h1>Thank you for comming!!</h1>
  <h2>
   ユーザー登録をしていただくと、施術内容が予約表に反映され、より正確な予約状況がわかります!
  </h2>

  <div class="btn">
    <%= link_to "登録する", signup_path, class: "btn btn-lg btn-primary" %>
  </div>
</div>

<%= render 'helpers/time_table' %>  ←このレンダーでエラーメッセージの下に記載したform_forのページを呼んでいます

<% end %>


初心者なので、なにか必要な情報など漏れているかもしれません。
よろしくお願いいたします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • siruku6

    2020/02/09 10:35

    うおお予想外なことにtimetablesコントローラーのcreateアクションが空じゃないですか..!
    たぶんですが、submitボタンを押したときにエラーになるのではなくて、そもそもhome画面自体が表示できていない、ということですかね。。

    確認ですが、deviseを使用しない方向で開発を進めるとしたらログイン認証はどうやって行いますか??
    (deviseを使うのであれば、最初は覚えることがたくさんあって大変ですが、一気に解決には近づくと思います。)

    キャンセル

  • winterboum

    2020/02/09 11:31

    >そのviewを書き出しているアクション
    はい、controllerのmethodです

    キャンセル

  • muraishi

    2020/02/09 12:15

    返事がおれくれて申し訳ないです!
    siruku6さん、
    そうなんです。サブミットボタンを押す以前に画面が表示されません!

    お二方へ。
    私のプログラミングに対する理解が浅いので、アプリケーション全体をみた方が早いと思ったので、githubにpushしました!多分みれると思います!

    https://github.com/frisk-peppermint/portfolio

    いろいろ汚いと思いますがよろしくお願いいたします!
    あと、お気づきかもしれませんが、このアプリケーションはrails tutorialを拡張した物です!

    キャンセル

回答 1

checkベストアンサー

0

params[:id]というのは、ブラウザが送信してきたパラメータの中のidと名前付けられた文字列を返します。
(routes.rbでリクエストURLからパラメータに追加できるけど、まぁブラウザが送信してることには違いない)
idパラメータをブラウザが送信していない場合はnilが返ります。

例えば、GETに対しては?id=1で1を送信する事ができるので
ブラウザのURL欄の末尾に?id=1を付け加えてエンターを押せば
@user = find(1)@user = find(params[:id])は同じ動作になりますし
Railsの_pathヘルパー等にid: 1もしくは{id: 1}を引数として渡してやれば?id=1を末尾に付ける、みたいな事をやってくれます。

ここで問題になるのが、root_pathは普通、直接アクセスしてくるものなので任意のパラメータを付け加えるのが難しいということです。

また、やりたいことを勝手に推測するとあなたがやりたいのは現在ログインしているユーザーの取得なのではないかと思います。
その場合は、いちいち現在ログインしているユーザーのidを伝搬していくのは面倒です。


このようにparamsの使用に難がある場合はsessionを用います。
詳しい説明は省きますのでRailsTutorialを読み直して欲しいのですが

app/helper/sessions_helper.rbを見る限り

@user = current_userにて現在ログインしているユーザーが取れます。

@timetable = Timetable.new
@timetable.reservation1 = current_user.name if logged_in?
<%= form_for(@timetable) do |f| %>
  <%= f.text_field :reservation1 %>

  <%= f.submit %>
<% end %>

で良かったはず

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/02/09 18:42

    詳しく説明してくださり本当にありがとうございます!root_pathの性質みたいなもの?は初めて知りました。はい、ユーザーのIDを取得してきて、それに紐づく名前(user.name)をform_forのvalueに渡すことで、ユーザーが予約を取るときに、いちいち自分の名前をフォームに打たなくてもいいようにしたいのです〜

    早速コードをStaticpaegsControllerのhomeアクションに書いてみたのですが、エラーが出てしまいました。


    ArgumentError in Users#timetable

    Showing /home/ec2-user/environment/portfolio/app/views/helpers/_time_table.html.erb where line #120 raised:

    First argument in form cannot contain nil or be empty

    Extracted source (around line #120):

    118
    119
    120
    121
    122
    123




    </div>

    <%= form_for(@timetable) do |f| %> ← ここが赤くなっています!
    <%= f.text_field :reservation1 %>

    <%= f.submit %>

    Trace of template inclusion: app/views/users/timetable.html.erb

    Rails.root: /home/ec2-user/environment/portfolio
    Application Trace | Framework Trace | Full Trace

    app/views/helpers/_time_table.html.erb:120:in `_app_views_helpers__time_table_html_erb___2205844234424230163_70100690180620'
    app/views/users/timetable.html.erb:1:in `_app_views_users_timetable_html_erb__3992942583381156466_70100690101320'

    Request

    Parameters:

    None


    私自身の根本的な力不足をすごく感じています。もう一度、復讐して、Rails に対する理解力の底上げしようと思います!!!

    キャンセル

  • 2020/02/09 19:13

    > ArgumentError in Users#timetable

    rootから/users/timetableに飛んだ後でしょうか?
    その場合、本質問と関係ない気がしますが…
    前回同様、UsersController#timetableに`@timetable = Timetable.new`をつければいいですが
    まぁ、面倒なのでview側で対処した方が楽ですね。

    <%= form_for(@timetable || Timetable.new) do |f| %>

    キャンセル

  • 2020/02/09 20:22

    おお、ちゃんと動きました!ありがとうございます!
    質問の意図が不明瞭になってしまって申し訳ないです。
    もう一度一から復習しようとおもういます。長く付き合っていただきありがとうございました!

    キャンセル

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

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

関連した質問

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