Progate Ruby on Rails5 振り返り

#プロゲート Ruby on Railsコース所感

プログラミングの学習に200時間ほど費やし、Railsコースに着手しました。
今までの学習ではスムーズに進んでこれたものの、今回は苦戦。
道場コース4の内容は完全には理解できていません。
復習できるように、メモとして記録を残します。

***

#マイグレーションファイル関連
マイグレーションファイルとは：データベースを作成するときの設計図。
モデルとは：テーブルを操作するための特殊なクラス
　　
モデルの作成

```
rails g model Post content:text 
```
rails g model モデル名 カラム名:データ型
※モデル名は単数系で指定する。
　　
マイグレーションファイルの作成

```
rails g migration add_image_name
```

#URLから値を取得する
ルーティングでハッシュを指定する。

```rb:routes.rb
get "posts/:id" => "posts#show"
```

params[ハッシュ]とすることで取得できる

```rb:controller.rb
def show
  @id = params[:id]
end
```

※params[:~~]で取得できる値は文字列であるため、比較等を行う場合には整形すること。

#フォームの送信先の設定
```erb:posts/new.html.erb
<%= form_tag("/posts/create") do%>
<% end %>
```
doを忘れないこと

#post時のリンク記述方法
第三引数としてメソッドのpostを指定する。

```
<%= link_to("削除する","/posts/#{@post.id}/destroy",{method: "post"})%>
<% end %>
```

#データベースへの保存処理での分岐
if ~~~の部分で保存処理は実行されていることに注意
(真偽値を返すだけではない)

```
def update
  @post = Post.find_by(id: params[:id])
  if @post.save
    redirect_to("/posts/index")
  else
    redirect_to("/posts/#{@post.id}/edit")
  end
end
```

#データベースを経由せず、直接ビューに表示する（render）
render(コントローラー名/ビュー名)と指定する

```
def update
  @post = Post.find_by(id: params[:id])
  if @post.save
    redirect_to("/posts/index")
  else
    render("posts/edit")
  end
end
```

#画像の送信欄
typeの指定を忘れないこと

```
<input name="image" type="file">
```

#画像の送信フォーム
{multipart: true}を指定する

```
<%= form_tag("~~~",{multipart: true}) do%>
```

#送信された画像の保存処理
受け取ったparams[:image]に対して、readメソッドを活用し画像データの中身を取得する。
File.binwrite("ファイルの場所","ファイルの中身")

```
  def update
    @user = User.find_by(id: params[:id])
    @user.name = params[:name]
    @user.email = params[:email]
    @user.image_name = "#{@user.id}.jpg"
    image = params[:image]

    if params[:image]
      File.binwrite("public/user_images/#{@user.image_name}",image.read)
    end
  end
```

#セッションの設定
ページを移動しても、ユーザー情報を保持し続けるために、sessionという特殊な変数を活用する。
sessionに代入された値はブラウザに保存される。

```
session[:user_id] = @user.id
```

#共通変数の定義
application.html.erbは全アクションから呼び出される。
そのため、全アクションで活用する変数を定義すると効率が良い。
before_action :アクション名　とすることでアクションが呼び出される前に「アクション名」が実行される。

```rb:application.rb
before_action :set_current_user

def set_current_user
  @current_user = User.find_by(id: sessino[:user_id])
end
```

#<font color="Red">投稿テーブル</font>に持たせたuser_id<font color="Red">から</font>別テーブルに存在するユーザー情報を取得する
使用するデータが存在するテーブル（ここではPostモデル）に対してアクションを定義する

```rb:post.rb
def user
  return User.find_by(id: self.user_id)
end
```

活用例(投稿から、それに紐づくユーザーを取得する）

```rb:posts_controller.rb
def show
  @post = Post.find_by(id: params[:id])
  @user = @post.user
end
```

#<font color="Red">ユーザーテーブル</font>に持たせたid<font color="Red">から</font>別テーブルに存在する投稿情報を取得する
使用するデータが存在するテーブル（ここではUserモデル）に対してアクションを定義する

```rb:user.rb
def posts
  return Post.where(user_id: self.id)
end
```
 
活用例（ユーザーから、それに紐づく投稿を全て取得し表示する）

```erb:show.html.erb
<% @user.posts.each do |post|%>
  <img src="<%= "/user_images/#{post.user.image_name}" %>">
  <%= link_to(post.user.name, "/users/#{post.user.id}") %>
  <%= link_to(post.content, "/posts/#{post.id}") %>
<% end%>
```

#各ユーザーがいいねした投稿の一覧表示
 ルーティングの指定

```rb:routes.rb
get "users/:id/likes" => "users#likes"
```
アクションの定義

```rb:users.controller.rb
def likes
  @user = User.find_by(id: params[:id])
  @likes = Like.where(user_id: @user.id)
end
```
ビューでの表記

```erb:likes.html.erb
<% @likes.each do |like|%>
  <% post = Post.find_by(id: like.post_id)%>
  <img src="<%= "/user_images/#{post.user.image_name}" %>">
  <%= link_to(post.user.name, "/users/#{post.user.id}") %>
  <%= link_to(post.content, "/posts/#{post.id}") %>
<% end%>
```
二行目のLikeテーブルのpots_idを用いて、対応する投稿を取得する部分を忘れないように。


***