niki12260714の日記

フリーランスのITエンジニアの呟き。

formを入れ子で使いたい場合の対応

オメェのシステム設計が悪いんだオラァ! と言われればそこまでなのですが、とある画面で、二つのformを内包するformを作りたいと思いました。
コードを書くと、こんな感じ。

<form id="親">
  <form id="子1">
    <intput type="text" id="child_txt_1">
  </form>
  <form id="子2">
    <intput type="text" id="child_txt_2">
  </form>
  <input type="button" value="送信">
</form>

それぞれ、子1,2で入力された値を親フォームのsubmit先で使いたい。
で、これをこのままにすると、formは入れ子が許されていないので、送信を押すと子1のformがsubmitされました。
困ったなぁと調べたところ、HTML5から、inputにform属性が追加になっていることが分かりました。
これを指定してあげると、formの中に入っていなくても、form属性で指定したidの方に属してくれることが分かりました。
なので、以下のように修正。

<form id="子1">
  <intput type="text" id="child_txt_2" form="親">
</form>
<form id="子2">
  <intput type="text" id="child_txt_2" form="親">
</form>
<form id="親">
  <input type="button" value="送信">
</form>

これで送信ボタン押してあげると、formが親に指定されている値がpostされます。

Go言語チュートリアル始めました

Go言語をちゃんと勉強しようと、チュートリアル始めてみました。

A Tour of Go

ポインタの前まで完了。
※読むだけなら全部読んだけど、理解できたのはポインタの前まで……

ざっと感想。
・型がきっちり決まっている
→引数、戻り値も「なんの型か」を最初に宣言する。
 型変換も、どの型に変えるか書かないといけない。
Rubyから入る人だと苦労しそうなポイント。

・deferは面白そう
→評価はされるけど呼び出しが最後というのは、どういうパターンで使うか一瞬イメージがつかなかったけど、調べたら「フォルダ作ってファイルを作るプログラムで、エラー発生時に巻き戻すときに使う」とあって、なるほど、と思った

・並列処理
→今までの業務ではそんなに使わなかったけど、処理を一緒に走らせながら相互に値をやり取りするのは面白そう

Webアプリばかり作っていたのですが、Go言語でなにか一つ作れたら面白そうだなーと思います。
ざっと思いつくのは、Webアプリをテストするためのプログラムとかですかね。
「指定したURLにアクセス→テストコードを実行」みたいな。
OS選ばないので、Windows,Macでそれぞれ実行して結果見られるし、複数ブラウザを同時にテストできますし。
Goで画面の値を読めたりするのかなー、ちょっと調べてみよう。

Bootstrap4で、スマホサイズの時に、Tableの特定カラムを非表示にする

Bootstrap4から、「このサイズの時は非表示」を示す「hidden-**」は廃止されました。

webnetamemo.com

なので、スマホサイズの時に非表示は「<p class="d-none d-sm-block">」のように書くことになります。

さて、これをこのままTableに適用すると、PCサイズの時に非表示に指定したカラムが縦に積まれて画面レイアウトが崩れます。
調べたら、Tableに適用する場合のコードは以下でした。

<table class="table table-hover align-items-center">
 <thead>
  <tr>
   <th scope="col">常に表示</th>
   <th scope="col" class="d-none d-sm-table-cell">スマホ非表示</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>表示中身</td>
   <td class="d-none d-sm-table-cell">非表示中身</td>
  </tr>
 <tbody>
</tbody>

配布のBootstrapテンプレートをRailsに導入する

世の中には親切な人が多いもので、格好いいBootstrapのテンプレートを配布している人がいます。
有料のものなんかサポートも付いていたりして、デザインセンスが壊滅的な人にはありがたい世の中です。
で、このテンプレートをRailに適用するにはどうしたらいいの? というお話です。
テンプレートをダウンロードしてくると、そのままサイトに使えるようにBootstrapのフォルダも入っていたりして、いやでもRailsのgemで入れてるから、これ要らないよねってなって、では、なにを適用するのか? って話になります。
全部が全部に対応するわけではないでしょうが、自分がハマったポイントを、後のメモとして残します。

【Bootstarapのバージョン確認】
適用するBootstrapのバージョンを確認します。
バージョンによって、gemを変更。
3ならbootstrap-sass、4ならbootstrapを導入。

【scssファイルをapp/assets/stylesheetsに配置、読み込み順を制御】
デフォルトのBootstrapに上書きする形でscssがあったので、それを「app/assets/stylesheets」以下に配置します。
で、これをrails -sすると、なんにもしてないと、Railsが配下にあるscssを順番関係なく全部コンパイルしてしまい、mixinが後に読まれて「そんな変数ないよ」と怒られたりします。
なので、application.cssを開いて、読み込み順を制御します。
「*= require_tree .」が、「このフォルダ以下を全部読み込み」という意味なので、ここを削ります。
代わりに、「*= require custom.css」のように、読み込みたいcssを、読み込みたい順番に上から記述していきます。

【その他、jsファイル、cssファイルをvendor/assetsに配置】
Bootstrap、JQuery以外の、適用テンプレート独自のjsファイル、cssファイルは、まとめてvendor/assets以下に配置します。
ここはアセットパイプラインがデフォルトで通されるところらしいです。
でも通らなかったら、以下を参照にapplication.rbに記述を追加、確認します。

