元祖若手のプログラミング奮闘記

元祖若手の奮闘記。主にメモ

【Vue.js】Gifを出したりしまったりする

app.html

<html>
<head>
  <title>Gif TEST</title>
</head>
<body>
  <h1>Gif TEST</h1>

  <div id="app">
    <div v-if="isLoading">
      <label>Loading Now!!</label>
      <img src="loading.gif"><!-- どっかからgifを取ってきてください。。 -->
    </div>
    Check this out!!<input type="checkbox" v-model="isLoading">
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script src="app.js"></script>
</body>
</html>


app.js

var app = new Vue({
  el: "#app",
  data: {
    isLoading: false
  }
})





Rails3.2.22.5 => 5.1.5 への道 コンフィグ編

  • config.whiny_nilsは、

nilにidメソッドが送信された場合に警告を表示するためのオプションでした。
たとえば@modelが初期化されていない状態で@model.idを取ろうとしたときに警告されます。
Rubyでは初期化されていないインスタンス変数はnilを返します。
nil.idを実行すれば普通にNoMethodErrorが表示されためRails4以降では不要となりました※(1)

  • config.cache_classesは、

アプリケーションのクラスやモジュールをリクエストごとに再読み込みするか(=キャッシュしないかどうか)どうかを指定します。

  • config.cache_classesのデフォルト値は、developmentモードではfalseなのでコードの更新がすぐ反映され、

testモードとproductionモードではtrueなので動作が高速になります。同時にthreadsafe!をオンにすることもできます。

  • config.eager_load は、

Rails のモデルやコントローラーであるクラス(app 以下にあるクラス、設定次第でこの限りでない)
をブート時に全て読み込むかどうか のフラグです。
全部読み込んでたら時間かかるため development = false
Rails起動(ブート)時に読んだ方が最初のリクエストを速く捌けるため production = true
がデフォルトです。

  • config.consider_all_requests_localは、

trueにすると、すべてのエラーをブラウザに表示をすることができる。
falseに設定すると、ブラウザには詳細情報が表示されない。

  • config.action_controller.perform_caching は、

「ページキャッシュ」「アクションキャッシュ」「フラグメントキャッシュ」といった
各キャッシュを使用する際に有効にする必要があります。
デフォルトではproduction環境でのみ有効になります。
Railsのフラグメントキャッシュは本体に組み込まれており、デフォルトで利用できます。
ページキャッシュやアクションキャッシュを利用するには、
Gemfileにactionpack-page_caching gemやactionpack-action_caching gemを追加する必要があります。※(3)

  • config.action_mailer.raise_delivery_errors は、

falseの場合メールが送れていなくてもエラーメッセージが表示されません。

  • active_support.deprecation_behavior は、

環境に対する非推奨レポート出力を設定します。
development環境ではデフォルトで:log、
production環境ではデフォルトで:notify、
test環境ではデフォルトで:stderrが指定されます。
config.active_support.deprecationに値が設定されていない場合、このイニシャライザは、
現在の環境に対応するconfig/environmentsファイルに値を設定するよう促すメッセージを出力します。
値の配列を設定することもできます

  • config.assets.debug は、

有効の場合、application.css/jsと個別のファイルの二重読み込みがされます。

  • config.assets.compressはRails 4で廃止されました。

CSSおよびJavaScriptアセットの圧縮を制御するには、
config.assets.css_compressorおよびconfig.assets.js_compressorを使用します。※(1)

  • config.assets.js_compressorは、

アセット圧縮方式の指定につかわれます。
sass-rails gemがGemfileに含まれていれば自動的にCSS圧縮に使用されます。
この場合config.assets.css_compressorオプションは設定されません。

  • config.assets.quiet は、

有効にするとアセット関連のログを出ないようになります。※(2)
Rails4の場合は
gem 'quiet_assets', group: :development
とGemfileに記述する必要があります。

  • config.action_controller.asset_hostは

