kasei_sanのブログ

かせいさんのIT系のおぼえがきです。胡乱の方はnoteとtwitterへ

Paperclip を使って Rails アプリに画像アップロード機能を追加する

やりたいこと

Rails アプリに画像アップロード機能を追加したい

方法

thoughtbot/paperclip を使う

paperclip のインストール

Gemfile

# 次のイテレーションで aws-sdk を使うが、その時に ver2 を使いたいので、Paperclipを最新のものにした
gem 'paperclip', git: 'https://github.com/thoughtbot/paperclip', tag: 'v5.0.0.beta1'

Photo model に、paperclip の設定を追加

app/models/photo.rb

class Photo < ActiveRecord::Base
  belongs_to :item
  has_attached_file :image, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/images/:style/no_image.png"
  validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/
end

Paperclip::ClassMethods#has_attached_file

has_attached_file( attachment_name, options={} )
  • attachment_name : 添付ファイルを参照する時に使用する名前。
    • 今回ならば、 photo.image_file_name のように、 attachment_name に紐付いた属性が追加される
  • options :
    • styles : オリジナルと別に、#{name}: #{size} で指定したサイズの画像を生成する
    • default_url : 画像がない場合に表示する画像のPATH

参考 : https://github.com/thoughtbot/paperclip#usage

migrate で、Photo に paperclip 用のカラムを追加

rails g migration AddImageColumnsToPhotos
class AddImageColumnsToPhotos < ActiveRecord::Migration
  def up
    add_attachment :photos, :image
  end

  def down
    remove_attachment :photos, :image
  end
end

View

app/views/items/show.html.haml

%ul
  - @item.photos.each do |photo|
    %li
      = photo.title
    %li
      = image_tag photo.image.url(:thumb)

Form

params[:photo] を許可

app/controllers/items_controller.rb

    def item_params
      params.require(:item).permit(:name, :price, photos_attributes: %i[id title image _destroy])
    end

form に file_field を追加

app/views/items/_photo_fields.haml

.nested-fields
  .field
    = f.label :title
    %br
    = f.text_field :title
    = f.file_field :image
  = link_to_remove_association 'remove', f

これで、public/system に写真がupされるようになる

.
└── photos
    └── images
        └── 000
            └── 000
                └── 001
                    ├── medium
                    │   └── IMG_8990.JPG
                    ├── original
                    │   └── IMG_8990.JPG
                    └── thumb
                        └── IMG_8990.JPG

cocoon を使って、1フォームで1対多のモデルを動的に編集できるようにする

やりたいこと

Railsで1対多のmodelがあるときに、 親modelのformで子modelを動的に追加したり削除したりしたい

方法

nathanvda/cocoon を使う

つくりかた

Gemfile

gem 'cocoon'

Item の scaffold を generate

rails g scaffold item name:string price:integer

Photo model を generate

rails g model photo title:string item_id:integer

Item と、Photo をリレーション

app/models/Photo.rb

class Photo < ActiveRecord::Base
  belongs_to :item
end

app/models/item.rb

class Item < ActiveRecord::Base
  has_many :photos, dependent: :destroy
end

db/seeds.rb

1.upto(10) do |i|
  item = Item.create(name: "item_#{i}", price: i*100)
  1.upto(5) do |j|
    item.photos << Photo.create(title: "#{i}_#{j}")
  end
end

ここで急に haml で書きたくなった

Gemfile

gem 'haml-rails'
gem 'erb2haml'
bundle install

一括変換!

rake haml:replace_erbs

ItemController#show で、 Photo を表示するように

app/controllers/items_controller.rb

    def set_item
      @item = Item.includes(:photos).find(params[:id])
    end

app/views/items/show.html.haml

%p
  %strong Name:
  = @item.name
%p
  %strong Price:
  = @item.price
%ul
  - @item.photos.each do |photo|
    %li
      = photo.title

Item の form で Photo を更新可能に

動的な追加/削除のための js ライブラリを追加

app/assets/javascripts/application.js

//= require cocoon

cocoonが使うパラメータを許可(_destroy は削除用)

app/controllers/items_controller.rb

     def item_params
       params.require(:item).permit(:name, :price, photos_attributes: %i[id title _destroy])
     end

子要素の追加/編集/削除を許可

app/models/item.rb

accepts_nested_attributes_for :photos, reject_if: :all_blank, allow_destroy: true

