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

元祖若手の奮闘記。主に注意されたことをメモがわりに使用するよ!

入力したものを計算させるだけの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),
      ];

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

        result *= capacity_list[i];
      }

      return result;
    }
  //-->
  </script>
</body>
</html>

Rails3.2.22.5 => 5.1.5 への道

■役たったコマンド

bundle exec rails app:update

これで初期設定はほぼやってくれる


あとこれはかならず使う
https://rubygems.org

■Config

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

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


Rspec
Rspec unknown keywordについて
get :show, id: 1
だとだめで
正しくは
get :show, params: { id: 1 }
とparamsで包まないといけない

Rails 5 からコントローラーのテストで assigns などを使う場合は
rails-controller-testing の gem が必要になりました。 gem がない状態でテストを実行すると下記のようなエラーが発生します。

レンダリングページ

expect(response).to render_template("hogehoge")
こんな書き方をしていたら
Controller名も追加してテンプレート名はアンスコ(_)を入れる
expect(response).to render_template("hage/_hogehohge")


■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エラーになる

・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) }
と修正


正規表現のエラー

^ $

から

\A \z

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

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?

■ヘルパー

・link_toの引数の数
必ず3つで!!


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




■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.

Javascriptでアクセスされてもいい場合
protect_from_forgery except: :index
見たいな書き方でエラーではなくなる


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

image_tag
javascript_include_tag
stylesheet_link_tag

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

↑SCSSファイルを直したさいに再度動くことを確認しました!

・scssの設定がこけるこける

@include 
@mixin not found

include は必ずそこのファイルで一度しないと
@mixin not found
のエラーが出る


勝手に作られた
configファイル
create config/secrets.yml
create config/cable.yml
create config/puma.rb
create config/spring.rb
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

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

■route.rb

・asに注意
as: :hoge
as: :hoge # => 二個あるよ!エラー

・match メソッド使うなら
:viオプションでアクション追加せい!


■sass

https://qiita.com/ryokio0129/items/bb62e4aeab2921290846
.hvr-bounce-in:hover
.hvr-bounce-in:focus
.hvr-bounce-in:active
これは非推奨だからやめとけ
でも直し方がわからん

■モデル
ActiveRecord::PendingMigrationError

未実行のマイグレーションファイルがあるぜ

・undefined method `sanitize`
パラムをそのまま使うの文字列に入れるのやめようぜ

■コントローラー
当たり前だけど
before_filterはうごかないぜ


users = ::User::User.where(status: 0).all
users << ::User::Hoge.where(status: 0).all
# ActiveRecord::Relation クラスだから配列みたいな扱いスンナ!って起こられる
before_actionへ切り替えや!

4/5

■これは弊社限定かもかも

config/load_models_for_rspec.rb

switch_pointの相性が悪く
swtich_pointのKey not found でこけるこける

Rspec
・specファイル命名と基本的な書き方
hoge_controller.rb
じゃなくて
hoge_controller_spec.rb

そして
先頭に
require 'spec_helper'
しないと
Rspecがちゃんと動いてくれない


さらに変にclass ... do end 書いているの消したら通った。。
俺の3時間返せ。。

■コントローラー
(モデル入れた変数).map(&:attributes)
これでModelクラスから通常のハッシュクラスになるので
は非常に大事だと思う


・params permit
ちゃんとしろよ!

・render text: はだめ render parain: に変更

■モデル
・モデルから取ってきたgeometry型はto_jsonするとこける
位置情報で使われるgeometry型
ああgeometry型
今回はGem入れて変換とかじゃなくて
純粋に項目を消した

4/10
ああ勘違い
モデルのincludesは
preload => joins しない
eager_load => joins する
って感じらしいのとプラス
基本は
preload が使用されるらしい
https://qiita.com/seiya1121/items/64037638c79a001cd4cd

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

4/18
■Model
・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.tn}.num")
と書こう!

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

Rails3はよしなにやってくれてた見たいだけど
Rails5からは
usersテーブル
name NOT NULL
age NOT NULL

だとしたら

user = User.new
user.name = "hogehoge"
user.save
でエラーになる(当たり前っちゃ当たり前だが)
user.age = 100
も追加しよう


・belongs_to の罠
valid?っでかなり変なエラーが追加されるのでなんぞや??
って調べまくっていたら
optional: true

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

https://qiita.com/iguchi1124/items/218e35a145f372062ea4


■全体
・Browserクラスの引数が変更
# botの場合はログに残さない
ua = URI.decode(request["HTTP_USER_AGENT"])
browser = Browser.new(ua: ua)

