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

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

ただいまの
回答率

88.92%

[Rails5]商品モデルを別ページへ追加して、表示する処理をしたい。

受付中

回答 1

投稿

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

kioak

score 20

 前提・実現したいこと

Ruby on Railsで簡易的なサービスを作っています。
実現したい流れは以下の通りです。

検索窓で商品名を打ち込む→検索結果(商品 + 追加ボタン)を表示→
追加ボタンを押してコメント入力する→ユーザーのページ(show.html.erb)にその商品の画像を表示する
です。

ここでの「追加ボタンを押す」は、投稿に当たるため、posts_controlerを作りcreateメソッドで処理しようと考えたのですが、どのようにモデルを渡せばいいのか分からず詰まってしまっています。

このページで追加ボタンを押し、
イメージ説明

こちらの右側の空白に、「商品名」「商品画像」「商品へのコメント」を表示したいです。
イメージ説明

コメントの処理は追加ボタンの上にtext_fieldで良いかなと思っています。後に、jQueryのモーダルで処理したいと考えています。

 発生している問題・エラーメッセージ

Amazonの商品はproduct.rb(商品モデル)として存在し、title, url, image_urlのカラムを持っています。post.rbはuser_idとcontentカラムを持っていて、belongs_to: user, belongs_to: productを書いています。

エラーメッセージ

 該当のソースコード

_product_list.html.erb(検索結果の表示,商品の追加(投稿)の処理のためのビュー)  

<% if @products.present? %>
  <% @products.each do |product| %>
    <div class="list">
      <%= link_to (image_tag(product.image_url, style: "width: 80px;height: 100px;display: inline-block;")), product.url %>
      <div class="product-title">
        <%= product.title %>
      </div>
      <div class="add-reco">
      <%= form_for @post do |f| %>
        <!--<#%= f.text_field :content %>-->
        <%= f.submit "追加", class: "btn btn-primary" %>
      <% end %>
      </div>
    </div>
  <% end %>
<% end %>

posts_controller.rb(投稿する処理をしたいcreateメソッド)

class PostsController < ApplicationController
  before_action :authenticate_user!, only: [:create, :destroy]

  def create
    #@product = Product.find(params[:title])
    @post = current_user.posts.build
    @user = User.find_by_id(params[:id])

    if @post.save
      flash[:success] = "投稿が完了しました!"
      redirect_to user_path(@user)
    else
      flash[:danger] = "投稿できませんでした"
    end
  end


  def destroy
  end

  private
  def post_params
    params.require(post).permit(:content, :title, :image_url, :url)
  end
end

products_controller.rb(検索結果の表示と投稿のための処理)

class ProductsController < ApplicationController
  before_action :authenticate_user!, :except => [:search]

  def search
    @post = current_user.posts.build

    if params[:keyword].present?
      # デバックログを出力するために記述
      Amazon::Ecs.debug = true

      #Amazon::Ecs::Responseオブジェクトの取得(amazon-ecsのitem_searchメソッドを利用し、検索した結果をproductsに格納する)
      products = Amazon::Ecs.item_search(
                                params[:keyword],
                                search_index: 'All',
                                dataType: 'script',
                                response_group: 'ItemAttributes, Images',
                                country: 'jp'
      )

      # 商品のタイトル、画像のURL、詳細ページURLの取得
      @products = []
      products.items.each do |item|
        product = Product.find_or_initialize_by(title: item.get('ItemAttributes/Title'))
        product.title = item.get('ItemAttributes/Title')
        product.image_url = item.get('LargeImage/URL')
        product.url = item.get('DetailPageURL')
        if product.save
          @products << product
        else
          render :search
        end
      end
    end
  end

  def create
    #@product = Product.find(params[:title])
    @post = Product.new(product_params)
    if @post.save
      flash[:success] = '投稿されました'
      redirect_to  user_path(@user)
    else
      flash[:danger] = '投稿されません'
    end
  end
end

 試したこと

form_forのリファレンスを読んだり、検索を色々してみましたが、どのような実装が良いのか分かりませんでした。ご覧の通り、prodcts_controller、posts_controllerどちらにもcreateメソッドがありまして、どちらで処理をするのが適切か悩んでいます。(おそらくposts_controllerの方がいいですよね)

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

Rails5.2.1

語句がちゃんと使えていなければご指摘お願いします。
必要なソースコードがあれば追記します。

ヒントなどいただければと思います、よろしくお願いします

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

0

以下のようなクラス図になっているのであれば、userのリレーションを辿ってproductのデータを取得できると思います。

クラス図

<% @user.posts.each |post| %>
  <%= post.content %>
  <%= post.product.title %>
<% end %>

投稿の保存はposts_controllerでいいと思います。
投稿を保存する時にproduct_idを渡すには_product_list.html.erbでhidden_fieldを使ってproductのidを渡すのがいいかもしれません。

<% if @products.present? %>
  <% @products.each do |product| %>
    <div class="list">
      <%= link_to (image_tag(product.image_url, style: "width: 80px;height: 100px;display: inline-block;")), product.url %>
      <div class="product-title">
        <%= product.title %>
      </div>
      <div class="add-reco">
      <%= form_for @post do |f| %>
        <!--<#%= f.text_field :content %>-->
        <%= f.hidden_field :product_id, product.id %>
        <%= f.submit "追加", class: "btn btn-primary" %>
      <% end %>
      </div>
    </div>
  <% end %>
<% end %>

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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