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

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

ただいまの
回答率

87.35%

【Ruby on Rails】paramsでurlのidを取得できずnilになってしまいます...助けてください...

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,793

score 19

前提・実現したいこと

rails tutorialの応用で記事(tourモデル)に対してコメントする機能を実装中です。
app/wiews/tours/show.html.hamlにコメントを反映させたいと考えています。
↓の記事を参考にしました
Railsでコメント機能をつくってみよう

問題点

comments_controllerのcreateアクションで、ページのurlからtour_idの値を取得したいのですが、
params[:tour_id]がnilになってしまい困っています。
エラー自体は出ていませんがコメントが反映されていない状況です。
ご教授お願いいたします。

試したこと

binding.pryをコメント保存後にかまして@commentの中身を見てみると、tour_idがnilになっていました。
app/wiews/tours/show/index.html.hamlのurlにはidが記載されてありました

該当のソースコード

app/db/schema

ActiveRecord::Schema.define(version: 20190729131749) do

  create_table "comments", force: :cascade do |t|
    t.string   "content"
    t.integer  "user_id"
    t.integer  "tour_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["tour_id"], name: "index_comments_on_tour_id"
    t.index ["user_id"], name: "index_comments_on_user_id"
  end

  create_table "tours", force: :cascade do |t|
    t.string   "tourname"
    t.text     "tourcontent"
    t.integer  "user_id"
    t.datetime "created_at",  null: false
    t.datetime "updated_at",  null: false
    t.string   "tour_image1"
    t.string   "tour_image2"
    t.string   "tour_image3"
    t.index ["user_id", "created_at"], name: "index_tours_on_user_id_and_created_at"
    t.index ["user_id"], name: "index_tours_on_user_id"
  end

  create_table "users", force: :cascade do |t|
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.datetime "created_at",                          null: false
    t.datetime "updated_at",                          null: false
    t.string   "provider"
    t.string   "uid"
    t.string   "username"
    t.boolean  "admin_flg"
    t.string   "refresh_token"
    t.string   "access_token"
    t.string   "userimage"
    t.index ["email"], name: "index_users_on_email", unique: true
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
  end

end


app/medel/tour.rb

class Tour < ApplicationRecord

  belongs_to :user
  has_many :likes
  has_many :liked_users, through: :likes, source: :user
  has_many :comments

  mount_uploader :tourimage, ImagesUploader
  validates :user_id,presence:true
end
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable,:omniauthable


  has_many :tours, dependent: :destroy
  has_many :likes, dependent: :destroy
  has_many :liked_tours, through: :likes, source: :tour
  mount_uploader :userimage, ImagesUploader
  has_many :comments, dependent: :destroy
end


app/medel/comment.rb

class Comment < ApplicationRecord
  belongs_to :user
  belongs_to :tour
  validates_uniqueness_of :tour_id, scope: :user_id
  validates :user_id,presence:true
  validates :tour_id,presence:true
end


app/controller/comments_controller.rb

class CommentsController < ApplicationController
    def create
        @comment = Comment.new(comment_params)
        @comment.user_id = current_user.id
        @comment.tour_id = params[:id]
        binding.pry
    if @comment.save
        redirect_back(fallback_location: root_path)
    else
        redirect_back(fallback_location: root_path)
    end
    end

    def destroy
        @comment = Comment.find_by(user_id: current_user.id)
        @comment.destroy
        redirect_back(fallback_location: root_path)
    end

      private

      def comment_params
        params.require(:comment).permit(:content)
      end

end


app/controller/tours_controller.rb

class ToursController < ApplicationController

  def index
    @tours=Tour.page(params[:page]).search(params[:search])
  end

  def show
     @tour=Tour.find_by(id: params[:id])
     @comments = Comment.where(tour_id: @tour.id)
     @comment = Comment.new
  end

end


app/wiews/tours/show.html.haml

%h1.page_title ツアー詳細
.card
  .card-body
    %h4.card-title  
      %smallタイトル:
      #{@tour.tourname}
    %h6.card-subtitle.mb-2.text-muted 
      %small製作者:
      #{@tour.user.username}
    %p.card-text
    = @tour.tourcontent
    = image_tag @tour.tour_image1.to_s
    = image_tag @tour.tour_image2.to_s
    = image_tag @tour.tour_image3.to_s
    // -if alredy_liked(@tour)
    //   = link_to('いいねを取り消す',like_path(@tour.id),method: :delete)
    // -else
    //   = link_to('いいねする',likes_path(@tour.id),method: :post)
.card  
  %h3.page_title コメント一覧
  .card-body
    -@comments.each do |comment|
      %h6.card-subtitle.mb-2.text-muted 
      =comment.content
      %h6.card-subtitle.mb-2.text-muted
      ユーザー名:
      =comment.user.username
      %h6.card-subtitle.mb-2.text-muted
      =comment.created_at
      -if comment.user_id == current_user.id
        = link_to("削除",comment_path(comment.id),class:"card-link",method: :delete)
