はじめに
新入社員がCakePHPやRuby on Railsなどを使ってweb開発をした際に躓いたポイントを列挙します。
細かい部分でも躓いたら逐一メモにとっていたので、上から時系列順に読んでいくと懐かしさを感じますが、
記事に書くために追記などをしつつ、分類別でまとめてみました。
HTML, javascript
meta viewport
chromeのモバイルエミュレータがなんだかうまく動作しない!?
そんな時はもしかしたらヘッダーに下のようにmeta viewportタグを埋め込むと解決するかもしれません。
<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 属性の違い
ajaxのエラーメッセージの出し方
下のように、error関数の引数を渡してあげればよいです。
$.ajax({
error:function(XMLHttpRequest, textStatus, errorThrown){
alert("システムエラー");
alert(XMLHttpRequest.status);
alert(textStatus);
alert(errorThrown.message);
}
});
jQueryの:oddがうまくいかない?
$('input:not('.display-none'):odd')
などでoddが意図した結果になってくれません。
:notと併用できない、もしくは内部でもつindexがおかしくなっている(?)と思われます。
仕方がないので以下のように実装
$("input:not(.display-none)").each(function( i ) {
if(i % 2 == 1) $(this).addClass('light-blue lighten-5');
});
3行も使ってしまいました。
(2017/2/6 19:00追記)
今やってみると、$('input:not('.display-none'):odd')、普通に動きます……。
indexがおかしくなっているとかアホなこと言ってすいませんでした。
filterも使えるようです。
smzkさんありがとうございました。
jsでformがsubmit()できない!
name にsubmitという文字列があると送信されないようです。
エラーメッセージなどがなく、submitボタンが効かないという異常しかないので原因特定が難しかったです。
ruby
key行列とarray行列のマージ
keys = ['u', 'h', 'o']
values = ['ご','り','ら']
key_values = {'u' => 'ご', 'h' => 'り', 'o' => 'ら'}
keys,valuesからkey_valuesを作る操作です。
これは、以下のようにします。
temparr=[keyarr,valuearr].transpose
mergearr=Hash[*temparr.flatten]
もちろん、mapなどを使って作ることも出来ます。
(2017/2/6 12:00追記)
以下のように、もっとシンプルに書くことができるそうです!
keys.zip(values).to_h
yancyaさんありがとうございました。
!は破壊的なメソッド。そうじゃないのは非破壊的なメソッド
分かっていてもバグに直面したら見落としがちです。
特にメソッドチェーンすると動作が不安になってしまいます。例えば、
slice('hoge').tr!('a','b')
はちゃんと実行されてくれません。
URIパース時に 'split': bad URI(is not URI?)のエラーが出る
rubyのバージョンが古いとホスト名にアンダーバーや空白を含むurlは
認識してくれずにエラーが出ます。
rubyのバージョンを上げてみるか、
変換したい文字列は自分で変換メソッドを書いてurl.parse()の中に入れるのが良いでしょう。
Ruby 2.1 と 2.2 における、URI#parseの挙動の違い
二次元ハッシュの扱いの注意
二次元ハッシュの初期化は
hash = Hash.new { |h,k| h[k] = {} }
で行います。
単純に、hash = {}だとうまくいかなかったです。
hashの値がnilになるんですけど!
hash = {a: 'hoge', b: 'fuga'}
としてhashを定義するとhash[:a]としないと'hoge'は取り出せません。
他の言語と同じノリでhash['a']とやってしまいがちです。
hashのkeyは文字列とシンボルを区別する
慣れないうちは何度もハマりました。クラスが違うんですよね。
Rails
bundle installをしようとしてtext file busyと出る!
以下のサイトが参考になります。
bundle install時にText file busy エラー
scopeで0件の検索結果を返すとき
scope内に、特定の条件でnilを返すような書き方をしてしまうと、
メソッドチェーンをした時にnilクラスに対するno method errorが起きてしまいます。0件の検索結果を返すときはnilではなくnoneを使うと良いですね。
saveされないときはとりあえずsave!を使う
エラーメッセージが詳細に出るので原因特定しやすいです。
jsのライブラリをlib以下、vendor以下のどちらにおけば良いのかわからない
サードパーティ製のライブラリは "/vendor/assets/"以下に、自作のライブラリは"/lib/assets/"以下に配置するのが良さそうです。
Magickが外部ソース画像を取得してくれない
Magick::ImageList.newはhttp://しか受け取らないようです。
もしhttpでもアクセスできるなら、ほしい画像のurlの頭をhttp://にするとよいです。
Magick::ImageList.new url.gsub('https://','http://')
変なゴミデータがview,erbに乗る
<%= @records.each do |r| %>
のようにeachにイコールをつけるとでてきてしまいます。
イコールを外します。これも割りとやってしまいます。
CakePHP, PHP
外部サイトとPOST通信をしたい
PHPのcURL関数を使って、HTTPのPOSTをするサンプル
を参照できます。
$postdataのところにkey=valueと指定して、
$POST['key']として取得できます。
CakePHPのフォームヘルパでcheckedさせたい
valueでoptionsのキーを指定するようにします。
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設定を変更します。
git rebaseで誤って削除した!
git rebaseでbitbucketのコミットを消すことができます。
git push origin +(ブランチ名)
誤って消してしまった場合は、
git reflogで作業履歴を閲覧して元に戻すことができます。
vagrantが起動状態でパソコンが強制終了
- vagrant:一度ストップする必要があります。
vagrant halt
vagrant up
vagrant reloadでもよいです。
(2017/2/6 12:00追記)
再起動時はvagrant reloadではなくvagrant resumeでないと駄目なようです。
h_ootakeさんコメントありがとうございました!
- mysql:
突然動かなくなりますが、
sudo service mysqld start
で解決。
cdをsudoしたい
cdはsudo出来ません。
sudo sh -c "cd /path/to/dir; ls hogehoge"
sudo ls /path/to/dir/hogehoge
中を見たいなら上2つのどちらかを使う事になります。
mysql に外部からアクセス出来ない
自分のホストからA5sqlなどのクライアントを用いてアクセス出来ない場合、MySQLがあるサーバーのポートなどの問題も考えられますが、
MySQL側のユーザー権限が足りていない可能性もあります。
MySQLに入り、
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
と出てきて動きません。
この記事を参考に解決しました。
Riot.jsのハマリポイント
<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属性には引数なしの関数を指定し、
オリジナル属性などで引数にしたいものを渡す必要があります。
<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>
受け取り側の関数例は下記です。
disp_number_change(event){
this.pagesize = event.target.attributes.disp_number.value;
this.page = 0;
this.update_page_list();
}