子要素を編集するフォームを追加

app/views/items/_form.html.haml

 %h3 Photos
 #photos
   = f.fields_for :photos do |photo|
     = render 'photo_fields', f: photo
   .links
     = link_to_add_association 'add photo', f, :photos```

app/views/items/_photo_fields.haml

.nested-fields
  .field
    = f.label :title
    %br
    = f.text_field :title
  = link_to_remove_association 'remove', f

できた!

http://localhost:3000/items

f:id:kasei_san:20160324222259p:plain

http://localhost:3000/items/2

f:id:kasei_san:20160324222330p:plain

http://localhost:3000/items/2/edit

f:id:kasei_san:20160324222358p:plain

github

https://github.com/kasei-san/relation_form_sample

参考

過去のcommitを修正したい時は、 `git commit --fixup` と `git rebase --autofixup` を使おう!

先に結論

  • 過去のcommitを修正したい時は、 git commit --fixup=#{commit番号} してから、git rebase --autofixup
  • --autofixup オプションは、 git commit --fixup した commit を自動的に fixup してくれる
  • git rebasefixup は、対象の commit を上の commit と結合させる命令

例えばこんな状態

* 8a66664 (HEAD -> refs/heads/branch) Add 02.txt
* c85bd12 Add aaa on 01.txt
* 7b24435 Add 01.txt
* a8bc429 (refs/heads/master) first commit
  • branch ブランチで、01.txt を作って、中身に 'aaa' を入れて、その後 02.txt を作った

ここで、01.txt に入れる内容は 'bbb' であったことに気づく!

さあどうする

ここで、 git commit --fixup の登場!

  • 引数に、修正対象のcommit番号を入れる
g ci --fixup=c85bd12
[branch 63cb5d4] fixup! Add aaa on 01.txt
 1 file changed, 1 insertion(+), 1 deletion(-)

すると、自動的にコミットメッセージが生成されて commit される

* 63cb5d4 (HEAD -> refs/heads/branch) fixup! Add aaa on 01.txt
* 8a66664 Add 02.txt
* c85bd12 Add aaa on 01.txt
* 7b24435 Add 01.txt
* a8bc429 (refs/heads/master) first commit

git rebase --autofixup

git rebase --autofixup すると、--fixup した commit をこんな風にいい感じにしてくれる

git rebase master -i --autofixup
pick 7b24435 Add 01.txt                
pick c85bd12 Add aaa on 01.txt         
fixup 63cb5d4 fixup! Add aaa on 01.txt 
pick 8a66664 Add 02.txt                

最終的なcommitログ

* 0423c38 (HEAD -> refs/heads/branch) Add 02.txt
* 362238a Add aaa on 01.txt
* 7b24435 Add 01.txt
* a8bc429 (refs/heads/master) first commit

c85bd1263cb5d4 が統合された!!

便利

2-3個 commit を重ねた後に、間違い気付いた場合にさっと修正できるのが気持ち良い!

追記

今回のような修正の場合は git commit --squash と、 git rebase --autosquash の方がよいかも

  • squash なので、圧縮後にコミットメッセージを修正できる

追記2

autofixup と、autosquash オプションを on にしておくと楽。

  • rebase 時に勝手に、 --autosquash --autofixup をつけてくれる

.gitconfig

[rebase]
    autofixup = true
    autosquash = true

参考

追記

first commit を rebase したい場合

git rebase -i --root 

git rebase/merge をそろそろキチンと理解する

なんなのかと

rebase

品質を落とす、品のない振る舞いをする

git rebase

つかいみち : ブランチにmasterの変更を取り込む

例えば、こんな感じに、 master と、branch_b がある場合...

* ac7957d Add 'd' in a.txt
| * 9aa15f9 (refs/heads/branch_b) Add 'c' in b.txt
| * b129f6c Add b.txt
|/
* 3d940b6 Add 'b' in a.txt
* 26ba7e0 Add a.txt
git checkout branch_b
git rebase master

git rebase master を実行すると、masterHEAD の上に、 branch_b が乗っかる感じになる

  • ブランチ分岐後に追加された変更 ac7957d の上に、 branch_b の変更が乗っかる
* a27055b (HEAD -> refs/heads/branch_b) Add 'c' in b.txt
* 7d45f1d Add b.txt
* ac7957d (refs/heads/master) Add 'd' in a.txt
* 3d940b6 Add 'b' in a.txt
* 26ba7e0 Add a.txt

上のような状態を fast-forward な関係にある という

git rebase --interactive

つかいみち : コミットの履歴を編集する

* afe1290 (HEAD -> refs/heads/make_01_txt) Add 'aaa' on 01.txt
* cccfaee Add 01.txt
* 183848b (refs/heads/master) first commit
git rebase -i 183848b

commit番号より上のcommitについて、 git rebase --interactive を行う

pick cccfaee Add 01.txt
pick afe1290 Add 'aaa' on 01.txt

# Rebase 183848b..afe1290 onto 183848b (2 command(s))
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
  • pick commitを採用
  • reword 名前変更
  • squash 上のcommitと合体
  • fixup 上のcommitと合体(commitメッセージは捨てる)

こうする

reword cccfaee Add 01.txt
fixup afe1290 Add 'aaa' on 01.txt
  • この場合、 9f6ec01 は、上のcommitと合体
  • その上で、79f2ab0 のコミットメッセージを変更

すると、commitメッセージの変更画面が出るので変更する

* 4625879 (HEAD -> refs/heads/make_01_txt) Create 01.txt
* 183848b (refs/heads/master) first commit

すっきりした!

ちなみに

  • git rebase --interactive の時に、commitの順序の入れ替えもできるので便利です

git rebase のログを見る

git reflog
4625879 HEAD@{0}: rebase -i (finish): returning to refs/heads/make_01_txt
4625879 HEAD@{1}: rebase -i (fixup): Create 01.txt
4cdf15a HEAD@{2}: rebase -i (reword): Create 01.txt
cccfaee HEAD@{3}: cherry-pick: fast-forward
183848b HEAD@{4}: rebase -i (start): checkout 183848b
afe1290 HEAD@{5}: commit: Add 'aaa' on 01.txt
cccfaee HEAD@{6}: commit: Add 01.txt
183848b HEAD@{7}: checkout: moving from master to make_01_txt
183848b HEAD@{8}: commit (initial): first commit

git rebase を元に戻したい!!

HEAD@{0}〜HEAD@{4} までが、git rebase でやったこと

git reset --hard HEAD@{5}

直前の git rebase を戻したいのであれば

git reset --hard ORIG_HEAD

mergeやreset、rebase を行った直前の HEAD (べんり!!!!!!)

git merge

ブランチ make_01_txtmaster にマージする

* afe1290 (HEAD -> refs/heads/make_01_txt) Add 'aaa' on 01.txt
* cccfaee Add 01.txt
* 183848b (refs/heads/master) first commit

git merge --ff

fast-forward な関係ならば、マージコミット無しでマージする

git merge make_01_txt --ff
* afe1290 (HEAD -> refs/heads/master, refs/heads/make_01_txt) Add 'aaa' on 01.txt
* cccfaee Add 01.txt
* 183848b first commit

fast-forward な関係じゃない場合は?

* e838a79 (HEAD -> refs/heads/master) Add 02.txt
| * afe1290 (refs/heads/make_01_txt) Add 'aaa' on 01.txt
| * cccfaee Add 01.txt
|/
* 183848b first commit

マージコミットが作られる

*   33cd880 (HEAD -> refs/heads/master) Merge branch 'make_01_txt'
|\
| * afe1290 (refs/heads/make_01_txt) Add 'aaa' on 01.txt
| * cccfaee Add 01.txt
* | e838a79 Add 02.txt
|/
* 183848b first commit

git merge --no-ff

fast-forward な関係でも、マージコミットを作る

git merge make_01_txt --no-ff
*   4084ea5 (HEAD -> refs/heads/master) Merge branch 'make_01_txt'
|\
| * afe1290 (refs/heads/make_01_txt) Add 'aaa' on 01.txt
| * cccfaee Add 01.txt
|/
* 183848b first commit

それぞれどういう時に使うの?

この辺はプロジェクト毎のルール次第のような

  • ブランチをマージする時には、コミットを1個にsquashしてからマージするとか
  • 必ず、マージコミットを作る為に --no-ff をつけるとか

git cherry-pick

特定のcommitをカレントブランチの先頭に乗っける

こんな場合

* ac7957d (HEAD -> refs/heads/master) Add 'd' in a.txt
| * 9aa15f9 (refs/heads/branch_b) Add 'c' in b.txt
| * b129f6c Add b.txt
|/
* 3d940b6 Add 'b' in a.txt
* 26ba7e0 Add a.txt

branch_b9aa15f9 を、masterHEAD にのせる

git checkout master
git cherry-pick b129f6c
* f16c177 (HEAD -> refs/heads/master) Add b.txt
* ac7957d Add 'd' in a.txt
| * 9aa15f9 (refs/heads/branch_b) Add 'c' in b.txt
| * b129f6c Add b.txt
|/
* 3d940b6 Add 'b' in a.txt
* 26ba7e0 Add a.txt

参考

次回予告

git pull --rebase を理解する

(おまけ)

本記事の git log は以下のオプションで出力してます

git log --graph --oneline --branches --decorate=full

エイリアスにしておくと便利かも

DNSを良くわかっていない自分が浸透問題を理解するまでのはなし

そもそもDNSってなんだっけ?

DNSサーバは2種類

  • コンテンツサーバ (権威DNSサーバ)
  • キャッシュサーバ
    • コンテンツサーバの内容をキャッシュするサーバ

DNSは分散構成

ドメイン取得の流れ

DNSサーバが自身が知らないドメインを調べる場合

  • ルートサーバに問い合わせを行う
  • ルートサーバは、特定のゾーンとDNSサーバの組み合わせを持っているので、「そのゾーンならば、このDNSサーバに問い合わせろ」という回答をする
  • そのまま、本当にIPを持っているDNSサーバまでたらいまわしが行われる
[ルートサーバ] -> [コンテンツサーバ] -> .... -> [コンテンツサーバ]

ついでにリゾルバの話

  • アプリケーションからドメイン問い合わせがあると、DNSに問い合わせを行って回答してくれるサービス
  • linux 系だと /etc/resolv.confDNSサーバのIPを書く
    • 社内DNSサーバだったり、プロバイダのDNSだったり、 8.8.8.8 だったり

参考

DNSのレコード

DNSに格納されている情報を レコード という よく使うレコードはこんな感じ

  • Aレコード : ホスト名と、IPv4アドレスのマッピング
  • AAAAレコード : ホスト名と、IPv6アドレスのマッピング
  • CNAMEレコード : 別名を定義
    • 1つのIPアドレス複数のホスト名を持たせたい時(バーチャルホストとか)
    • あと、www.test.com と、test.com どちらでもアクセス可能にしたい時とか?
  • NSレコード : あるゾーンについてのDNSサーバの問い合わせ先
    • 自分のゾーンの場合、自分のホストが書かれている
    • たらいまわし
  • MXレコード : あるドメイン宛てのメールをどのホスト名に渡すかのマッピング
  • PTRレコード IPv4アドレスと、ホスト名のマッピング
    • Aレコードの逆。逆引きDNSで使用
  • SOAレコード : 自分が管理しているゾーンに関しての情報

ついでに、DNSを設定する時によく聞くTTLって何?

TimeToLive

  • コンテンツサーバが設定する、キャッシュサーバがそのデータを保持して良い時間
  • 単位は秒
  • DNSのデフォルトのTTL値は86400秒(24H) らしい

DNSが浸透するってどういうこと?

DNSサーバを引っ越して、Aレコードも変更した時に、引越し先のIPアドレスにアクセスされるようになるまで時間がかかる様子

何でそんなことが起こるの?

こんな流れで、親DNSサーバの中で DNSサーバのNSレコードが延々とキャッシュされつづける ため

前提

  • ドメイン : www.example.jp
  • DNSサーバ : ns-old.example.jp
  • 前提知識 : 自分が権威を持っているゾーンのNSレコードには、自分自身を書く

引越前、旧DNSサーバのゾーン情報を親DNSサーバはキャッシュしている

DNSサーバのキャッシュ

www.example.jp. 10 IN A 192.0.2.1
example.jp. 100 IN NS ns-old.example.jp.

10秒後、Aレコードのキャッシュが切れて、NSレコードのキャッシュが残っている状態になる

DNSサーバのキャッシュ

example.jp. 90 IN NS ns-old.example.jp.

この時に、www.example.jp について問い合わせが発生

  • DNSは、NSレコードのキャッシュを元に DNS に問い合わせを行う
  • DNSは、古いIPを返す
  • その内容でAレコードがキャッシュされる
  • その後、 NSレコードのTTLがリセットされる!!!!!!

DNSサーバのキャッシュ

www.example.jp. 10 IN A 192.0.2.1
example.jp. 100 IN NS ns-old.example.jp.

元に戻ったよ!

これが延々と繰り返されると、親DNSサーバはいつまでも旧DNSの情報をキャッシュしつづけてしまうよね...

なんでTTLをリセットとかするの?

  • DNSプロトコルに違反している訳ではない
  • おそらくは無駄な問い合わせをなるべくしないようにするため?

正しい方法

DNSサーバを立てた後に、親のNSレコードを切り替える前に、 DNSサーバの自ゾーンのNSレコードを新DNSサーバに切り替えておく

  • DNSサーバはどちらにせよ、新DNSサーバに問い合わせに行くことになるため、上記の問題は発生しない

あと、 bind9.2.3では、TTLをリセットしないように実装が変更された

まとめ

浸透なんてないんだよ! 単なる設定のミスで古い情報がキャッシュされつづけるだけだよ!!

次回予告

  • digコマンドの使い方について説明する

参考

Rails高速化のためのパフォーマンスチューニングに役立つツール 8個+α

これは何?

レスポンスタイムが遅くて辛いけど原因が特定できないときに役立つツールをまとめてみました

  • Rails以外でも使えるものも一緒くたに書いているけど、気にしない!

やらないこと

それぞれのツール詳細な説明

  • 気が向いたら個別記事を書く

環境

New Relic

パフォーマンス監視サービス

  • 運用フェイズ
  • アクション実行時にどの処理にどれだけ時間が掛かったかをメトリクス収集してくれる

参考


以降のツールは基本的には開発、テスト時に使用するやつです


rack-mini-profiler

パフォーマンス計測ツール(gem)

  • アクション実行時に、ブラウザにレンダリングに掛かった処理の時間を表示してくれる

参考

bullet

N+1問題検出ツール(gem)

  • アクション実行時に、N+1問題があるとポップアップやログで警告してくれる

出力例

2009-08-25 20:40:17[INFO] N+1 Query: PATH_INFO: /posts;    model: Post => associations: [comments]·
Add to your finder: :include => [:comments]
2009-08-25 20:40:17[INFO] N+1 Query: method call stack:·
/Users/richard/Downloads/test/app/views/posts/index.html.erb:11:in `_run_erb_app47views47posts47index46html46erb'
/Users/richard/Downloads/test/app/views/posts/index.html.erb:8:in `each'
/Users/richard/Downloads/test/app/views/posts/index.html.erb:8:in `_run_erb_app47views47posts47index46html46erb'
/Users/richard/Downloads/test/app/controllers/posts_controller.rb:7:in `index'

参考

activerecord-cause

クエリの実行箇所をログに出力してくれるツール(gem)

bulletで分からないような、ビューのループの中で直接モデル読んでるみたいなヤバイ箇所を速やかに見つけるためのものです。

出力例

D, [2015-04-15T22:13:46.928908 #66812] DEBUG -- :   User Load (0.1ms)  SELECT "users".* FROM "users"
D, [2015-04-15T22:13:46.929038 #66812] DEBUG -- :   User Load (ActiveRecord::Cause)  caused by /Users/joker/srcs/activerecord-cause/spec/activerecord/cause_spec.rb:16:in `block (3 levels) in <top (required)>'