.card  
  .card-body
    %h3.page_title コメントする
    = simple_form_for(@comment) do |f|
      = f.error_notification
      .form-inputs.form_group
        = f.input :content,                       
          input_html: { autocomplete: "content",class:"form-control" } 
        =hidden_field_tag :tour_id,@tour.id
        = f.button :submit, "Comment!",
        input_html: { class:" btn btn-primary " } 


app/wiews/tours/index.html.haml

%h1.page_title tour一覧
=render "shared/search"
= page_entries_info @tours
= paginate @tours  
-@tours.each do |tour|
  .card
    .card-body
      %h4.card-title  
        %smallタイトル:
        #{tour.tourname}
      %h6.card-subtitle.mb-2.text-muted 
        %small製作者:
        #{tour.user.username}
      %p.card-text
        = tour.tourcontent
      = link_to "詳細",tour_path(tour.id),class:"card-link"
= paginate @tours  


app/config/routes.rb

Rails.application.routes.draw do


  mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
  root 'static_pages#home'
  get '/about'=>'static_pages#about'

    devise_for :users, controllers: {
    registrations: 'users/registrations',

    sessions: "users/sessions",
    omniauth_callbacks: "users/omniauth_callbacks",

  }
resources :users, :only => [:show]
resources :tours, :only => [:index,:new,:create,:show,
                            :edit,:update,:destroy]
resources :likes, :only => [:create,:destroy]
resources :comments, :only => [:create,:destroy]

  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

補足情報(FW/ツールのバージョンなど)

Rails 5.0.7.2
cloud9使用

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • winterboum

    2019/07/30 13:39

    index.htmlに問題があると思うのですが、ここに示されている index.html はshow.htmlの様に思われます。indexを見せて下さい

    キャンセル

  • k_yusuke

    2019/07/30 14:10

    回答ありがとうございます
    申し訳ございません
    質問のソースコードのパスに記載ミスがあったので訂正しました。

    変更前
    前提・実現したいこと
    app/wiews/tours/show/index.html.hamlにコメントを反映させたいと考えています。
    ソースコード
    app/wiews/tours/show/index.html.haml

    変更後
    前提・実現したいこと
    app/wiews/tours/show.html.hamlにコメントを反映させたいと考えています。
    ソースコード
    app/wiews/tours/show.html.haml

    キャンセル

  • winterboum

    2019/07/30 14:14

    ツアーのindexからツアーの詳細に行くのが問題ではないのですね?
    Commentのnewへはどのviewから行くのか、がわからないのですがそれはどれ?
    Commentの new.htmlはどんな?

    キャンセル

  • k_yusuke

    2019/07/30 14:31

    ツアーのindexからツアーの詳細に行くのは問題ありません!

    Commentのnewは用意せず、ツアー詳細ページにあるコメントフォームに入力することでCommentをcreate,destroyするように実装したいと考えています。
    その際に、ツアー詳細ページのurlからtourのidをparamsで取得して、commentのtour_idに代入したいです!その際にparamsが空になるので困っています

    キャンセル

回答 2

checkベストアンサー

0

comment_path(comment.id)

comment_path(comment.id, tour_id: @tour.id)

Commentのnewは用意せず、,,,

これとても重要な情報です。
どこからどういうcodeによってこのcontrollerに来たのか、がないと判断間違えますから

間違えた、それ削除の所だからtour_id要らないですね。ちとまって

= f.input :content
の辺りに
= hidden_field_tag :tour_id,@tour.id
をいれて下さい

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/07/30 19:38

    すみません、回答者の目線に立てていなかったです...
    winterboum様には回答のみならず、よりよい質問の仕方を教えていただき、本当に感謝しています。

    指摘していただいた点を、ソースコードに反映してみました。
    挿入する箇所はここで合っていますか??
    やはり、まだコメントはツアー詳細ページ上に反映されていないようです。
    comments_controller.rbのcreateアクション内でsave前の@tourの中身をbinding.pry覗くと
    ```
    id: nil,
    content: "wdadawdaw",
    user_id: 122,
    tour_id: nil,
    created_at: nil,
    updated_at: nil>
    ``` 
    と表示されます

    キャンセル

  • 2019/07/30 19:46

    comments_controller.rbのcreateアクション内には@tourって無いですが。
    @comment ですか?

    折角 tuor_id で渡してるのに、:id してるからです。 params を見て下さい
    @comment.tour_id = params[:id]

    キャンセル

  • 2019/07/30 21:03

    @comment.tour_id = params[:tour_id]としたところコメントが反映されました!!!
    本当にありがとうございます!!すごく嬉しいです!!

    キャンセル

0

app/controller/tours_controller.rb

  def show
     @tour=Tour.find_by(id: params[:id])
     # @like=Like.new # 使ってないですよね?コレ
     @comments = Comment.where(tour_id: @tour.id)
     @comment = Comment.new(tour_id: @tour.id)
  end

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/07/30 19:39

    回答ありがとうございます。
    指摘していただいた箇所を変更してみたのですが、やはり、まだコメントはツアー詳細ページ上に反映されていないようです。別の個所に問題があるのでしょうか???

    キャンセル

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

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

関連した質問

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