key’s Tech::Blog

渋谷で働く学生の技術Blog

スコープを活用して部分テンプレートを扱う

はじめに

環境
ruby 2.3.1
rails 5.0.0.1

スコープを上手に活用して部分テンプレートを扱うことで可読性をあげるとともに無駄のないコードを書いていこう。

背景

スコープのことなど深く考えずに部分テンプレートを量産して、インスタンス変数をlocalsで渡さずに使ってたら友人のスーパーエンジニアさいぬ君(kattyan310)に指摘されたのでそのことについてまとめておく。

実例〜解決策

localsを使わず、コントローラーで定義したインスタンス変数を使うと異なるコントローラーの時に毎回同じインスタンス変数を定義しなくてはいけないことになる。

  • localsを使わない場合
# コントローラー1
class UsersController < ApplicationController
  def index
    @names = User.all
  end
end

# ビューファイル1
<%=  render partial: "index" %>

# コントローラー2
class GroupsController < ApplicationController
  def index
     @names = Group.all
  end
end

# ビューファイル2
<%=  render partial: "index" %>

# 部分テンプレート
 <% @names.each do |name| %>
      <%= name %>
 <% end %>

また、コントローラーから部分テンプレートまではツリー構造(コントローラー→ビュー→部分テンプレート)になっているので、インスタンス変数のスコープ範囲が広すぎる。 そのため、規模が大きくなると、部分テンプレートからコントローラーで定義しているインスタンス変数を探すのが大変である。

  • localsを使う場合
# コントローラー1
class UsersController < ApplicationController
  def index
    @user_names = User.all
  end
end
# ビューファイル1
<%=  render partial: "index", locals: { names: @user_names } %>

# コントローラー2
class GroupsController < ApplicationController
  def index
    @group_names = Group.all
  end
end
# ビューファイル2
<%=  render partial: "index", locals: { names: @group_names } %>
  

# 部分テンプレート
 <% names.each do |name| %>
      <%= name %>
 <% end %>

localsで定義してあげることで、部分テンプレートが関数として捉える事ができ、どのような値を与える事でどのように値を加工して、出力してくれるのかがわかる。

また、部分テンプレートがコントローラーとは依存せず、インスタンス変数のスコープ範囲がコントローラーとビューファイルに収まり、可読性も上がる。

最後に

部分テンプレートには、変数をlocalsで渡すようにする。
理由は、

  • 可読性が上がる。
  • 異なるコントローラー毎に同じインスタンス変数を定義しなくて良い。

参考

railsguides.jp

bundle execを使ったrailsプロジェクト開発

はじめに

bundle execをなぜ使うのかということに焦点を当てて、一連の流れをまとめていこうかなと思います。


【開発環境】
OSX 10.13.1
Ruby 2.3.1
rails 5.0.6

gem install bundlerでbundlerはインストールしておいて下さい。


背景

bundlerやgemについての知識が混同していたところ、友人のスーパーエンジニアさいぬ君(@kattyan310)に色々と教えてもらったのでそれを基に自分なりにまとめていこうと思います。間違った解釈があればご指摘お願いします。

gemとbundlerについて

詳細は下記の記事などを参考にして下さい。*1

Bundlerの使い方 - Qiita

簡単に言うと、

  • gemはプログラミング言語Rubyに付属してるライブラリ管理ツール(であり、ライブラリの総称でもある。)

  • bundlerはgemのバージョン管理ツール同士の依存関係を解決・管理するためのライブラリ*2

なぜbundle execを使うのか

一言で言えば、プロジェクト内のgemを使うためです。
(bundle install --path vendor/bundleのコマンドでプロジェクト内のvendor/bundleにgemをインストールすることができます。)

bundle execなしでコマンドを打つとシステム(PC)内にインストールされたgemを利用することになります。

これを利用することで新たなプロジェクトに参加する際に新たにシステム内にgemを入れる必要もなく、gemを利用することができる。

実例

$ rails new プロジェクト名   #railsアプリケーションの新規作成

gemを追加したら

$ bundle install --parh vendor/bundle   #プロジェクト内のvendor/bundle内にgemをインストール

データベースを作成する場合、

$  bundle exec rake db:create   #データベースの作成

など、rakeやrailsなどのコマンドの時にbundle execをつければOK

※一度、--path vendor/bundleでパスを指定してあげれば、プロジェクトディレクトリ配下にあるbundleの設定が書かれた.bundle/config内にBUNDLE_PATH: vendor/bundleという設定を追加してくれるので、次回以降にgemを追加する際にはbundle installだけでOKです。

まとめ

  1. gemはbundlerで管理しよう

  2. bundle execを使うことでプロジェクト毎にgemを使い分けることが出来る

最後に

