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

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

ただいまの
回答率

89.12%

個々の記事に対してコメントを関連づけて保存したい

解決済

回答 2

投稿

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

NaojirouHisada

score 60

現在Facebookのような機能をRailsで作成しています。
ユーザは複数の記事と複数のコメントを持ち、
複数の記事は一人のユーザに帰属し、コメントも1つの記事に帰属するという関係です。

ユーザモデル
class User < ActiveRecord::Base
    has_one :member
    has_many :microposts
    has_many :comments

    has_secure_password

    accepts_nested_attributes_for :member


end

記事モデル
class Micropost < ActiveRecord::Base
  belongs_to :user
  has_many :comments
end

コメントモデル
class Comment < ActiveRecord::Base
  belongs_to :micropost 
  belongs_to :user
end

現在、ユーザコントローラとコメントコントローラをこのように記述することで、
ユーザと記事に紐付いたコメントを作成することに成功しました。

*current_userはログイン中のユーザを表しています。

ユーザコントローラ
class UsersController < ApplicationController

    def show
        @user = User.find(params[:id])
        @micropost = Micropost.find(params[:id])
        @microposts = @user.microposts
        @microposts.each do |micropost|
            @comment= micropost.comments.build
            @comment.user = current_user
        end



    end
end

コメントコントローラ

class CommentsController < ApplicationController 

    def create
        @microposts = current_user.microposts
        @comment = Comment.new(comment_params)
        @microposts.each do |micropost|
            @comment.micropost = micropost
        end
        @comment.user = current_user


        if @comment.save  
            flash[:success] = "コメントしました。"
            redirect_to root_path
        else
            render 'static_pages/home'
        end
    end
end

ですが、
どの記事にコメントしても、
最後の記事に紐付いたコメントを作成してしまいます。

INSERT INTO "comments" ("content", "micropost_id", "user_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?)  [["content", "s"], ["micropost_id", 3], ["user_id", 1], ["created_at", "2016-01-05 08:14:59.920023"], ["updated_at", "2016-01-05 08:14:59.920023"]]

これを、
ユーザの記事1に対しては、

INSERT INTO "comments" ("content", "micropost_id", "user_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?)  [["content", "s"], ["micropost_id", 1], ["user_id", 1], ["created_at", "2016-01-05 08:14:59.920023"], ["updated_at", "2016-01-05 08:14:59.920023"]]

ユーザの記事2に対しては

INSERT INTO "comments" ("content", "micropost_id", "user_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?)  [["content", "s"], ["micropost_id", 2], ["user_id", 1], ["created_at", "2016-01-05 08:14:59.920023"], ["updated_at", "2016-01-05 08:14:59.920023"]]


のように個々の記事に紐付いたコメントを作成するためには、
どう修正すればよいのでしょうか?
お手数おかけしますが、
アドバイス宜しくお願いします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

0

class Micropost < ActiveRecord::Base
   has_many  :comments
のような記述の追加が必要だということです。

上のページからの参照先
http://stackoverflow.com/questions/3732198/
に comment を新規登録する場合の ruby コード記載例があります。

  @post = Post.find(params[:post_id])
  @comment = @post.comments.build(params[:comment])
  @comment.user = User.find(current_user.id)

こんな風に commtnt <--> post,  comment <---> user の関連付けを構築していく必要があります。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/01/06 18:17

    katoyさん。
    お忙しい中、アドバイスありがとうございます(^^)

    ```
    記事モデル
    class Micropost < ActiveRecord::Base
    belongs_to :user
    has_many :comments
    end
    ```
    このように記事モデルに、
    commentsを関連づけて、
    コメントコントローラの
    def create
    Micropost.find(params[:micro post_id] )
    .....
    end
    と続けてみましたが、
    マイクロポストのIDが見つかりませんというエラーがでました(^^;)
    試しに、rails dbでデータベース内を確認しましたが、
    IDは正常に発行されていました。
    これは、
    関連づけが正常に行われていないがためにエラーになったのでしょうか(^^;)??

    キャンセル

  • 2016/01/07 07:24

    Micropost.find(params[:micro post_id] ) の実行成否は、関連づけの状態とは無関係と思います。
    Micropost.find(params[:micro post_id] ) の実行前で break して、
    Micropost.find(params[:micro post_id] ) を手作業で実行させてみてください。
    params の内容も確認してみてください。
    (break する方法がわからなければ、 params の内容を log に出しなどして確認をするとよいです)
    "rails pry" で web 検索すると、break のさせ方がわかると思います。

    キャンセル

  • 2016/01/07 18:28

    手作業で実行させてみた結果、
    ```
    [1] pry(#<CommentsController>)> Micropost.find(params[:micropost_id])
    Micropost Load (7.2ms) SELECT "microposts".* FROM "microposts" WHERE "microposts"."id" = ? LIMIT 1 [["id", nil]]
    ActiveRecord::RecordNotFound: Couldn't find Micropost with 'id'=
    from /usr/local/rvm/gems/ruby-2.2.1/gems/activerecord-4.2.1/lib/active_record/core.rb:155:in `find'
    ```
    このような結果がでました。
    MicropostのIDが正常にコメントに引き渡されていないということでしょうか?(^^;)

    キャンセル

checkベストアンサー

-1

突っ込みたいところはいっぱいありますが・・・

CommentControllerのcreateで、commentをつけたいmicropostを特定できていないので、つけようがないでしょう。
書かれているソースでは、current_userのmicropostsをすべて取得した上で、ループで回して新規に作成したcommentに次々関連づけているので、当然、自分にひも付いているmicropostの最後のものが関連づけられます。

何らかの引数で関連づけたいmicropostのidを引き渡し、Micropost.findして関連づけてあげる必要があるでしょう。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/01/06 18:22

    rifuchさんアドバイスありがとうございます。
    コメントコントローラの def create内で、

    micropostのidをMicropost.find(params[:micropost_id])で取得しようとしましたが、
    Micropostのidがないというエラーが発生していましたが、そのためでしたか(^^;)
    引き渡すのは、
    コメント投稿時に、コメント内容と共に、
    記事のIDも送信させるということでしょうか??

    お手数おかけして申し訳ございません(^^;)

    キャンセル

  • 2016/01/07 05:06

    そうなりますね。普通の流れで行けば、comment投稿の対象となるmicropostが表示されているでしょうから、そのIDをパラメータに含めておくってあげれば良いかと思います。
    また、showメソッドの中でのparams[:id]の扱いがおかしい(UserとMicropostを同じIDで検索している)ので、パラメータに何が入っているのか理解されていないのでは?と思った次第です。
    このあたり、どのパラメータに何が入っているのか、きちんと意識して実装される事をお勧めします。

    キャンセル

  • 2016/01/07 18:30

    showの部分で、
    Micropost.find(params[:micropost_id])と記述しても、
    Couldn't find Micropost with 'id'=とエラーがでたので、
    prams[:id]で行っていました(^^;)

    なるほど。
    アドバイスありがとうございます。
    一度意識してもう一度考えて行ってみます!!

    キャンセル

  • 2016/01/07 18:59 編集

    link_toメソッドやform系のメソッドでどんなURLが生成され、どんなパラメータが渡されているかをきちんと把握する必要がありそうですね。
    Railsもバージョンが上がる毎に自動生成されるURLが便利になってゆき、逆に生成されるURLやパラメータがわかりにくくなっている気がします。
    Railsガイドなんかを読みこんで、しっかり理解される事をお勧めします。
    がんばってくださいね!

    キャンセル

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

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