ajaxのhtmlとreplaceWithメソッドの違い

ajaxのhtmlとreplaceWithメソッドの違い

htmlとreplaceWithを使った際の違いを、デベロッパーツールで確認していこうと思います。

  • ajaxのhtmlとreplaceWithメソッドの違い
    • 前書き
    • htmlメソッドを使用した場合
    • replaceWithメソッドを使用した場合
    • まとめ
    • 参考リンク
続きを読む

resourcesをnestするときのshallow

resourcesをnestするときのshallow

resourcesをnestするときのURLをshallow有り・無しで比較していきたいと思います。

今回は、掲示板モデルとコメントモデルのアソシエーションを使用します。

  • resourcesをnestするときのshallow
    • shallow無し
    • Shallow有り
    • 比較
    • まとめ
続きを読む

アソシエーションを使用したデータ作成

アソシエーションを使用したデータ作成

ユーザー(user)が複数の掲示板(board)を所持している場合に、どのようにcreateするのか見ていきたいと思います。

  • アソシエーションを使用したデータ作成
    • New
    • Create
    • まとめ
続きを読む

N + 1問題について

N + 1問題について

データを表示する際に、SQL文が多く発行されてしまい、負荷が上がることです。

今回は、この対処法について記載していきます。

  • N + 1問題について
    • 対策前
    • 対策
      • 対策後
    • まとめ

続きを読む

tmuxのvim背景色

tmuxのvim背景色

tmux内でvimを使用するときに、背景色が白飛びしてしまっていたので、解決策を記載します。

  • tmux

  • vim

  • Iceberg

解決策

.tmux.conf

set -g default-terminal "screen-256color"

上記の設定では、文字の色は着きますが、背景色が白で飛んでます。

以下を追記すると、元のvimの表示と同じになります。

.vimrc

set background=dark

パーシャルへの変数の渡し方

パーシャルとは、テンプレートを別出しして再利用することです。
具体的な書き方とデバッグ内容をまとめていきます。

目次

each文

boards_controller.rb

def index
  @boards = Board.all
end


index.html.erb

<% @boards.each do |board| %>
  <%= render partial: 'list', locals: { board: board } %>
<% end %>


_list.html.erb

<% binding.pry %>


rails consoleで確認します。

