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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

Q&A

解決済

1回答

270閲覧

Ruby(Ruby on Rails) ビューでのループの仕方について

anvinon

総合スコア38

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

0グッド

0クリップ

投稿2017/06/30 09:21

###開発環境

  • MacOS X 10.11 El Capitan
  • Ruby 2.3.1
  • Ruby on Rails 4.2.6

###発生している問題
ビューで、ループの仕方がよくわからず、困っています。下記に出来るだけ詳しく書きましたので、わかる方いらっしゃれば、ご教示願います。

###ゴール
この画像のような状態にしたいです。
イメージ説明
一番上にユーザーレビューという文字があり、その下に複数のレビューがあります。そして、レビューに複数のコメントがある状態です。

###現状
以下のような状態で、コメントが表示されていません。また、「複数のレビューに、複数のコメント」という状態になっていません。

イメージ説明

ビューは以下のソースコードのようにしました。

Ruby

1# app/views/products/show.html.erb 2 3<h2>ユーザーレビュー</h2> 4<% if @review_all.nil? %> 5 まだユーザーレビューはありません。 6<% else %> 7 <% @review_all.each do |r| %> 8 ユーザー名:<%= @review_all.find(r).name %> 9 レビュー文:<%= @review_all.find(r).text %> 10 <% @review_all.each do |c| %> 11 コメント:<%= @review_all.find(r).comments.find_by(id: c) %> 12 <% end %> 13 <% end %> 14<% end %>

コントローラーは以下のとおりです。

Ruby

1# app/controllers/products_controller.rb 2 3class ProductsController < ApplicationController 4 5 def index 6 @product_all = Product.all 7 end 8 9 def new 10 @product_new = Product.new 11 @review =Review.new 12 end 13 14 def create 15 Product.create(product_params_create) 16 redirect_to :action => "index" 17 end 18 19 def show 20 @product = Product.find(params[:id]) 21 session[:cart] ||= {} 22 session[:cart]["#{params[:id]}"] = Product.find(params[:id]) 23 @review_new = Review.new 24 session[:product_show_id] = params[:id] 25 @review_all = Review.all 26 @comment_all = Comment.all 27 end 28 29 def add 30 if session[:item] == nil then 31 session[:item] ||= {} 32 session[:item]["#{params[:id]}"] = params[:item] 33 else 34 session[:item]["#{params[:id]}"] = params[:item].to_i + session[:item]["#{params[:id]}"].to_i 35 end 36 end 37 38 39 def content 40 end 41 42 def destroy 43 product = Product.find(params[:id]) 44 product.destroy 45 end 46 47 def edit 48 @product_edit = Product.find(params[:id]) 49 end 50 51 def update 52 @product_update = Product.find(params[:id]) 53 @product_update.update(product_params_update) 54 redirect_to :action => "index" 55 end 56 57 def search 58 @products = Product.all 59 if params[:description].present? 60 @products = @products.get_by_description params[:description] 61 end 62 end 63 64private 65 def product_params_create 66 params.require(:product).permit(:price, :description, :image) 67 end 68 69 def product_params_update 70 params.permit(:price, :description, :image) 71 end 72 73end 74

モデルは以下のとおりです

Ruby

1# app/models/comment.rb 2 3class Comment < ActiveRecord::Base 4 belongs_to :user 5 belongs_to :review 6end

Ruby

1# app/models/product.rb 2 3class Product < ActiveRecord::Base 4 mount_uploader :image, ImageUploader 5 #ユーザー名による絞り込み 6 scope :get_by_description, ->(description) {where("description like ?", "%#{description}%")} 7 has_many :reviews 8end

Ruby

1# app/models/review.rb 2 3class Review < ActiveRecord::Base 4 belongs_to :user 5 belongs_to :product 6 has_many :comments 7end

Ruby

1# app/models/user.rb 2 3class User < ActiveRecord::Base 4 has_secure_password 5 validates :name, presence: true, :uniqueness => true 6 validates :email, presence: true, :uniqueness => true 7 has_many :reviews 8 has_many :comments 9end

データベースのテーブルの構造は以下の状態になっています。