masaqu.id

ここまでで、自分は適用できました。
以下、自分が一番ハマったポイント。

【モバイル画面のために、metaタグを記述する】
Chromeディベロッパーツールを使ってモバイルで見ても、画面の文字が大きくならない。
cssを見ると、画面サイズに応じてフォントサイズを変える記述があるのにおかしい。
なので、テンプレートに含まれていたサンプルページのソースコードを見て、自分の記述との差異を確認したら、以下が違ってました。

<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

これを外してモバイルで見ると、文字が小さくなる。
入れると、狙った通りにフォントサイズが変わる。
このタグはモバイルを対象とするページでは必ず入れないといけなかったらしい。

getbootstrap.com

上記ページの「Mobile first」ってところです。
で、viewportってなんだろうと調べると、こちらが詳しかったです。

tech.nitoyon.com

これで適用終了です。

※gemでBootstrap入れてますけど、これを止めて、Railsフォルダに諸々一式置く方法もあります。
自分は試してないんですけど、vendor/assets以下に置いてコンパイル通せばいけるんじゃないかと予想。

MySQLでソートを任意に制御する方法

文字列でソートする場合、普通にやると「AaBbCc」と並びますが、これを「ABCabc」とソートした場合のやり方。
MySQLはソートにcaseを使えるので、それを利用します。

ORDER BY CASE
 WHEN ソート文字列 REGEXP '[A-Z]' then 0
 WHEN ソート文字列 REGEXP '[a-z]' then 1
 ELSE 99
END ASC

REGEXP正規表現を利用して大文字A~Zとの一致を示しています。
こうやって大文字、小文字に重みを振り分ければ、任意の順番にソートが可能。

AWS Cloud9 + Rails + MySQLで絵文字を扱う

参考にしたのはこちら。

qiita.com

というわけで、MySQL文字コードを確認するわけですが、そっちは既に「utf8mb4」でした。
でもrailsの方で文字コードを「utf8」にしていたので、rake:dbした時にutf8でテーブル作ってしまっていたようなので、これを修正します。

/config/database.ymlを以下のように設定

default: &default
 adapter: mysql2
 charset: utf8mb4
 encoding: utf8mb4
 collation: utf8mb4_unicode_ci
 reconnect: false
 pool: 5
 host: localhost

次にMySQLでAlter tableをします。

alter table (テーブル名) convert to character set utf8mb4;

が、ここでエラー。
「Specified key was too long; max key length is 767 bytes」

ぐぐったら、こちらに原因と修正方法がありましたので、参考にしました。

nabeatsu.hatenablog.com

「sudo vi /etc/my.conf」で以下を追加

innodb_file_format=Barracuda
innodb_file_format_max=Barracuda
innodb_file_per_table=1
innodb_large_prefix=1

「sudo /etc/init.d/mysqld restart」でMySQLを再起動

再びMySQLに入り、

alter table (テーブル名) ROW_FORMAT=DYNAMIC;
alter table (テーブル名) convert to character set utf8mb4;

これで文字コードがutf8mb4に変わり、絵文字が入ります。

AWS Cloud9でMySQLに乗り換える

諸事情により、ポスグレからMySQLにDBを変更することになり、開発環境のDBを変えることになりました。
その手順です。

※2018/7/30現在、AWS Cloud9には、MySQLが標準でインストールされているので、インストール作業は飛ばします

MySQLにデータベースを作る】

参考にしたのはこちら。

qiita.com1.文字コードを修正する
「sudo vi /etc/my.cnf」で、my.confに「character-set-server=utf8mb4」を追加
※sudoでやらないと権限足りなくて書き込みできませんでした
2.開発用、テスト用、本番用のデータベースを作る
mysql -uroot」でmysqlに入り、「create database DB名;」でそれぞれデータベースを作成
3.接続用のユーザーを作成し、作成したデータベースへの権限を不要
「create user 'ユーザー名'@'localhost' identified by 'パスワード';」でユーザー作成
「grant all on DB名.* to 'ユーザー名'@'localhost' identified by '接続パスワード';」

MySQLのgemを入れる】

Gemfileに「gem 'mysql2'」を追加、「bundle install」
→失敗する。
 「Gem::Ext::BuildError: ERROR: Failed to build gem native extension.」の表示
ぐぐってみると、こちらの記事がヒット。

kzy52.com

「sudo yum -y install mysql-devel」を実施後、「bundle install」「bundle update」でエラーが発生しなくなる

【database.ymlを修正】

こちらの記事の設定をそのまま使わせていただきました。

www.rubylife.jp

【DB作成しなおし】

「bundle exec rake db:migrate」を実行。
→エラー発生、「NoMethodError: undefined method `inet' for #<ActiveRecord(略」が発生
ぐぐると、こちらの記事がヒット。

programming-beginner-zeroichi.jpまったく同じ状態だったので、inetをstringに修正、再度「bundle exec rake db:migrate」を実施、成功。

ここまで来たら、「rails s -b $IP -p $PORT」でrails serverを起動し、ログイン画面を表示させ、ログインを試しました。
当然ユーザーがいないので蹴られます。
DBにユーザーを問い合わせられる(接続が確立している)、ユーザーがいない(新しいDBを見に行っている)から、成功していると判断。
以上終了です。