参考

stackprof & stackprof-webnav

a sampling call-stack profiler for ruby 2.1+ (gem)

  • メソッドの実行時間をメトリクス収集
  • stackprof-webnavで、収集結果をリストアップして見やすくしてくれる
  • 処理が早いので、運用フェイズで使用しても殆どボトルネックにならないらしい

出力例

参考

rack-lineprof

行単位のベンチマークツール(gem)

  • 行単位に処理に掛かった時間を表示してれる
  • 重い処理はハイライトしてくれる。便利!
  • stackprof は、処理時間の収集。rack-lineprof は特定の処理について見たい時に、みたいな使い分け?
    • stackprofで十分かもしれない

出力例

参考

rails_best_practices

静的解析ツール(gem)

  • Rails Best Practicesに沿わないコードを指摘してくれるツール
  • CIと組み合わせるべき
  • Always add DB index とかが発見されるとパフォーマンスに直結するはず

参考

module Benchmark

ベンチマークモジュール(Ruby標準)

  • 怪しいと思った部分を Benchmark.benchmark で囲むと、ベンチマークが取れる
  • 修正前/後でどれだけ処理が軽くなったか確認する時などに

参考

その他

rails-perftest

  • Rails4で本家から分離されたgem
  • パフォーマンス計測ツールらしいけど、記事が殆ど無い...?

