【個人アプリ開発作業メモ】インスタみたいな画像一覧ページを作る

## やりたいこと
すでに画像は各投稿での表示はできているので、

![スクリーンショット 2020-08-21 午後6.43.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547640/50bd9d41-3bab-a1ec-a71d-ea8d91efe6ce.png)

各投稿の画像だけを1つのページで表示したい。

## なぜ画像一覧ページを作るのか？
今作ってるのはダイエットアプリで、身体の変化がわかるようにするため。

## 作業内容
すでに画像はデータベースに保存できてるので、あとはデータベースから取ってきて表示するだけだ。

![スクリーンショット 2020-08-21 午後7.08.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547640/0df9a2b8-a790-46b4-f894-439df8998d81.png)

この「画像一覧」を押したら、current_userが投稿した画像一覧が見れるページに遷移するようにしたい。

### 新しくビューを作る
![スクリーンショット 2020-08-21 午後7.10.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547640/63954da9-299b-e212-8104-ed9f8fb90b52.png)
「画像一覧ページ」なので「image.html.haml」というファイルをpostsディレクトリ下に配置した。

### コントローラーに新しくアクションを作る
![スクリーンショット 2020-08-21 午後7.12.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547640/390610a0-361b-01fc-c145-4f67f1687dbf.png)
posts_controllerにimageアクションを追加した。

### ルーティングを設定する

```ruby:config/route.rb
# 画像一覧ページ
get "posts/image" => "posts#image"
```
posts#imageが動くようにルーティングを設定する。

### パスを設定する
![スクリーンショット 2020-08-21 午後7.16.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547640/58fa075c-71d6-6a0e-6a38-fe2d879ef10a.png)
`$ rails routes`で確認して、以下のようにpathを設定した。
![スクリーンショット 2020-08-21 午後7.13.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547640/89a9c7f2-ea33-f39c-fe3e-065445554860.png)

ここまででposts#imageが動くようになった。

### posts#imageでcurrent_userが投稿した画像データを取得

mapメソッド？
valueメソッド？

## current_userが投稿した画像一覧ページができた
結果的に出来上がったページはこちら。
current_userが投稿した画像が新しい順で表示されてる。
![スクリーンショット 2020-08-22 午後7.26.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547640/4aeea70f-bf58-6658-835b-79836e24c9f5.png)


### 該当コードはこちら
#####コントローラー

```ruby:posts_controller.rb
def image
  @posts = Post.where(user_id: current_user.id)
end
```
これは単純にログイン中ユーザーの投稿を`@posts`というインスタンス変数に入れてビューでここから取得できるようにしてる。
##### ビュー

```ruby:image.html.haml
.content
  .images
  - @posts.each do |post|
    = image_tag post.image.url, class: "my-images"
```
ここで画像を表示するのに苦労した。

最初は後述の番外編の`@images`から取得して表示しようとしたが、これだと表示できなかった。

```ruby
- @posts.each do |post|
  = image_tag post.image.url, class: "my-images"
```
ログイン中ユーザーの投稿したpostsたちが配列の形で`@posts`に入ってるので、それをeachメソッドで1つ1つ取り出して、
その1つ1つ取り出すのに使うのが変数（ここでいうpost）。

`@posts`のにはどんな感じでposts(投稿データ)が入ってるかというと、

```ruby:ターミナル
[1] pry(#<PostsController>)> @posts
  Post Load (0.5ms)  SELECT `posts`.* FROM `posts` WHERE `posts`.`user_id` = 28
  ↳ app/controllers/posts_controller.rb:65
=> [#<Post:0x00007fc263764bc0
  id: 217,
  food: "サラダ",
  calorie: 10.5,
  protein: 10.5,
  fat: 10.5,
  carbo: 10.5,
  text: "サラダを食べました。",
  created_at: Fri, 21 Aug 2020 06:56:52 UTC +00:00,
  updated_at: Fri, 21 Aug 2020 06:56:52 UTC +00:00,
  user_id: 28,
  start_time: nil,
  image: "image6.png",
  weight: 70.5>,
 #<Post:0x00007fc263764a58
  id: 219,
  food: "サラダ",
  calorie: 10.0,
  protein: 10.0,
  fat: 10.0,
  carbo: 10.0,
  text: "サラダ",
  created_at: Fri, 21 Aug 2020 10:20:31 UTC +00:00,
  updated_at: Fri, 21 Aug 2020 10:20:31 UTC +00:00,
  user_id: 28,
  start_time: nil,
  image: "image6.png",
  weight: nil>,
```
こんな感じだ。

`@posts.image`とすることで、このうちのimageカラムを指定できる。
上記のような配列から1つ1つ取り出して、それらの`image: "image6.png"`この部分だけを取り出して、
image_tag で表示できるように`.url`を付ければOK。

### 番外編（おお!!ってなったこと）

```ruby:posts_controller.rb
def image
  @images = Post.where(user_id: current_user.id).select(:image).map{ |image| image[:image]}
end
```
結構感動したのがこれ。

binding.pryするとどうなるかというと、

```ruby
[1] pry(#<PostsController>)> Post.where(user_id: current_user.id).select(:image).map{ |image| image[:image]}
  User Load (0.4ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 28 ORDER BY `users`.`id` ASC LIMIT 1
  ↳ (pry):2
  Post Load (0.4ms)  SELECT `posts`.`image` FROM `posts` WHERE `posts`.`user_id` = 28
  ↳ (pry):2
=> ["image6.png", "image6.png", "image5.png", "image4.png"]
```
こんな感じで、画像データを配列の形で取得している。

```ruby:posts_controller.rb
def image
  @images = Post.where(user_id: current_user.id).select(:image).map{ |image| image[:image]}
end

# Post Postモデルの
# .where(user_id: current_user.id) ログイン中ユーザーの投稿を検索して取得
# .select(:image) imageカラムだけ取得
```
ここまでは簡単。

てっきりこれで画像データを取得できると思ったらできない。

ここまででbinding.pryするとどうなるかというと、

```ruby
=> [#<Post:0x00007fc261c86290 id: nil, image: "image6.png">,
 #<Post:0x00007fc261c85fe8 id: nil, image: "image6.png">,
 #<Post:0x00007fc261c85cc8 id: nil, image: "image5.png">,
 #<Post:0x00007fc261c85a20 id: nil, image: "image4.png">]
```
こんな感じで画像のurl以外の情報も出てきてしまうのだ。

どうすれば`image6.png`この部分だけ取り出せるかと試行錯誤した結果、上記のやり方で取得できた。

結果的に使わなかったけれど、こういう形で取得できるんだとわかったので、勉強になった。