[13] pry(#<#<Class:0x00007fae67c39570>>)> board.title
=> "Bellatrix Lestrange"
[15] pry(#<#<Class:0x00007fae67c39570>>)> board.body
=> "To the well-organized mind, death is but the next great adventure."


@boardsからboard変数に入れて、renderのlocalsでboard変数にboard変数を入れる形になります。 この方法は、パーシャルをeachで回した数だけ読み込んでいますので、負荷が高いです。

※今回は、seed.rbでBoardに20個データを入れているので、20回パーシャルが呼ばれることになります。
※Rendered boards/_board.html.erbが複数回行われていることが分かります。

log

Started GET "/boards" for ::1 at 2020-10-03 15:59:48 +0900                                                                                          
Processing by BoardsController#index as HTML                                                                                                        
  User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]                                       
  ↳ vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/log_subscriber.rb:98                                                         
  Rendering boards/index.html.erb within layouts/application                                                                                        
  Board Load (0.3ms)  SELECT "boards".* FROM "boards"                                                                                               
  ↳ app/views/boards/index.html.erb:16                                                                                                              
  Rendered boards/_board.html.erb (1.1ms)                                                                                                           
  Rendered boards/_board.html.erb (0.2ms)                                                                                                           
  Rendered boards/_board.html.erb (0.2ms)                                                                                                           
  Rendered boards/_board.html.erb (0.2ms)
  Rendered boards/_board.html.erb (0.2ms)
  Rendered boards/_board.html.erb (0.2ms)
  Rendered boards/_board.html.erb (0.2ms)
  Rendered boards/_board.html.erb (0.2ms)
  Rendered boards/_board.html.erb (0.2ms)
  Rendered boards/_board.html.erb (0.2ms)
  Rendered boards/_board.html.erb (0.2ms)
  Rendered boards/_board.html.erb (0.1ms)
  Rendered boards/_board.html.erb (0.2ms)
  Rendered boards/_board.html.erb (0.2ms)
  Rendered boards/_board.html.erb (0.3ms)
  Rendered boards/_board.html.erb (0.2ms)
  Rendered boards/_board.html.erb (0.4ms)
  Rendered boards/_board.html.erb (0.2ms)
  Rendered boards/_board.html.erb (0.2ms)
  Rendered boards/_board.html.erb (0.2ms)
  Rendered boards/index.html.erb within layouts/application (25.1ms)
  Rendered shared/_header.html.erb (2.1ms)
  Rendered shared/_flash_message.html.erb (0.4ms)
  Rendered shared/_footer.html.erb (0.4ms)
Completed 200 OK in 71ms (Views: 68.1ms | ActiveRecord: 0.6ms)


ちなみに、renderの書き方をまとめると
Goog

<%= render partial: 'list', locals: { board: board } %>
<%= render 'list', board: board %>


Bad(undefined local variable or method `board')

- ×   <%= render partial: 'list', board: board %>
- ×   <%= render 'list', locals: { board: board } %>

要するに、オプションを指定して書くのか、書かないのかはっきりしろということです。

collection

パーシャルにコレクションを渡すと、コレクションのメンバごとにパーシャルがレンダリングされて挿入されます。
要するに、パーシャルは一度だけレンダリングされるので、効率的だよね、ということです。
実際に書いてみましょう。

index.html.erb

<%= render partial: 'list', collection: @boards %>
undefined local variable or method `board'


:asオプションを指定してローカル変数経由でアクセスしてみます。

index.html.erb

<%= render partial: 'list', collection: @boards, as: 'board' %>


rails consoleで確認します。

[10] pry(#<#<Class:0x00007febd7b6e4d0>>)* board.title
=> "James Potter"
[11] pry(#<#<Class:0x00007febd7b6e4d0>>)> board.body
=> "Just because you have the emotional range of a teaspoon doesn’t mean we all have."


log

Started GET "/boards" for ::1 at 2020-10-03 16:03:55 +0900                                                                                          
Processing by BoardsController#index as HTML                                                                                                        
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]                                       
  ↳ vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/log_subscriber.rb:98                                                         
  Rendering boards/index.html.erb within layouts/application                                                                                        
  Board Load (0.2ms)  SELECT "boards".* FROM "boards"                                                                                               
  ↳ app/views/boards/index.html.erb:16                                                                                                              
  Rendered collection of boards/_board.html.erb [20 times] (1.9ms)                                                                                  
  Rendered boards/index.html.erb within layouts/application (8.0ms)                                                                                 
  Rendered shared/_header.html.erb (3.0ms)                                                                                                          
  Rendered shared/_flash_message.html.erb (0.3ms)                                                                                                   
  Rendered shared/_footer.html.erb (0.3ms)                                                                                                          
Completed 200 OK in 51ms (Views: 46.1ms | ActiveRecord: 0.8ms) 

これでレンダリングの数を1回に絞ることができました。
ただ、asオプションを省略するためにはどうすればいいか調べてみると、 Railsガイドに以下の記述を見つけました。

パーシャルを呼び出す時に指定するコレクションが複数形の場合、パーシャルの個別のインスタンスから、出力するコレクションの個別のメンバにアクセスが行われます。このとき、パーシャル名に基づいた名前を持つ変数が使用されます。上の場合、パーシャルの名前はproductであり、このproductパーシャル内でproductという名前の変数を使用して、出力されるインスタンスを取得できます。


パーシャル名(list)を基にした変数(lists)を使って、アクセスするよということです。
ですので、パーシャル名と変数名は揃えた方が良さそうですね。

修正してみます。
index.html.erb

<%= render partial: 'board', collection: @boards %>


ファイル名変更

mv _list.html.erb _board.html.erb


railsコンソールで確認します。

[1] pry(#<#<Class:0x00007fdcc4321f10>>)> board.title
=> "James Potter"
[2] pry(#<#<Class:0x00007fdcc4321f10>>)> board.body
=> "Just because you have the emotional range of a teaspoon doesn’t mean we all have."


log

Started GET "/boards" for ::1 at 2020-10-03 15:55:46 +0900                                                                                          
Processing by BoardsController#index as HTML                                                                                                        
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  ↳ vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/log_subscriber.rb:98                               
  Rendering boards/index.html.erb within layouts/application                                                                                        
  Board Load (0.5ms)  SELECT "boards".* FROM "boards"                                                                                               
  ↳ app/views/boards/index.html.erb:16                                                                                                              
  Rendered collection of boards/_board.html.erb [20 times] (3.4ms)                                                                                  
  Rendered boards/index.html.erb within layouts/application (13.2ms)                                                                                
  Rendered shared/_header.html.erb (1.8ms)                                                                                                          
  Rendered shared/_flash_message.html.erb (0.3ms)                                                                                                   
  Rendered shared/_footer.html.erb (0.2ms)                                                                                                          
Completed 200 OK in 68ms (Views: 61.2ms | ActiveRecord: 1.4ms)                                                                                      


こちらもレダンリングは1回になっています。

まとめ

collectionを使用して、レンダリングをまとめましょう。
次回は、N + 1問題について記載します。

railsプロセスをkillするalias登録

デバッグする際に、バックグラウンドのプロセスをキルして、rails serverを実行したかったので、aliasを登録しました。

for x in `lsof -i:3000 | awk '{print $2}' | grep -v PID` ;do kill -9 $x ;done

コマンドプロンプトで実行し、バックグラウンドのプロセスが消えたことを確認しました。 .bash_profileに記載します。

alias rstop='for x in `lsof -i:3000 | awk '{print $2}' | grep -v PID` ;do kill -9 $x ;done'

sourceすると、、

source ~/.bash_profile 
-bash: alias: } | grep -v PID` ;do kill -9 $x ;done: not found

awkのシングルクォートをエスケープする必要があるようです。

alias rstop='for x in `lsof -i:3000 | awk '\''{print $2}'\'' | grep -v PID` ; do kill -9 $x ; done'

これでいけました。