psgr_db=# select * from users;
id | name | email | password_digest | created_at | updated_at
----+------+----------------------------------+--------------------------------------------------------------+----------------------------+----------------------------
71 | a | ここはメールアドレスのため消去 | $2a$10$p5DiQ7Bh1zOg71OQdOBBnuVTiuszmrS/sRS9rx8Fr2uAJFmYQZFVy | 2017-06-27 00:49:49.70169 | 2017-06-27 00:49:49.70169
72 | b | ここはメールアドレスのため消去 | $2a$10$bt4vEi9awOMxeMBlo2S/kOVYtHibapImXf4oo/kdxzMvf8JQJgCk6 | 2017-06-27 04:03:42.885492 | 2017-06-27 04:03:42.885492
(2 rows)

psgr_db=# select * from products;
id | price | description | created_at | updated_at | image
-----------+-------+-------------+----------------------------+----------------------------+--------------
980190962 | | | 2017-06-17 02:59:35 | 2017-06-17 02:59:35 |
298486374 | | | 2017-06-17 02:59:35 | 2017-06-17 02:59:35 |
980190963 | 1 | 青い時計 | 2017-06-17 05:52:30.865063 | 2017-06-17 05:52:30.865063 | watch025.png
980190964 | 2 | 白い時計 | 2017-06-17 05:53:00.457151 | 2017-06-17 05:53:00.457151 | watch001.png
(4 rows)

psgr_db=# select * from comments;
id | user_id | review_id | text | created_at | updated_at
----+---------+-----------+----------------------------------+----------------------------+----------------------------
23 | 72 | 19 | 強度がどれくらいなのかが気になる | 2017-06-29 22:37:38.241337 | 2017-06-29 22:37:38.241337
24 | 72 | 19 | 強度は結構ありますね | 2017-06-29 22:47:39.277646 | 2017-06-29 22:47:39.277646
(2 rows)

psgr_db=# select * from reviews;
id | user_id | name | text | created_at | updated_at | product_id
----+---------+------+------------------------------+----------------------------+----------------------------+------------
19 | 72 | b | 作りがしっかりとした時計です | 2017-06-29 22:35:44.657063 | 2017-06-29 22:35:44.657063 | 980190964
(1 row)

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

色々ツッコミどころ満載ですね。
とりあえず、一回公式チュートリアルをやったほうがいいかもしれません。

ruby

1 <% @review_all.each do |c| %> 2 コメント:<%= @review_all.find(r).comments.find_by(id: c) %> 3 <% end %>

ruby

1 <% @comment_all.each do |c| %> 2 コメント:<%= @review_all.find(r).comments.find_by(id: c) %> 3 <% end %>

にすればとりあえず動きそうですが
全然Railsぽくなくスマートではないので
下記のようにしてみてください。
※本題と外れますが@review_allがnilになることはありません

ruby

1# app/views/products/show.html.erb 2 3<h2>ユーザーレビュー</h2> 4<% if @review_all.blank? %> 5 まだユーザーレビューはありません。 6<% else %> 7 <% @review_all.each do |r| %> 8 ユーザー名:<%= r.name %> 9 レビュー文:<%= r.text %> 10 <% r.comments.each do |c| %> 11 コメント:<%= c.text %> 12 <% end %> 13 <% end %> 14<% end %>

また、上記だけでも動きますが
show を下記のようにするとReviewに対するコメントをあらかじめ取得するのでスピードアップが測れます。

ruby

1 def show 2 @product = Product.find(params[:id]) 3 session[:cart] ||= {} 4 session[:cart]["#{params[:id]}"] = Product.find(params[:id]) 5 @review_new = Review.new 6 session[:product_show_id] = params[:id] 7 @review_all = Review.joins(:comments).references(:comments) 8 end

投稿2017/07/03 04:44

moke

総合スコア2241

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

anvinon

2017/07/03 07:25

moke様 こちらでもご回答くださり、ありがとうございます。Railsチュートリアルは8章までしかやっていないので、続きもやります。 また、頂いたスピードアップのご回答も、勉強します。ありがとうございました。ベストアンサーとして選ばせて頂きます。
moke

2017/07/03 07:39

チュートリアル8章までやったなら、最後までやっても、絶対必要なのはこの内容だけですね 一度現在のappを作り終えてから再度、チュートリアルを見る方が勉強になるかもしれません。 そこはご自由にw ここでいうスピードアップとはRailsとDBの接続回数を減らすという意味です。 @review_all = Review.joins(:comments).references(:comments) commentsがないreviewがある場合joinsではなくincludesのがいいです。 rails5だとleft_joinsができてさらにスピードアップが測れます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問