新入社員がほぼ１年間のWeb開発を通して躓いたこと30選

## はじめに
新入社員がCakePHPやRuby on Railsなどを使ってweb開発をした際に躓いたポイントを列挙します。
細かい部分でも躓いたら逐一メモにとっていたので、上から時系列順に読んでいくと懐かしさを感じますが、
記事に書くために追記などをしつつ、分類別でまとめてみました。



## HTML, javascript
### meta viewport
chromeのモバイルエミュレータがなんだかうまく動作しない！？
そんな時はもしかしたらヘッダーに下のようにmeta viewportタグを埋め込むと解決するかもしれません。

```html
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
```

### formタグが正しいところに出ない
formタグは入れ子に出来ません。
中にformタグがないか確認してみます。
地味に引っかかるタイプの問題です。

chromeだと中のタグは消えてしまうようです。
### disabledだとフォームが送信されない
disabled 指定だとフォーム自体不完全なものとなり、postで
データをsubmitしようとしてもデータが入ってきません。

PHPの$POST['hoge']の値が空になります。キー自体は作られているようです。

文字が予め入っているテキストフィールドにdisabled属性を付け、
submitしようとしたときにハマりました。disabledではなくreadonlyを付けましょう。

[input 要素の disabled 属性と readonly 属性の違い](http://www.koikikukan.com/archives/2009/04/26-003300.php)
### ajaxのエラーメッセージの出し方
下のように、error関数の引数を渡してあげればよいです。

```javascript
$.ajax({
error:function(XMLHttpRequest, textStatus, errorThrown){
  alert("システムエラー");
  alert(XMLHttpRequest.status);
  alert(textStatus);
  alert(errorThrown.message);
}
});
```

### jQueryの:oddがうまくいかない？
```javascript
$('input:not('.display-none'):odd')
```
などでoddが意図した結果になってくれません。

:notと併用できない、もしくは内部でもつindexがおかしくなっている（？）と思われます。

仕方がないので以下のように実装

```js
$("input:not(.display-none)").each(function( i ) {
    if(i % 2 == 1) $(this).addClass('light-blue lighten-5');
});
```
３行も使ってしまいました。

(2017/2/6 19:00追記)
今やってみると、$('input:not('.display-none'):odd')、普通に動きます……。
indexがおかしくなっているとかアホなこと言ってすいませんでした。

filterも使えるようです。

smzkさんありがとうございました。


### jsでformがsubmit()できない！

[[jQuery]form.submit()できない原因](http://www.happyquality.com/2012/03/12/2039.htm)


name にsubmitという文字列があると送信されないようです。
エラーメッセージなどがなく、submitボタンが効かないという異常しかないので原因特定が難しかったです。


## ruby
### key行列とarray行列のマージ
```ruby
keys = ['u', 'h', 'o']
values = ['ご','り','ら']
key_values = {'u' => 'ご', 'h' => 'り', 'o' => 'ら'}
```
keys,valuesからkey_valuesを作る操作です。

これは、以下のようにします。

```ruby
temparr=[keyarr,valuearr].transpose
mergearr=Hash[*temparr.flatten]
```
もちろん、mapなどを使って作ることも出来ます。

（2017/2/6 12:00追記）
以下のように、もっとシンプルに書くことができるそうです！

```ruby
keys.zip(values).to_h
```

yancyaさんありがとうございました。

### !は破壊的なメソッド。そうじゃないのは非破壊的なメソッド
分かっていてもバグに直面したら見落としがちです。

特にメソッドチェーンすると動作が不安になってしまいます。例えば、

```ruby
slice('hoge').tr!('a','b')
```
はちゃんと実行されてくれません。
### URIパース時に 'split': bad URI(is not URI?)のエラーが出る

rubyのバージョンが古いとホスト名にアンダーバーや空白を含むurlは
認識してくれずにエラーが出ます。

rubyのバージョンを上げてみるか、
変換したい文字列は自分で変換メソッドを書いてurl.parse()の中に入れるのが良いでしょう。

[Ruby 2.1 と 2.2 における、URI#parseの挙動の違い](http://qiita.com/dogwood008/items/923e3b7280af902c292e)
### 二次元ハッシュの扱いの注意
二次元ハッシュの初期化は

```ruby
hash = Hash.new { |h,k| h[k] = {} }
```
で行います。


単純に、hash = {}だとうまくいかなかったです。

[Rubyで多次元hashの初期化をまとめてみた](http://qiita.com/shibukk/items/35c4859e7ca84a427e25)
### hashの値がnilになるんですけど！
```ruby
hash = {a: 'hoge', b: 'fuga'}
```
としてhashを定義するとhash[:a]としないと'hoge'は取り出せません。
他の言語と同じノリでhash['a']とやってしまいがちです。


**hashのkeyは文字列とシンボルを区別する**

慣れないうちは何度もハマりました。クラスが違うんですよね。







## Rails
### bundle installをしようとしてtext file busyと出る！
以下のサイトが参考になります。

[bundle install時にText file busy エラー](http://dev.classmethod.jp/server-side/ruby-on-rails/tips_ruby-on-railsbundle-install_text-file-busy-error/)
### scopeで０件の検索結果を返すとき
scope内に、特定の条件でnilを返すような書き方をしてしまうと、
メソッドチェーンをした時にnilクラスに対するno method errorが起きてしまいます。0件の検索結果を返すときはnilではなくnoneを使うと良いですね。

[クラスメソッドとスコープの使い分け](http://kotatu.org/blog/2014/10/11/why-should-use-scopes-over-class-methods/)
### saveされないときはとりあえずsave!を使う
エラーメッセージが詳細に出るので原因特定しやすいです。
### jsのライブラリをlib以下、vendor以下のどちらにおけば良いのかわからない
サードパーティ製のライブラリは "/vendor/assets/"以下に、自作のライブラリは"/lib/assets/"以下に配置するのが良さそうです。

[RailsでJavaScriptライブラリの配置に迷う](http://shin.hateblo.jp/entry/2013/01/20/164924)
### Magickが外部ソース画像を取得してくれない
Magick::ImageList.newはhttp://しか受け取らないようです。

もしhttpでもアクセスできるなら、ほしい画像のurlの頭をhttp://にするとよいです。

```ruby
 Magick::ImageList.new url.gsub('https://','http://')
```
### 変なゴミデータがview,erbに乗る
```
<%= @records.each do |r| %>
```
のようにeachにイコールをつけるとでてきてしまいます。
イコールを外します。これも割りとやってしまいます。

## CakePHP, PHP
### 外部サイトとPOST通信をしたい
[PHPのcURL関数を使って、HTTPのPOSTをするサンプル](https://hydrocul.github.io/wiki/blog/2013/1111-php-post-curl.html)

を参照できます。

$postdataのところにkey=valueと指定して、
$POST['key']として取得できます。
### CakePHPのフォームヘルパでcheckedさせたい
valueでoptionsのキーを指定するようにします。

```php
echo $this->Form->input('real_name_ok', array(
	'legend' => false,
	'default' => $userdata['Member']['Teacher']['real_name_ok'],
	'type' => 'radio',
	'options' => $allowlists['real_name_ok']['allowedChoice']['rule']['1'],
	'value'=>'1',
	'div' => false,
　'class'=>'with-gap',
)
									);
```
### exhausts memoryが出てきたらdebug-kitのcacheのせい
タイトル部分がオレンジの憎いやつです。

tmp/cache/cake_toolbar_*のファイルを削除すると良いでしょう。



## その他
### cssが読み込み出来ない
キャッシュしか読み込まない！変更が反映されない！
vagrantが原因の一つかもしれません。
sendfile設定を変更します。

[VagrantでCSSの更新が反映されない場合の対処法](http://qiita.com/shoyan/items/12389d5beaa8695b1a53)
### git rebaseで誤って削除した！
git rebaseでbitbucketのコミットを消すことができます。

```bash
git push origin +(ブランチ名)
```

誤って消してしまった場合は、
git reflogで作業履歴を閲覧して元に戻すことができます。

[git/git rebaseを元に戻す方法](http://tobysoft.net/wiki/index.php?git%2Fgit%20rebase%A4%F2%B8%B5%A4%CB%CC%E1%A4%B9%CA%FD%CB%A1)
### vagrantが起動状態でパソコンが強制終了

- vagrant:一度ストップする必要があります。

```bash
vagrant halt
vagrant up
```

~~vagrant reloadでもよいです。~~

(2017/2/6 12:00追記)
再起動時はvagrant reloadではなくvagrant resumeでないと駄目なようです。
h_ootakeさんコメントありがとうございました！

- mysql:
突然動かなくなりますが、

```bash
sudo service mysqld start
```
で解決。
### cdをsudoしたい
cdはsudo出来ません。

```bash
sudo sh -c "cd /path/to/dir; ls hogehoge"
```

```bash
sudo ls /path/to/dir/hogehoge
```
中を見たいなら上２つのどちらかを使う事になります。
### mysql に外部からアクセス出来ない
自分のホストからA5sqlなどのクライアントを用いてアクセス出来ない場合、MySQLがあるサーバーのポートなどの問題も考えられますが、
MySQL側のユーザー権限が足りていない可能性もあります。

MySQLに入り、

```sql
grant all on *.* to 'ユーザ名'
```
とした後に、権限付与するときにflush privileges;で確定すると解決するかもしれないです。
### gitでcannot unlink to old~が出た時
思い切ってそのファイルをaddすると治るかもしれません。
### redisでdbを指定して一括削除する方法
```
redis-cli --raw -n 0 KEYS "*" | xargs redis-cli -n 0 DEL
```
redis-cliの外で上を実行します。
また、-n の次の数字でredisのdbを指定します。
### MySQLのinsertが重いよー
indexが全くない状態が一番速いです。なるべく不要なindexは消すようにします。
### RSpec が、エラーで動かない

```
NoMethodError:　undefined method `visit' for #<RSpec::ExampleGroups　
```
と出てきて動きません。

[この記事](http://qiita.com/hts1004/items/220014152689ecf880d3)を参考に解決しました。

### Riot.jsのハマリポイント

```html
<input class="with-gap" name="disp-number" type="radio" id="disp-50" onclick={disp_number_change(10)} />
<label for="disp-50">50件</label>
```
上のように、onclick属性としてRiot.jsの関数を引数付きで渡してしまうとなぜか描画時に実行されてしまいます。

したがって、下のようにonclick属性には引数なしの関数を指定し、
オリジナル属性などで引数にしたいものを渡す必要があります。

```html
<input class="with-gap" name="disp-number" type="radio" id="disp-50" disp_number="2" onclick={disp_number_change} />
<label for="disp-50">50件</label>
```

受け取り側の関数例は下記です。

```javascript
disp_number_change(event){
    this.pagesize = event.target.attributes.disp_number.value;
    this.page = 0;
    this.update_page_list();
  }
```