こんなコードを見つけたんだが
正しくは
browser = Browser.new(ua)
である

■Js

これは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

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

Rails 参考になる書き方書いてあった

ちょっとした細かいところまで書いてある!!
これは使える!


github.com

RailsのModelを複雑にした時

SQLのこんな動きをしたい
UPDATEする時JOINしてGROUPBYしてって時

update
  items
inner join (
  select
    orders.item_id,
    count(*) count
  from
    orders
  group by
    item_id
  ) myorders
set
  items.orders_count = myorders.count
 where
  items.id = myorders.item_id


Arelなら綺麗にかけるけども
現場でArelを使ってかいてなかった。。

って時に考えた結果こうなった
ベタ書きってどうよ。。

order = Order.select("#{Order.tn}.item_id, COUNT(*) count").group(:item_id)
Item.joins("INNER JOIN (#{order.to_sql}) myorders")
  .where("#{Item.tn}.id = myorders.item_id")
  .update_all("#{Item.tn}.orders_count = myorders.count")

PHPの正規表現でWARNINGがでまくったのでとめた。

こんなコードを書いていたら
WARNINGがでまくったので

<?php
    public function validateWords($word_list = array()){
        $pattern = implode('', array(
            "\x{3041}-\x{3094}", //ひらがな
            "\x{30A1}-\x{30F3}", //カタカナ
            "\x{4E00}-\x{9FFF}", //漢字
            "\x{F900}-\x{FAFF}", //漢字
            "\x{FF01}-\x{FF5A}", //全角記号、全角英数字
            "a-zA-z0-9Α-Ωα-ω¢£"
        ));

        $result = array();
        foreach ($word_list as $word){
            if (preg_match('/[^'. $pattern .']/', $word)){
                $result[] = $word;
            }
        }
    }
    return $result;
?>

そしてこんな感じでWARNINGがでた

Warning: pregmatch() [function.preg-match]: Compilation failed: invalid range in character class at offset 13

まぁ範囲の指定がUnicodeとa-zとかごちゃってるからな
ってことで

全部統一してみる
だがしかしWARNINGは止まらない

そして気づく。

「そういえばこれEUC-JPやんけ。。」

ってことで修正

<?php
    public function validateWords($word_list = array()){
        $pattern = implode('', array(
            "\x{0030}-\x{0039}", //半角数
            "\x{0041}-\x{005A}", //半角英小
            "\x{0061}-\x{007A}", //半角英大
            "\x{3041}-\x{3094}", //ひらがな
            "\x{30A1}-\x{30F3}", //カタカナ
            "\x{4E00}-\x{9FFF}", //漢字
            "\x{F900}-\x{FAFF}", //漢字
            "\x{FF01}-\x{FF5A}", //全角記号、全角英数字
            "\x{FFE0}\x{FFE1}" //セント、ポンド
        ));

        $result = array();
        foreach ($word_list as $word){
            $str = mb_convert_encoding($str, "UTF-8", "EUC-JP"); // UTF-8へ変換

            if (preg_match('/[^'. $pattern .']/u', $str)){ //u修飾子をつけ忘れないように
                $result[] = $word;
            }
        }
        return $result;
    }
    
?>

WARNING止まった!!!!

だが待つんだ
喜ぶのはまだ遅かった
全角のマイナスとセント、ポンドがなぜか
NGワードでひっかかる

ってことで
UTF-8に変換したところでvar_dump
なんと半角に変換されていた。。。。

-¢£ => -¢£
ってことなので
範囲を追加。

下のやつでおしまい。

<?php
    public function validateWords($word_list = array()){
        $pattern = implode('', array(
            "\x{0030}-\x{0039}", //半角数
            "\x{0041}-\x{005A}", //半角英小
            "\x{0061}-\x{007A}", //半角英大
            "\x{3041}-\x{3094}", //ひらがな
            "\x{30A1}-\x{30F3}", //カタカナ
            "\x{4E00}-\x{9FFF}", //漢字
            "\x{F900}-\x{FAFF}", //漢字
            "\x{FF01}-\x{FF5A}", //全角記号、全角英数字
            "\x{FFE0}\x{FFE1}" //セント、ポンド
            "\x{2D}\x{A2}\x{A3}"
        ));

        $result = array();
        foreach ($word_list as $word){
            $str = mb_convert_encoding($str, "UTF-8", "EUC-JP"); // UTF-8へ変換

            if (preg_match('/[^'. $pattern .']/u', $str)){ //u修飾子をつけ忘れないように
                $result[] = $word;
            }
        }
        return $result;
    }
    
?>