SQL auto explain (Rails4で削除済)

Rails同梱の、処理が遅いSQLを自動的に通知してくれるツールだったけど、Rails4で削除された

ActiveRecord::Relation#explain は残っているらしいので、個別に怪しい処理をirbからexplainするのがよいかもしれない

考えていること

  • rack-mini-profilerbullet はアクションを実行した時に遅い部分を見つけるツール
  • テスト実行時に、一緒にパフォーマンス計測をして、遅い処理を見つける方法ってないものだろうか?
  • フィーチャーテスト実行時に、一緒にパフォーマンス計測とか???
  • ボトルネックを見つけたら、その部分についてはパフォーマンステストも実行する。とかが現実的なのだろうか?

TODO

参考

ツール紹介

パフォーマンスチューニングの実践

2015振り返り

本当は2015年にやりたかった...

Keep

ニンジャ学会!

  • 自分主体で何かをするということに抵抗が無くなった
  • 素晴らしい内容の本ができて、色々な方に喜んで頂けた
  • リーダーシップについての知見を得た
    • 独断で引っ張って良い。むしろそうすべき
    • 会社で小さいチームのリーダーをしていて、引っ張り方がわからなかったのが解決した
    • 自分が楽しい! と思うことと実業務の課題がリンク
  • 自分の自己評価の回復
    • これだけ素晴らしい内容の本を作れる自分も素晴らしいのでは...? と思えた
    • 自分1人だけで本を作ったら、多分これはなかった。合同誌ならでは!
  • ついでに知見をblogに書いたらtwitterがバズった
  • 学生時代からやりたかった、「自分主体で同人誌を作る」というタスクが終わった...
    • やっとこさ、学生時代から背負ってきたものを下ろせた気がする