モヤモヤしてたものが少し晴れたので良かった♪(´ε` )

本記事のは初心者向けですが、もう一歩踏み出した中級者以上にはさいぬ君(@kattyan310)の下記の記事がオススメです。
sa-inu.hatenablog.com

参考

bundler、bundle execについて ※自分用メモ - Qiita

Ruby の gem をプロジェクト毎に Bundler で管理する - fugafuga.write

*1:どちらもgemをインストールすることはできるけれど、bundlerでは他のメリットもあるために基本的にbundlerを使う。メリットについてはこちら

*2:「依存関係を解決する」とは、例えばですが、rails(ver4.2.6)、mysql2(ver0.3.18)があった際にこれらは問題なく動作するとしても、rails(ver5.0.6)にした場合にmysql2(ver0.3.18)との連携が取れなくなる場合があります。(このgem同士はまずないでしょうが。。)しかし、bundlerを使うことでrails(ver5.0.6)にした場合、それと連携できるmysql2のバージョンをbundlerは探し出して入れてくれます。

undefined method `new_registration_path' in rails・・・・ 

タイトルにあるエラーが出て、プロジェクト内で検索してもrake routesでprefixから探してもnew_registration_parhなんてなかったから割と意味不明だったのと解決したけどなんでこれで解決したのかわからないからメモ

とりあえず下記のを参考にサーバー立ちなおしたら直った。。なんで。。?

deviseでrouteとかの変更した後にサーバ再起動が必要みたい - whitefox_105のコメント / はてなブックマーク

require_treeにハマった。

簡単そうなエラーのくせに割と数時間かかったのでメモ。

scssを一通り書き終わって実行したら下記のエラーが発生 f:id:key_libres:20171202210127p:plain

undefindってあるのでそもそも書いてないか、読み取る場所にない、ディレクトリの配置ミス、スペースとかスペルミスとかそんなとこかな?って思ってたけどどれを試してもダメ。

そんで諦めてできる人に聞いて見てようやく解決。(結構何人かに当たった)

原因はrequire_tree

require_treeはstylesheet以下のディレクトリを上から順番に読み取って行くから定義したところに当たる前に呼び出そうとしてるからエラーが出てるみたい。 ちゃんとapplication.scssのなかで@importで順番を考慮してやるとできた。

require_treeとかイマイチよくわかってなかったから勉強になったわ〜。

shellの変更(fishの導入!)

fish導入しました!

本格的な開発だとデフォルトのままではlogで状況把握するだけでも一苦労。 ってことで友人のスーパーエンジニアさいぬ君(@kattyan310)にfishをおすすめされたので導入して見ました✌︎('ω'✌︎ )

基本的には下記の記事を参考に入れて見た。

dev.classmethod.jp

qiita.com

qiita.com

  1. brew install fish # fishをインストール

  2. sudo vi /etc/shells # 末尾に /usr/local/bin/fish を追加

  3. chsh -s /usr/local/bin/fish # デフォルトシェルを fish に変更

  4. curl -L https://get.oh-my.fish | fish # oh-my-fishを導入

確かこれでタブ補完とか少しカラーがついたり、ブランチ名が表示されたりデフォルトである程度の機能が入ったのでよしとする。(というか記事の続きをやってみたがうまくいかなくて諦めただけw) また、やってて不満が出たらまた調べて少しづつ改造してこうかな。

githubを早く使いこなさねば。。。

githubがまだよくわからん。

とりあえず現時点で簡単に備忘録として書き留めておこう。 github Desktopとコマンドがごっちゃになってるけどとりあえずできることが大事。

[自分のみ](自分のみだとgit hub使う必要ないけどコミットととかプッシュとか慣れるために書いておく)

# リモートリポジトリの作成

1:まず右上にある+ボタンからNew repository選択  

# ローカルリポジトリの作成(projectsディレクトリで作ろう)

2:コマンドで[git clone url(git hubから貼り付ける用のurlをコピーできる)]

#ブランチの作成

3:git branch ブランチ名 (ディレクトリに注意)

# ブランチの切り替え

4:git checkout ブランチ名

# インデックスに追加

5:git add .

# コミット

6:git commit -m "コミットメッセージ"   (-mはオプションでコミットメッセージと呼ばれる)

# マージ

7:git merge ブランチ名

大雑把にこんな感じ?

*共同開発の時のはまた後でまとめます

環境構築

ん〜、初めて共同プロジェクトに参加して環境構築なるものにチャレンジしたので、それをメモ的に残してみる。 全部自分でやったわけじゃないし、ちゃんと理解してるわけじゃないから曖昧なところ多々あるけどメモなので気にしない方向で。

まずはプロジェクトのgithubのurlを教えてもらい、アクセス?の認証してもらってターミナルで git clone "url" ※urlはgit hub右上にある下記のボタンから f:id:key_libres:20171125232014p:plain

MySQLにユーザーを作成する。

$mysql -u root でmysqlにアクセス

mysql> GRANT ALL PRIVILEGES ON ???? TO '???'@'%' IDENTIFIED BY '???'; mysql> flush privileges; mysql> GRANT select ON mysql.slow_log TO ??? (slow log監視の為に権限付与)

MySQLにデータベースを作成する。

mysql> CREATE DATABASE ???? CHARACTER SET ???; mysql> SET NAMES ???; シンボリックリンクを貼る。

$ ./setup.sh npmをインストールする。Node.jsが入っていない場合は、先にインストールしてください。

$ npm i Railsのセットアップを行う。

$ bundle install --path vendor/bundle

>ここだったかな?(ちょっと時間が空いて忘れた笑)確かrmagickなんかのエラーが出ててimagemagickの6系をインストールすれば解決した気がする。

$ bundle exec rake db:migrate db dumpをもらったらインポートする。結構長いのでコーヒーでも飲んで一服していてください。

$ mysql ??? ???? < xxx.sql

あと、どこで出たか忘れたけどrubyがインストールできない問題が発生。macOS High Sierraに依存する問題のため、次の記事を参考にして解決。

taplaboratories.com

その後、とりあえず自分はrbenvを使っているので必要なバージョンをrbenv install バージョンでインストールして rbenv global バージョン => パソコンごと rbenv local バージョン => プロジェクトごとにバージョン設定できたはずなのでlocalで設定。

ん〜、他にも2点くらいこの後あったけど忘れてしまった。。 最近記憶力が落ちたので、もっと早く書くことにしよう。。反省