アセットを置くためのホストを設定します。
これは、アセットをホストする場所としてアプリケーションサーバーの代りに
CDN(コンテンツ配信ネットワーク)を使用したい場合に便利です

  • config.assets.digestは

pipelineを通した後のファイルにつく数字をつけるかどうかです。
付けてあげるとキャッシュに残っているものも変更を加えることが出来るのでproductionではtrueが良さそう。

  • config.active_record.whitelist_attributes

Rails4以降はStrongParameterを使用するため廃止
Rails model でnew する際に
newで許可する値を制限することを
attr_accessibleで制御するかという設定※(1)

config.assets.compile = false
trueにすると、アセットが見つからないときに自動でコンパイルを試みてくれる。


■ config/initializers/配下のファイルについて

  • config/initializers/application_controller_renderer.rb

Rails 5からcontroller外でテンプレートをrender出来るようにする為の
ActionController::Rendererというクラスが追加されていて、
そこで使用するデフォルトのRack environmentを設定する為のinitializer。




※(1) Rails3のみもの
※(2) Rails5から追加されたもの

※(3)ページキャッシュ機能 アクションキャッシュ機能は、Rails 4本体から取り除かれ、gem化されました。
actionpack-page_caching gem (https://github.com/rails/actionpack-page_caching)
actionpack-action_caching gem (https://github.com/rails/actionpack-action_caching)をご覧ください。
新しい推奨メソッドについては、DHH's key-based cache expiration overview (http://signalvnoise.com/posts/3113-how-key-based-cache-expiration-works)をご覧ください。

pyenv 3.7.0 install 失敗した話

バージョンはこんな感じ

Pythonが現場で必要になったので
新しいバージョンをひとまずインストール

$ pyenv install 3.7.0
ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?

Please consult to the Wiki page to fix the problem.
https://github.com/pyenv/pyenv/wiki/Common-build-problems

失敗!
ここを見てくれと
言われているので
見てみる

github.com

だが何しても同じエラーで
怒られるってことで
Issue を見ているといい感じのやつ発見

https://github.com/pyenv/pyenv/issues/1184


最終的にこの手順で解決した

brew install 'openssl@1.1'
CONFIGURE_OPTS="--with-openssl=$(brew --prefix openssl)" pyenv install 3.7.0
$ pyenv versions
* system (set by /Users/z.kyoichi.yamada/.anyenv/envs/pyenv/version)
  3.7.0

次からCONFIGURE_OPTSが必要になるのかなと
思ったりしたのでした。

入力したものを計算させるだけのJavaScript

そんなものを作ってみた!

<html>
<head>
  <title>山田がテストするってよ</title>
</head>
<body>
  <h1>Javascriptが計算しまーす</h1>
  <form name="omitsumori">
    <ul>
      <li>X: <input type="text" name="x" size="10" maxlength="10"></li>
      <li>Y: <input type="text" name="y" size="10" maxlength="10"></li>
      <li>Z: <input type="text" name="z" size="10" maxlength="10"></li>
      <li>計: <div id="capacity"></div></li>
    </ul>
  </form>

  <script type="text/javascript">
  <!--
    // window.onload => 最後に読み込む
    window.onload = function() {
      // onblur => 入力フォームからカーソルが離れたときに動くイベント
      document.omitsumori.x.onblur = function() { checkCapacityAndAdd(); }
      document.omitsumori.y.onblur = function() { checkCapacityAndAdd(); }
      document.omitsumori.z.onblur = function() { checkCapacityAndAdd(); }
    }

    function checkCapacityAndAdd() {
      // 成功 => 1以上, 失敗 => 0
      var add_capacity = addCapacity();

      // id="capacity"の中身を入れる
      var capacity = document.getElementById("capacity");
      if (add_capacity > 0) {
        capacity.innerText = add_capacity;
      } else {
        // 失敗なら空文字を入れる
        capacity.innerText = "";
      }
      
    }

    function addCapacity(){
      // form name="omitsumori"にすることで document.omitsumori と記述すれば連携する
      var omitsumori_form = document.omitsumori;

      // 取得できなかったら処理終了
      if (!omitsumori_form) return 0;

      // 各値を代入
      // parseInt => 良しなに整数に変える関数
      var capacity_list = [
        parseInt(omitsumori_form.x.value),
        parseInt(omitsumori_form.y.value),
        parseInt(omitsumori_form.z.value),
      ];

      for (var i in capacity_list) {
        // 存在しなければループ終了
        if (!capacity_list[i]) {
          return 0;
        }
      }

      // 全部かける
      var total_size = capacity_list[0] * capacity_list[1] * capacity_list[2];

      // TODO: 少数を切り上げる
      return total_size;
    }
  //-->
  </script>
</body>
</html>

Rails3.2.22.5 => 5.1.5 への道

■役たったコマンド

git co feature/rails5.1.5 spec/controllers/

これでブランチの一部をマージできる!地味にうれしい!

bundle exec rails app:update

これで初期設定はほぼやってくれる
Rails4ならこっち

bundle exec rake rails:update

勝手に作られた
configファイル

      create  config/secrets.yml
      create  config/cable.yml
      create  config/puma.rb
      create  config/spring.rb
      create  config/initializers/application_controller_renderer.rb
      create  config/initializers/assets.rb
   identical  config/initializers/backtrace_silencers.rb
      create  config/initializers/cookies_serializer.rb
      create  config/initializers/cors.rb
      create  config/initializers/filter_parameter_logging.rb

逆に設定ファイルがあるせいで
エラーが出ることがある
一応
バックアップファイルとしておいてるけど挙動が不安スグル


■エラー集

Model

・countの罠

ActiveRecord::StatementInvalid: Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near

こんなエラーがでたら

test = model.select("aaa, bbb, ccc").where(hoge: 0)

してから

test.count

をすると

select count(aaa, bbb, ccc) from hage where hoge = 0;

というようなSQLが発行され
Syntaxエラーになる

正解はこちら

test.size

・has_many, has_one, be_longsto系
conditios,orderは今後一切使えないので

has_one :hoge, order: :hoge_rank, condtions: ["hoge_rank >= 0", 0]
has_one :hoge, -> { where("hoge_rank >= ?", 0).order(:hoge_rank) } 

と修正
そもそもconditiosが必要ないModel設計が
今回のバージョンアップで一番大切だと学んだ
正直これ直すのめちゃ辛かった。

・undefined method `sanitize`
Rails5から

ActiveRecord::Base::sanitize

は使えなくなりました!


・Modelから通常のハッシュクラスにしたい

users = User.where(sex: 1).map(&:attributes)

これでなるので
to_jsonにするときとかは非常に大事だと思う


MySQL geometry型

位置情報で使われるgeometry型
Rails5からto_jsonするとこけるようになった
今回はGem入れて変換とかじゃなくて
使われてなかったので値を消した。

・eager_loadで勘違い
モデルのincludesは
preload => joins しない
eager_load => joins する
って感じらしいのとプラス
基本は
preload が使用されるらしい

ちなみにConfigのeager_load
はTrueであると
modelとは一切関係なく
サーバー起動前にapp配下のオブジェクトのNilCheckをしてくれるというやさしいやつ

・join, orderの書き方

User.joins(:item).order(:num)

というようなOrderの書き方に注意

Rails3だと

select users.* from users inner join items on items.user_id = users.id order by num;

と発行されるが
Rails5だと

select users.* from users inner join items on items.user_id = users.id order by users.num;

になるので
usersテーブルにnumカラムがないとエラーが起きるぞ!
ちゃんと

order("#{Item.table_name}.num")

と書こう!

・NOT NULL制約のカラムは入力必須に

Rails3は見ていなかったが
Rails5からはNOT NULL制約をみるようになった

usersテーブル
name NOT NULL
age NOT NULL

だとしたら

user = User.new
user.name = "hogehoge"
user.save

でエラーになる(当たり前っちゃ当たり前だが)

user.age = 100

も追加しよう


・belongs_to の罠
valid?っでかなり変なエラーが追加されるのでなんぞや??
って調べまくっていたら
relationで設定されている値がNullになっていると
エラーを出すようになったらしい。
Nullの可能性もあるよって時は

optional: true

をbelongs_toの最後に追加することで解決した


・配列と見せかけActiveRecode::Relationクラス

users = ::User.where(status: 0).all
# Rails5だとエラーになる
users << ::User.where(status: 1).all

また
普通の配列のようにslice
を使うと
これは配列じゃないだよと怒り出すので

User.all.to_a.slice(1, 3)

見たいに使おう

Controller

Javascriptでアクセスされてもいい場合

Security warning: an embedded <script> tag on another site requested protected JavaScript. If you know what you're doing, go ahead and disable forgery protection on this action to permit cross-origin JavaScript embedding.
protect_from_forgery except: :index

見たいな書き方でエラーではなくなる


・before_filterはうごかないぜ
before_actionへ切り替えや!

・params permit
ちゃんとしろよ!
permit してないのに

params[:user][:name].gsub(/ruby/, "perl")

とかしたらおこだぞ!


・Browserクラスの引数が変更

# botの場合はログに残さない
ua = URI.decode(request["HTTP_USER_AGENT"])
browser = Browser.new(ua: ua)

こんなコードを見つけたんだが

正しくは

browser = Browser.new(ua)

である

ActionController::Parametersオブジェクトに対して
with_indifferent_accessは使えない

with_indifferent_access
とはHash変数の引数を文字列でもシンボルでも受け取れるようになる関数

使用するためには

.to_h.with_indifferent_access

としなくてはいけない

・render text
はもう使えない

render plain: "OK"

に変更

Route

・asオプションに注意

get 'hoge', to: 'hoge#index' as: 'hoge'
get 'huge/:id', to: 'hoge#show', as: 'hoge' # => 二個あるよ!エラー

・match 使うなら
vi オプションでHTTPメソッドの指定をしないといけなくなりました!

match 'admin' => 'admin#show', via: :get

ActiveRecord::PendingMigrationError

未実行のマイグレーションファイルがあるぜ
Rails3は未実行でもエラーを起こさなかったことが逆にすごい。。

Rspec

Rspec unknown keywordについて
Rails5限定みたい

get :show, id: 1

だとだめで
正しくは

get :show, params: { id: 1 }

とparams変数に入れないといけない

Rails 5 からコントローラーのテストで assigns などを使う場合

rails-controller-testing

gem 必要です!
さらにいうとrequest specへ
移行することが好ましいようです!

レンダリングページ

expect(response).to render_template("hogehoge")

こんな書き方をしていたら
Controller名も追加してテンプレート名を正しい値を入れる

expect(response).to render_template("hage/_hogehohge")

その他


・invalid byte sequence in UTF-8
これが厄介すぎる
普通の文字列のはずなのに
なぜかUTF-8じゃないって怒られて

image_tag
javascript_include_tag
stylesheet_link_tag
とか一切動かない
fileコマンド打ってみたらasciiがあったけども。。

=> 原因不明のままだが
Scssファイルの構文エラーを直し

bundle exec rails precompile

したら直る


・scssの設定がこけるこける
@include
@mixin not found
なんとかしないと

https://rubygems.org

正規表現のエラー

The provided regular expression is using multiline anchors (^ or $), which may present a security risk. Did you mean to use \A and \z, or forgot to add the :multiline => true option?

先頭、末尾を

^ $

から

\A \z

を使用
大体モデルで使ってるので
モデルに記載して終了


Cookieの形が違う

TypeError (incompatible marshal file format (can't be read)
    format version 4.8 required; 123.34 given):

意外とガッツリはまったw

bundle exec rails app:update

で作成された下記ファイル
config/initializers/cookies_serializer.rb

ails.application.config.action_dispatch.cookies_serializer = :json

と指定していたらいつの間にか
上のエラーが出てびっくりした
ブラウザキャッシュを消すことで
収まったがこの設定はもう必要ないかな。。

・lib配下のモジュールを使う
config/application.rb
に下記を追加することで
lib配下のモジュールを使うことができた

config.paths.add 'lib', eager_load: true

・ブロック無しのlink_toは引数の数を三つ以内じゃないとエラー

link_to("hoge", "https://hogehoge/hage", a_options, b_options) => ×
link_to("hoge", "https://hogehoge/hage", a_options.reverse_merge(b_options)) => ○

JqueryのVerによって書き方違った

$('a[href^=#hoge-]').on('click', function() {});

unrecognized expressionとエラーがでて
失敗するので

$('a[href^="#hoge-"]').on('click', function() {});

とかいてクォーテーションで囲もう

VargrantのguestOSのversionが合ってなくてエラーになってたのを直した

お世話になっているvargrant
なんかごにょごにょしたらエラーが出てしまった

$ vagrant up
(前略)
[default] GuestAdditions versions on your host (5.1.28) and guest (5.0.6) do not match.

(中略)

because the filesystem "vboxsf" is not available. This filesystem is
made available via the VirtualBox Guest Additions and kernel module.
Please verify that these guest additions are properly installed in the
guest. This is not a bug in Vagrant and is usually caused by a faulty
Vagrant box. For context, the command attempted was:

mount -t vboxsf -o uid=1000,gid=1000 vagrant /vagrant

The error output from the command was:

mount: unknown filesystem type 'vboxsf'

[default] GuestAdditions versions on your host (5.1.28) and guest (5.0.6) do not match.


よはguestOSのversionを合わせればいいんだなって思い

vargrant ssh

でログイン

$ curl -0 http://download.virtualbox.org/virtualbox/5.1.28/VBoxGuestAdditions_5.1.28.iso > /tmp/vboxguest.iso
$ sudo mount -o loop /tmp/vboxguest.iso /mnt
$ yes yes | sudo /mnt/VBoxLinuxAdditions.run
$ exit

ほんで読み込み直しておしまい

myuser: centos7$ vagrant reload
==> default: Attempting graceful shutdown of VM...
==> default: Checking if box 'bento/centos-7.1' is up to date...
==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
    default: Adapter 2: hostonly
==> default: Forwarding ports...
    default: 3000 (guest) => 3000 (host) (adapter 1)
    default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
==> default: Machine booted and ready!
[default] GuestAdditions 5.1.28 running --- OK.

(後略)

.bashrcで作業効率アップ

長いコマンドをパイプ繋いで頑張っていた
今日この頃

.bashrcで設定して作業効率向上させたお話

こんなコードをいちいち打つのはめんどくさい

$ history | grep mysql


まずbashrcを作成

$ vi ~/.bashrc

i
を押して編集モードにする
そして下記エイリアスを作成

alias hgrep='histroy | grep'

escキーを押してコマンドモードに戻して

:wq
を押して保存して終了

$ source ~/.bashrc

これで先ほど作った hgrep が
有効になります。
もし失敗したらターミナル再起動

$ hgrep mysql

またこんなコマンドはさらにめんどい

$ find app/controller -name "*.rb" | xargs grep -r "debug"

そういったときはfunctionを使う
またまた.bashrcを編集する

function fgrep() {
  command find $1 -name "*.$2" | xargs grep -r "$3"
}

また.bashrcを読み込み直して
無事に動きました

$ fgrep app/controllers rb debug

おすすめエイリアス
あればぜひ教えていただきたい。。