会社に価値を提供できるようになってきた

いまさらかよ

  • ごめんなさい
  • とはいえ、ただタスクをこなすだけではなく、「会社に提供できる価値」と言うものを意識できるようになってきたと思う
  • こっちについても、自分主体で何かするということに抵抗が無くなった
  • 「業務改善の為にこれを導入したい」「この作業面倒くさいから自動化したよ!」など

blog再開

  • 10月以降あんまり書いてないけど、なんだかんだで 37 記事
    • 基礎的な内容なので、バズったものはない
  • こんなのを書いて、勉強すべきことの方向性を考えていた
    • 習得したいことメモ - kasei_sanのブログ
    • 丁度レガシーなプロジェクトから外に出て、色々新しい技術を学ばなければならない時だった
    • 随分色々やりたがってる
      • 案の定半分くらいしかできてない
    • 定期的に必要なスキルの見直し、棚卸しはしたほうが良いと思った

Problem

前半の迷走っぷり

  • 2015前半は電子工作にハマって、PICをかじっていた
  • まぁ趣味だから良いのだけど、それが仕事とリンクしたり、他との広がりがそこまで伸びるものでもないということを、自覚しながらやってしまった気がする
  • サイバーサングラスの成功を引っ張りすぎた感
  • 後、本当に習得すべきスキルからの現実逃避というか...
  • 5月のニンジャ万博でそれを一区切り出来たのは良かったと思う

自分の市場価値についての不安を払拭出来ていない

  • ついにプログラマー限界年齢に!
  • 不安に思って色々勉強をしていたが、それで不安がとれたか? というと、そんなことは無かった
  • 2016年は、この辺もうすこし掘り下げたい

防衛機制

  • 高ストレスや、プレッシャーがある時に、防衛機制を働かせてそのことに気づかずに面倒なことになったりした
    • 0か1か思考
    • 思考に柔軟性が無くなる
  • それに気づけたのはKeep
  • 防衛機制 - Wikipedia
    • 合理化(rationalization)
    • 知性化(intellectualization)

Try

  • 習得したいことのメモ 2016版を書く
  • 市場価値を上げる方法についての知見をまとめて実践する
  • 認知行動療法の本を読む