JavaScript/e.preventDefaultってなんやねん
って話。
結構JavaScriptを書いてると使う機会のあるコードなんだけど。
正直ちゃんと理解をして使ってるわけじゃない。
どうやら非同期通信を始めとした技術ではどうしても使わざるをえない大前提のような記述らしいのでちょっとまとめてみようかなっと。
preventDefaultとは
実行したイベントがキャンセル可能である場合、イベントをキャンセルするためのメソッドのこと。
ちなみにe.preventDefaultと使われることが多いと思うんだけど、eってのはeventのことらしい。
例えばリンクをクリックした時、チェックボックスにチェックを入れた時なんかにイベント処理が発火するはずなんだけど、これを適用することにより発火しなくなるということ。
いやいや.on('submit')とかで指定してるじゃんダメじゃん。
なんのためにやるんだよ動かなくなるじゃんと思ったんだけど。
だからこそちゃんと考えなくてはならないみたい。
つまり「prevent(妨害する)」 「Default(初期動作)」のうち、初期動作とはなんなのかってことを考える必要がある。
イベントの初期動作と仕様を考える
ChatSpaceを例に考えるなら。
◆初期動作
メッセージ送信機能はsubmit属性を持っているわけだけど、HTML上ではaタグと紐づいていて、設定されたリンク先に飛ぶことになる。
この設定されたリンク先に飛ぶっていう動作がこの場合の初期動作。
◆仕様
非同期通信がしたい。
つまり、ユーザーが送信ボタンを押した場合にブラウザをリロードせずにメッセージを反映させたいということ。
上記を踏まえて考えると、e.preventDefaultを使わないと、送信ボタンを押した場合にブラウザリロードされちゃうよねってこと。
まとめ
・e.preventDefaultはイベントの初期動作を発火させないようにするコード
・イベントごとの初期動作とは一体なんなのか?考える必要がある
・仕様を明確にする。
・初期動作と仕様を明確にした上で、e.preventDefaultを適用するかどうか決定する。
こんなとこっすかね
RubyOnRails/Carrierwaveとminimagickの導入
くそー変なところでつまづいてた〜〜〜。
ChatSpaceでずっとundefine method 'url'がでていて、変数として使用しているurlなんてmessage.image.url、つまりメッセージから取得した画像のurlしかなかったのです。
で、メッセージテーブルにurlカラムなんてないし、imageテーブルなんて作ってないし一体どういうことなんだと思っていたら。
Carrierwaveとminimagickを導入すればurlメソッドのようなものが使えて、メッセージから取得したimageファイルにurlを埋め込める・・らしい。
つまりCarrierwaveとminimagickを導入し忘れてたってこと!
今回はその導入方法を手早く書いていくぞ!
まずgemの記載。
gemfile
忘れずにインストール!
ターミナル
イメージアップローダーをジェネレートする
ターミナル
モデルに記述。
app/models/message.rb
最後にイメージアップローダーに記述。
app/uploaders/image_uploader.rb
include~~はimage_uploaderの4行目くらいでコメントアウトされてるので、コメントアウトを解除します。
process resize_to_fitは画像を投稿する際のサイズを決定しています。
RubyOnRailsでAjaxの実装
また備忘録的に書いていこうかなと。
今回はAjaxの実装について。
まずAjaxとはなんぞやと。
Ajax(Asynchronous JavaScript + XML)とは
ウェブブラウザ内で非同期通信を行いながらインターフェイスの構築を行うプログラミング手法である[4]。XMLHttpRequest(HTTP通信を行うためのJavaScript組み込みクラス)による非同期通信を利用し、通信結果に応じてダイナミックHTML (DHTML) で動的にページの一部を書き換えるというアプローチを取る[5]。
(引用:https://ja.wikipedia.org/wiki/Ajax)
やっぱり文章にするとわかりづらいよね。
自分が調べていてイメージしやすいなと思ったのはグーグルマップかな。
ドラッグすると現在表示されている画面から、滑らかにスライドするように地図表示情報が見えてくると思ういます。
これが昔はドラッグして違う画面を見ようと思ったら、その度にページ読み込みをしていたので滑らかに見ることができなかったのです。
(自分はギリギリそんな過去があったなと思えるんだけど、知らない世代は知らないかも・・)
やっぱり使用感として使い心地が全然違うよねって話
今回はRailsでどうやって実装していくかについて簡単にまとめようかと思うよ。
ちなみに今回はツイートに対してコメントをした場合に、コメントが非同期通信で表示されるという機能をテーマに書いていきます。
1.まずはGemを導入。Gemfileに書いたら忘れずにbundle installを。
Gemfile
2.フォームが送信されたらイベントが発火するようにする
javascripts階層にcomment.jsを作成して、下記の通りコードを記載。
この時、フォームにID名(もしくはクラス名)をつけ忘れないように
app/assets/javascripts/comment.js
3.非同期通信でコメントが保存されるようにする
上記コードに非同期通信をする上での詳しいオプションを書いていきます。
フォームの送信が行われた場合にcreateアクションを動かします。
この時のdata形式ではjsonを指定しています。
app/assets/javascripts/comment.js
4.コメントを保存し、respond_toを使ってHTMLとJSONの場合で処理を分ける
responto_to do を使用し、リクエストされたformatによって処理を分けるようにしています。
フォーマットがjsonの場合、jbuilderを使ってJavaScriptに返すデータを作成します。
app/controllers/comments_controller.rb
5.jbuilderを使用して、作成したメッセージをJSON形式で返す
jbuilderでは、[j.son.KEY VAKUE] という形で書くことができます。
こうすることにより、JavaScriptファイルに帰ってきたデータをjbuilderで定義したキーとバリューの形で呼び出して使うことができます。
app/views/comments/create.json.jbuilder
6.帰ってきたJSONをdoneメソッドで受け取り、HTMLを作成する
function buildHTMLではHTMLを追加しています。
.done以降では非同期通信に成功した時の記述をしています。function(data)となっていますが、非同期通信に成功した時の第一引数にはサーバから返されたデータが入っています。
この場合ではcreate.json.jbuilderのデータです。
app/assets/javascripts/comment.js
7.エラー時の処理を行う
通信に失敗した場合、アラートを出します。
app/assets/javascripts/comment.js
大まかな流れはこんなところかな。
rails/deviseをrspecで使えるようにする準備
久々に書くよ。
最近はカリキュラムに追いつくのが必死でなかなかね・・。
あとはやっぱりがっつり書きすぎると続かないので、今回は本当に備忘録くらいの量で書こうかなと思う。
今回はRubyOnRailsでdeviseをrspecで使えるようにする準備手順について書くよ
まずは下記ファイルを作成、記載。
spec/support/controller_macros.rb
spec/rails_helper.rb
これだけでdevise機能をrspec上で使用することができます。
今度はrspecの導入基礎も書きたいな。
JavaScript/繰り返し文
久々にブログを書く気になったので書こうと思う。
ブログのモチベーション保つの難しいよ〜。
夜まで勉強してるとどうしても書くのが深夜になっちゃうし・・・。
う〜ん、ちょっとやり方考えなきゃな。
とりあえず、今日はJavaScriptの繰り返し文について書こうかなと思う。
ここ一週間はTECH::EXPERTの中間試験、模試、本試験ばっかりでなかなか新しい知識がなかったんだけど、久々に。
ちょっと基礎を飛ばし気味になるけど、解説の中で説明するから許して。
ちなみにhtmlファイルの中の記述は下記で進めます。
htmlファイルの編集はしません。
ファイル名:blog.html
今回は以下のような仕様のものを作るよ。
・JavaScript上で英数国理社5教科それぞれの点数を打ち込む。
・それを足し合わせた合計点をhtml上のコンソールに表示。
・合計点に応じてA、B、Cのランク付をする。
・合計点=500点⇨Aランク
・300<=合計点<500⇨Bランク
・合計点<300⇨Cランク
・ランクの結果もhtml上のコンソールに表示
ちなみに実行結果の様子と、コンソール画面は以下の画像みたいな感じになります。
htmlファイルをブラウザ上で開いて、F12を押すとコンソール画面に入れます。
色々と長くなったので、いつものごとくコードをどん。
順繰りに解説していきます。
まずここ。
配列subjectsの中にハッシュがある状態です。
JavaScriptの場合は、変数を定める際にvarという単語を入れます。
あとはrubyと完全に同じ。
配列sabjectsは順番で値を管理します。
subjects[2]={subject: 国語, score: 50}となります。
このハッシュの中に入っている値を取り出す場合は、
subjects[2].scoreと記載します。この場合は国語の50点という値が返ってきます。
次にこの記述。
rubyでいうところのdefに当たります。
独自のメソッドを作れますよっていう便利構文です。
見切れちゃってますけど、メソッド全体を{ }で囲む必要があります。
( )内は引数です。今回は使いません。盛り込みたかった・・・・。
次にfor文。rubyではeach文がよく使われましたが、for文で記載しています。
var total_score=0は、教科の合計点数を出すために変数total_scoreを作成し、0点と定義しています。
3行目では、「変数iを0として定義し、配列の値の数までiを増やし続けろ」と命令しています。i < subjects.lengthの意味合いを理解できるかどうかが肝でしょうか。
4行目では、「0点から始まったトータルスコアに対して、繰り返すたびに教科ごとのスコアを和算しろ」という意味になります。
subjects[ i ].scoreの意味を理解することが大事です。
繰り返すたびにiは0から1ずつ増えていくので、最終的に英数国理社全てを読み出すことになります。.scoreにより、その時の配列からscoreキーに入っている値を読み出して、total_scoreに和算することになりますね。
よくあるif文ですね。
ほとんどrubyとおなじ。
elsif ではなくてelse ifと記述するところ、条件を都度( )で覆うところ、
実行処理を{ }で覆うところが違うところでしょうか。
ほとんど同じ感覚で使ってます。
最後の文
一番最初にfunctionによるメソッドとして定義したものは、
実行するためにこうやって記載して呼び出してあげないと動いてくれません。
これもrubyと一緒ですね。
今回は引数を用いないので、( )の中は何もなしです。
こんなところかぁ・・・。
JavaScriptに関しては、概ねrubyの基礎があれば同じ感覚で使えるんじゃないかなと思います。
うおおおおおおお眠い、眠いぞ。
明日は正規表現を書きたい・・・。
意味わからんのじゃ・・・正規表現は・・・。苦手なんじゃ・・。
ruby/クラスとインスタンス
最近勉強ばっかりで書いてなかったので書こうかなと。
今日はrubyのクラスとインスタンスについて書こうかなと思うよ。
クラスとは
とある種類のオブジェクトにおける、共通の属性とメソッドをまとめて定義しておく型のようなもの。
ある属性のクラスからインスタンスを作成し、そのインスタンスで処理を行います。
これによってインスタンスの一貫性が生まれます。
さて全くわからん!なんのことだよって感じなんで、次はインスタンスについて調べます。
インスタンスとは
クラスに基づいて生まれたオブジェクトのことをインスタンスと言います。
とにかくクラスが先。クラスからインスタンスが生まれます。
なんて言われてもやっぱりわからんよね・・。
ということでいつも通りとりあえず書いてみます。
こんな感じ。
ちなみに実行結果ははこんな感じ。
一個一個何してるかというと、まずこれ
Fruitsというクラスを定義しています。
同時にこのクラス内でクラス変数@@fruitsを使うと、"果物"がかえってくるようにしてます。クラス変数は、fruitsクラスの内部であればどこでも使用可能です。
ちなみにクラスには継承というものもあるので、継承先でもクラス変数が使えます。
ちなみにインスタンス変数はクラスのインスタンスにおいて使用することができます。
self.(メソッド名)でクラスメソッドを定義できます。
クラスメソッドはクラス変数にアクセスするときに用いることが多いそうです。
例えば、外部ファイルからデータを取得してインスタンスを作成するときとか・・・らしい。
ここでは実行することで"甘いよ"って言います。果物のくせに生意気ですね。
最後にまたインスタンスメソッド。インスタンスメソッドでは、別のインスタンスメソッドで使われたインスンタンス変数を使うことができます。
ここでは"私はメロンで色は緑です。"と自己紹介します。果物のくせに生意気ですね。
これらは書いただけでは実行されず、下記の通りに記載することで初めて実行されます。
furits = Fruits.newにより、fruitsというインスタンスが作成されます。
まずこのコマンドによってインスタンスを作成する必要があります。
その後は、
インスタンスメソッドであれば(インスタンス名).(インスタンスメソッド名)と書くことによって
クラスメソッドであれば(クラス名).(クラスメソッド名)と書くことで実行されます。
途中で出てきたinitializeメソッドは、Fruits.newと同時に実行されるので省略されます。
こんな感じか。
噛み砕くためにクラスという単語とインスタンスという単語を努めて使わないという初心は開始数行で消えました。
bundle installエラーの原因 gemファイルの保存場所がおかしい?
掲題について、前回も少しまとめたんだけど
原因これかも?というのがあったので自分のために走り書きを。
ターミナルにて、
bundle show rails
を実行すると
/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rails-4.2.6
というのが帰ってくるらしい。
どうやらこれがbundlerによって保存されるgemの場所とのこと、
自分のPCでこの指示を出すと、返ってくるのが、
/Users/ユーザー名/projects/rensyuutyuu/vendor/bundle/gems/rails-5.2.2.1
ここにgemが保存されてることになってる。
おそらく前者が標準gemファイル保存場所というやつで、後者がprojectごとにgemをインストールしてしまっている状態だと思う。
以前記事にまとめたbundle installの話は、標準ファイルに保存すればいいものをなんでお前はプロジェクトに保存しようとしてるんだ?っていうエラーだったのではないかという仮説。
ちなみに、現状のgemファイル保存状況では、まったく階層違いのrbファイルでrequireを使ってもクラスを読み取ることができなかった。
応急処置として、rbenv exec gem install gemファイル名
というコードで、rbenv exec gem listのlocal gemに入れることでひとまず対処できた。
忘れないうちに走り書きしておいた。
自分用メモと言えどひどい文章だ。わかりにくい。わかってないけど。