Web Marina

日々の業務や勉強などで得た知識をアウトプットしていきます。

【jQuery】show/hide ~イベントによって表示・非表示を切り替える~

f:id:song-of-life1352607:20180113005923j:plain

こんにちは、マリンです。

今回はボタンクリックなどのイベントによって

簡単に要素の表示・非表示を切り替えようと思います。





概要

任意の要素の表示・非表示をボタンのクリックで切り替えます。

ボタンを押すと要素を非表示に、もう一度押すと表示させます。

詳細

Rails環境で行っているため、JSの記述はcoffee scriptです。

View

<!-- app/views/samples/index.html.erb -->

<div class="target-element" data-display="on">
    <p>この部分を切り替えます。</p>
</div>

<button type="button" class="btn btn-md btn-default switch-display">Switch</button>

<script>
    samples.switchDisplay();
</script>




上から順番に解説します。

<div class="target-element" data-display="on">
    <p>この部分を切り替えます。</p>
</div>

この部分が表示したり非表示にしたりする要素です。

target-elementjQueryでこの部分を特定するためのセレクタです。

data-display="on"は、現状が表示中かどうかを判定するためのものです。


<button type="button" class="btn btn-md btn-default switch-display">Switch</button>

表示・非表示の切り替えボタンです。

Bootstrapを使っているので、btnなどのクラスでスタイルを当てています。

switch-displayはイベントの対象となるセレクタです。


CoffeeScript

class SamplesController

    switchDisplay: ->
        $('.switch-display').on 'click', ()->
            if $('.targe-element').data('display') == 'on'
                $('.switch-display').data('display', 'off')
                $('.switch-display').hide()
            else
                $('.switch-display').data('display', 'on')
                $('.switch-display').show()
        return

this.samples = new SamplesController




上から順番に解説します。(class ~~については省略します)

$('.switch-display').on 'click', ()->
    if $('.targe-element').data('display') == 'on'

.switch-display(ボタン)がクリックされたら、

まず切り替え対象の要素の持つdata-displayの値が

onであるかそうでないか検証します。


$('.switch-display').data('display', 'off')
$('.switch-display').hide()

値がonの時、つまり表示状態の時には

data-displayの値をoffにし、

切り替え対象の要素をhide()で非表示にします。


else
   $('.switch-display').data('display', 'on')
   $('.switch-display').show()

値がoffので非表示状態の時には

data-displayの値をonにし、

切り替え対象の要素をshow()で表示にします。


まとめ

要点としては、

  • 切り替えの着火剤となるイベント

  • hideによる非表示

  • showによる表示

この3点です。

今回はイベントをクリックにしましたが、

hoverなどで自作のポップオーバーに使ったりなど

イベントを変えればいろいろと応用が効くと思います。

【Rails5】Rails5で自作のWebアイコンを使う

f:id:song-of-life1352607:20180314224659p:plain

こんにちは、まりんです。

うちの会社ではFontAwsomeがマストなんですが、

結構クライアントからこんなアイコン使って欲しい!といわれ、

そんなのねーよ!!という事が多々あるようです。

そしてこの前唐突に、上司から

アイコン作るスキル身につけて欲しいんだけど。

と言われました。

マジかよ!?

という事で、今回ちょっとやってみました。

「独自アイコンをWebアイコン化し、それをRails5で使ってみた。」

です。





概要

環境

使用アプリ

  • icomoon


今回は元素材はこちらでお借りしました。

icooon-mono.com

f:id:song-of-life1352607:20180709125300p:plain

使いたいアイコンのページからSVG形式でダウンロードしてください。


本当にアイコン作るところからやる場合は、

IllustratorInkscapeなど、SVGで出力できるアプリを使って作成して下さい。

(イラレは高いので私はInkscapeにしようと思っています。本業じゃないし。)


Webアイコン使用までの流れ

  1. 素材(SVG)をicomoonでWebアイコン化する

  2. Webアイコンをダウンロードして必要ファイルをアプリケーションに移動

  3. ファイルの移動先に合わせてダウンロードしたstyle.cssを書き換え

  4. assets/stylesheets/application.scssからimportで読み込む


詳細

それでは一つずつの詳細を説明します。

素材をWebアイコン化する

今回はicomoonというアプリを使って行います。

元となる素材をアップしてそこからダウンロードするだけでできるのでとてもお手軽です。


f:id:song-of-life1352607:20180709135805p:plain

①まずは左上のボタンから素材のファイルをアップロードします。

今回は1枚だけですが、複数アップロードすることが可能です。


②Webフォント化する素材を選択します。

ここでも複数選択が可能で、今後アプリで使用したいアイコンをまとめてダウンロードすれば、

オリジナルのアイコンリストを作れます。

今回はアップロードしたものの他に、追加したBrandsと言うライブラリのニンテンドーswitchのアイコンと、

デフォルトで表示されているIcoMoonのHomeアイコンを一緒にダウンロードしてみます。

*ちなみに写っていませんが、ページの一番下にライブラリ追加のリンクがあります。


③選択すると、下部の真ん中のSelectionの数が増えます。

④右下のボタンでWebアイコンを作成。

Webアイコン化するファイルの確認ページに飛びます。


f:id:song-of-life1352607:20180709140410p:plain

①ここで付いている名前がそのままアイコン使用時のクラス名になります。

アップロードしたアイコンが日本語になっているので編集します。

他にもアイコン画像をクリックすれば、拡大縮小や反転などの簡単な編集も可能です。

②編集、確認が終わったら右下のボタンでダウンロードして下さい。


必要ファイルをアプリケーションに移動

ダウンロードしたフォルダを解凍したら、必要なファイルをアプリケーションに移動します。

f:id:song-of-life1352607:20180709142837p:plain

必要なファイルは上記のfontsフォルダ下のものと、style.cssです。


railsアプリのvendor下に置きます。

vendorの中にassetsをまず作り、その下にfontsstylesheetsを作ります。

他にも何かダウンロードしたものを使うことがあるかもしれないので、

一応専用のフォルダをそれぞれ作ってそこに入れます。

  • vendor/assets/fonts/icomoon → fonts下のファイル

  • vendor/assets/stylesheets/icomoon → style.css




style.cssの書き換え

先ほど移動した構造に合わせて、ダウンロードしたstyle.css内のurlの部分を書き換えます。

f:id:song-of-life1352607:20180709150059p:plain

私はここの指定が不十分だったがために余計な時間や手間を使ってしまいました。

assetsなので、追加した専用フォルダ名からで大丈夫です。

*今回はRails5なのでconfigの方の設定は入りませんでした。

確認はしていませんが、もしかしたらRails4以下ではプリコンパイルなどの設定がいるかもしれません。

こちらで大変詳しく説明して下さっています。

qiita.com




application.scssで読み込む

最後にassets/stylesheets/application.scssからimportでライブラリを読み込みます。

f:id:song-of-life1352607:20180709150950p:plain

ここでも専用フォルダ名が必要になるのでご注意ください。

*直置きの場合は入りません。

以上で実際にviewで使用するまでの準備は完了です。


アイコンを使ってみる

viewでの使い方は、Font Awesomeなどのようにクラスにicon-~のアイコン名を入れて使います。

icomoonの場合は<span>にクラスをつけるようにしてください。

<div>
    <span class="icon-nightsky"></span>
</div>
<div>
    <span class="icon-home3"></span>
</div>
<div>
    <span class="icon-nintendoswitch"></span>
</div>

f:id:song-of-life1352607:20180709151743p:plain

無事表示できました。

まとめ

Webアイコン化して表示させるまでは簡単ですね。

問題はアイコンを作れるかどうかです。

画力も計算もデザイン能力も全く自信がないのですが。。。

それはさておき、途中にも書きましたがこれはRails5での方法になります。

Rails4以下ではvendorに置いたものをデフォルトで探してはくれなかったりするようなので、

おそらくconfig/initializers/assets.rbなどに設定する必要があるかと思います。


今回はこちらの記事を参考にさせていただきました。

machida.github.io

【jQuery (CoffeeScript)】属性の値に変数や式を使う 〜式展開の色々〜

f:id:song-of-life1352607:20180113005923j:plain

こんにちは、マリンです。

今回はjQueryでの式展開についてです。

よくdata属性で要素を絞り込む際の値に

事前に定義した変数を使いたい時があるのですが、

そんな時にいつも職場で使われている記述が理解できず、

色々ググってみたのに見つからない。。。

でも調べているうちに「はっ!!」と気付いたのです。

「これ、式展開だ!!」と。

ってことでこういった副題が付いています。笑





まず今回もRailsの中で検証してますので、

基本、記述方式はCoffeeScriptです。

では今回検証で使いました例のソースコードです。

# HTML
<ul id="lists">
  <li class="a" data-index="1">AAA</li>
  <li class="b" data-index="2">BBB</li>
  <li class="c" data-index="3">CCC</li>
</ul>
<button type="button" class="has-element">HasElement</button> 

# jQuery
$('.has-element').on 'click', () ->
      class_a = "a"
      index = 2

まあボタンはどうでもいいんですけど、

これ押すとコンソールに表示されるって使用でつけました。

このクリックイベントの中に後述の式展開を書いていく感じで。

以後そこのみ書いていきます。


jQueryでの式展開の色々

やり方は3つあります。

  • #{}

  • +

  • ,


#{}

これが純粋な式展開ではないかと思います。

[ソースコード]

// class属性で検索
classA = $('#lists').find("[class = #{class_a}]")
console.log(classA.text)

// data属性で検索
classB = $('#lists').find("[data-index = #{index}]")
console.log(classB.text)

// 展開部分の中で計算する
classC = $('#lists').find("[data-index = #{index + 1}]")
console.log(classC.text)

[実行結果]

AAA
BBB
CCC




それぞれ属性値の指定に、予め値を入れておいた変数を使用しています。

もちろんその中でさらに計算させることも可能です。


JSやjQueryでは' '" "を区別しないみたいなんですが、

これはcoffeeだからだなんでしょうね、

#{}の式展開はダブルクォーテーションの中じゃないと使えませんでした。


+

こちらは前後の文字列と+を使って連結する方法。

[ソースコード]

// class属性で検索
classA = $('#lists').find("[class = " + class_a + "]")
console.log(classA.text)

// data属性で検索
classB = $('#lists').find('[data-index = ' + index + ']')
console.log(classB.text)

// 展開部分の中で計算する
classB = $('#lists').find('[data-index =' + (index + 1) + ']')
console.log(classC.text)

実行結果は前回と同じです。


classBに注目していただきたいのですが、

これは単純に一つの文字列を前後に分け、

その間に変数を入れて繋げる方法ですので、

クォーテーションはシングルでもダブルでも大丈夫です。


その次のさらに計算をする方法ですが、

こちらは計算部分をカッコで囲ってください。

計算の順番が関係するということですね。

これをしないと左から順番通りに計算され、

前半の文字列にindexの中身が足されたものに+1をすることになり、

「は?」と怒られます。

正直、ここまでやってきて初めて計算の順番を意識しました。


,

最後は文字列の後ろに展開したものをくっつけるときに使えます。

文字列の間には入れられませんので、表題とはズレた番外編です。

[ソースコード]

# 値取得部分
classA = $('#lists').find("[class = #{class_a}]")

# 表示部分(展開)
console.log("classA: ", classA.text)

[実行結果]

classA: AAA




今回の展開部分は後半の

("classA: ", classA.text)の部分です。

文字列の後にカンマで区切ったclassA.textを展開してくっつけています。

変数の中身などを展開して文字列に連結しているので、

多分式展開の一種ではないかと思います。。。


まとめ

今回そもそもの問題だった「記述が理解できない」部分に関しては、

おそらく式展開の問題ではなく、コードの読解力だと思います。

真ん中のclassB = $('#lists').find('[data-index = ' + index + ']')

の記述でハマったのですが、

findのカッコ内が' 'で囲まれていた時点できちんと

文字列 + 変数という構造であることを理解できていればこんなことにはなりませんでした。

なぜか' + index +'という塊で捉えてしまったんですよね。


まぁおそらく私のような間違いを犯す人はいないと思いますが、

式展開の方法は一つではないとわかっていれば、

他人が書いたコードを読むときなどにちょびっとだけ役立てるのではないかな?

なんて思ったりなんかして。。。

【SQL】テーブル結合 ー外部結合ー

f:id:song-of-life1352607:20170220105406j:plain

こんにちは、マリンです。

前回の続き、次は外部結合についてです。

内部結合についてはこちらです⬇️

song-of-life.hatenablog.com




外部結合

外部結合は、結合したテーブルの指定したカラムの値が一致するものに加え、

どちらかのテーブルにしかないレコードも取得します。

どちらかというのは、基準とするテーブル(つまり左か右か)によって変わります。


例に使うテーブル構造を記述しておきます。

[cars]

belongs_to :owner

id name owners_id
1 crown 1
2 vellfire 1
3 stepwagon 3
4 legacy 2
5 elgrand

[owners]

has_many :cars

id name
1 ichiro
2 jiro
3 saburo
4 shiro




基本構文

SELECT カラム1, カラム2,... FROM テーブル1
LEFT(RIGHT) OUTER JOIN テーブル2 ON 条件

LEFTまたはRIGHTはどちらのテーブルを基準にするかを示しています。

  • LEFT OUTER JOIN: 左側(テーブル1)を基準結合

  • RIGHT OUTER JOIN: 右側(テーブル2)を基準に結合

例えばLEFTであればテーブル1が基準となり、

並び順や、前述したこちらのテーブルにしかないレコードも

テーブル1の物が表示されます。




詳細

それでは例を使った詳細です。

なお、railsでの方法には私が職場でよく使用するincludesをご紹介します。

*内部、外部ともに様々な方法がありますが、

 現時点でよく使うもの以外は理解が浅いので、

 内部はjoins、外部はincludesのみご紹介させていただきます。




[SQL]

SELECT * FROM cars
LEFT OUTER JOIN owners
ON cars.owner_id = owner.id

LEFT OUTER JOINなので、carsが基準テーブルになります。




[Rails]

Cars.includes(:owner)

こちらが基本形。

includesは厳密には外部結合ではないようですが、

同等の値を取得することができます。




上記を実行すると

  Car Load (1.2ms)  SELECT "cars".* FROM "cars"
  Owner Load (12.8ms)  SELECT "owners".* FROM "owners" WHERE "owners"."id" IN (6, 1, 4)

と言うSQLが発行されます。

ご覧の通り、まずcarsの全カラムを呼び出し、

その後上記のowner_idを元にownersの該当レコードを取得しています。

ちょっと二度手間感がありますね。

そんな時はreferencesを使います。


includesとreferencesをセットで使う

先ほどの基本形でも取れる値は同じなのですが、

もっとスマートに1回のSQLでinclude先のレコードも取ってくることができます。

それがreferencesメソッドです。

Car.includes(:owner).references(:owner)

これを実行すると

SQL (0.2ms)  SELECT "cars"."id" AS t0_r0, "cars"."owner_id" AS t0_r1, "cars"."name" AS t0_r2, "cars"."created_at" AS t0_r3, "cars"."updated_at" AS t0_r4, "cars"."dealership" AS t0_r5, "cars"."display_order" AS t0_r6, "owners"."id" AS t1_r0, "owners"."name" AS t1_r1,"owners"."created_at" AS t1_r2, "owners"."updated_at" AS t1_r3
 FROM "cars"
 LEFT OUTER JOIN "owners"
 ON "owners"."id" = "cars"."owner_id"

となります。

ご覧の通り、SQLは1回のみでownerのレコードも取得できています。




上記を見ると、

LEFT OUTER JOINになっていますね。

includesだけではこうはなっていなかったので、

外部結合として使うのであれば、こちらがお作法的には正しいのかな?

なんて思ったりしました。




Ownerのカラムを使う

上記のまま、例えば

Car.includes(:owner).references(:owner).each do |car|

    car.owner.name

end

とするとおそらく

NoMethodError: undefined method 'name' for nil:NilClass と出てきてしまうと思います。

オーナーのいない車もテーブルに入っているため、

そこのオーナー名が引っかかってしまっているわけですね。




このような時はtryを使うと便利です。

  • try:対象がnilでない場合のみメソッドを呼び出す。

つまりowner ? owner.nameと同じことをやってくれるということです。

tryの方が短く済んで良いかなと思います。




Car.includes(:owner).references(:owner).each do |car|

    car.owner.try(:name)

end

これできちんとオーナーの名前も取得でき、もしオーナーが空の場合には取得しない。

ということが実現できます。




まとめ

今回はincludes&referencesの方法をご紹介しましたが、

他にもeager_loadpreloadなどもあります。

内部結合でも様々な方法がありますので、

ご興味のある方は調べてみてください。

なかなか奥が深い上に咀嚼に時間のかかるテーブル結合でした・・・

自分で色々試しながら理解してきましたが、

まだまだ自信がない部分も多々あります。

何か間違っているところなど御座いましたらぜひご教示ください。

最後に、今回こちらの記事に大変助けられましたのでご紹介しておきます。

qiita.com

【SQL】テーブル結合 ー内部結合ー

f:id:song-of-life1352607:20170220105406j:plain

こんにちは、マリンです。

今回はSQLの内部結合と外部結合についてです。

まさかこの私がSQLについての記事を書く日が来ようとは…

〇〇結合とは?

まずはそもそものお話しです。

〇〇結合とはなんぞ?

は?そこから?と思った方は飛ばして下さい。


データベースからデータを取り出す際、

基本は「一つのテーブルから条件に合致するデータを取り出す」

だと思います。


ではもし、「欲しいのはこのテーブルのデータだけど、

あっちのテーブルと一致するやつで検索したいんだよなぁ〜」

と言うときは?

SELECT * FROM sample_tables

だけでは探せないですよね。

この場合検索条件に出せるのはここで出たsample_tablesのカラムだけです。


こんな時に使えるのが〇〇結合です。

予め関連づけられたテーブルを一時的に結合させ、

それぞれのカラムを使った検索条件で絞り込んだデータを、

結合させて取得する事が可能になります。


では次からはその結合方法について解説しますので、

その前に例として使うテーブル構造をば。

[cars]

belongs_to :owner

id name owners_id
1 crown 1
2 vellfire 1
3 stepwagon 3
4 legacy 2
5 elgrand

[owners]

has_many :cars

id name
1 ichiro
2 jiro
3 saburo
4 shiro




内部結合

内部結合は、それぞれのテーブルから

指定したカラムの値が一致するレコードだけを結合します。

ポイントは、「一致するレコードだけ」という点です。

一致しないものや、そのカラムがnilのものなどは除外されます。


基本構文

SELECT カラム1, カラム2,... FROM テーブル1
INNER JOIN テーブル2 ON 条件

テーブル1からカラム1、カラム2...を撮ってきた後、

結合の条件に従ってテーブル2からも値を取得し、

一致したものを結合します。

SELECTを指定しなければテーブル1の全カラムが対象になります。


詳細

では例を使って詳細を解説します。

ここからはRailsでの書き方も追加します。

[SQL]

SELECT * FROM cars
INNER JOIN owners
ON cars.owner_id = owners.id

[Rails]

Car.joins(:owner)

carsテーブルとownersテーブルを結合し、

cars.owner_idowners.idの値が一致するレコードをくっつけます。


これを実行すると

irb():001:0> Car.joins(:owner)
  Car Load (6.5ms)  SELECT "cars".* FROM "cars" INNER JOIN "owners" ON "owners"."id" = "cars"."owner_id"
=> #<ActiveRecord::Relation [#<Car id: 1, owner_id: 1, name: "crown", created_at: "2018-04-26 03:41:31", updated_at: "2018-04-30 16:06:58">,
 #<Car id: 2, owner_id: 1, name: "vellfir", created_at: "2018-04-28 16:14:28", updated_at: "2018-04-30 16:07:50">,
 #<Car id: 3, owner_id: 3, name:"Stepwagon", created_at: "2018-04-29 06:33:21", updated_at: "2018-04-30 16:07:58",
 #<Car id: 4, owner_id: 2, name: "legacy", created_at: "2018-04-29 06:33:38", updated_at: "2018-04-30 16:08:08">]>

こんな感じで条件に一致するレコードが取得できます。

一致していない(owner_idがない)carsの

id: 5, name: "elgrand"は除外されています。


基準となるのがFROMの方のテーブルなのでcarsのレコードが表示されていますが、

結合されているのでINNER JOINownersの値も取得できます。

そちらも検証してみました。

INNER JOINの方のカラムを取得する場合にはSELECTでそのカラムを指定する必要があります。

 詳しくは補足をご覧ください。


【番外】結合した方のカラムの値を取得してみる

結合後のレコードからownersnameを取得してみます。

  • nameというカラム名が両テーブルでかぶっているので、結合時に別名をつける。

[SQL]

SELECT cars.*, owners.name AS owner_name
FROM "cars"
INNER JOIN "owners"
ON cars.owner_id = owners.id

[Rails]

def self.list_by_ownerid
    @cars = Car.joins(:owner).select("cars.*, owners.name as owner_name")
end

SELECTの中でowner.nameowner_nameに変更して値を取得します。




次に、上で取得・連結したレコードの中からrailsowner_nameを取り出します。

Car.list_by_ownerid.map {|car| car.owner_name}

上記を実行すると

SELECT cars.*, owners.name as owner_name FROM "cars"
 INNER JOIN "owners" 
ON "owners"."id" = "cars"."owner_id"
=> ["ichiro", "ichiro", "saburo", "jiro"]

と結果が出るはずです。


並び順などに注目していただくとわかりますが、

carsテーブルが基準となっているので、

車が2台登録されている"ichiro"は2回出て、

並び順はcars.idの順番に並んでいます。


まとめ

最後に内部結合のポイントをまとめておきます。

  • 値が一致したレコードのみを取得、結合する

  • 基準となるテーブルは右側(FROM)のテーブル

  • 基準テーブルは並び順などに関係してくる

基準テーブルについては結合全体で関係してくることです。

次は外部結合について書きたいと思います。


補足

「内部結合/詳細」の中で

基準となるのがFROMの方のテーブルなのでcarsのレコードが表示されていますが、

結合されているのでINNER JOINownersの値も取得できます。

と書きましたが、

これはその後の番外で解説したSELECT句に結合する方のカラムを指定した時のみ、

そのカラムの値を使用できるようです。


試しにOwnerモデルの方でCarsをjoinして以下のようにやってみましたが、

NoMethodErrorが出ました。

# Model
def self.owner_list
    @owner = Owner.joins(:cars)
end

# View
# dealership: ディーラー名
<% Owner.owner_list.each do |owner| %>
    <%= owner.dealership %>
<% end %>

モデルを以下のように書き換えるときちんと表示できました。

def self.owner_list
    @owner = Owner.joins(:cars).select("owners.*, cars.dealership")
end

【jQuery】Ajaxでサーバー側にアクセスする

f:id:song-of-life1352607:20180113005923j:plain

こんにちは、マリンです。

今更ながら、「Ajaxでサーバーのアクセスする」と言う意味がわかりました。

というか、それで何ができるのかということがわかったので、

嬉しくて思わず書き記したくなりました。


Ajaxとは?

ウィキペディアによると、

Ajax(エイジャックス、アジャックス)は、ウェブブラウザ内で非同期通信を行いながらインターフェイスの構築を行うプログラミング手法である。XMLHttpRequest(HTTP通信を行うためのJavaScript組み込みクラス)による非同期通信を利用し、通信結果に応じてダイナミックHTML (DHTML) で動的にページの一部を書き換えるというアプローチを取る。

……え、なんて??

理解力の乏しい私にはなかなかです。。。

順を追って噛み砕いてみましょう。


従来とAjaxの違い

通常のデータ通信は同期通信と言って、

クライアントがサーバーへリクエストを送り、

そのレスポンスを受け取って画面遷移を行うという流れです。

クライアントとサーバーのリクエスト・レスポンス、

それぞれの送受信のタイミングが揃っていないといけないので、

レスポンスが帰ってくるまでの間他の処理はできません。

双方が同期しているので、同期通信です。


一方ここにある非同期通信とは、

「リクエストは送るが、レスポンスが帰ってくるのを待たない」

という通信方法です。

待たないということは、その間に別の処理を行えるということです。


更に「ウェブブラウザ内で」という点もポイントです。

つまりJavaScriptがこの送受信を行ってくれるので、

画面遷移をしなくて済むということです。


よくある例ですが、Google mapで見てみましょう。

Google mapは地図をドラッグすると、自動的に新しい未表示部分を表示してくれますよね?

これはJavaScriptが足りない地図を非同期通信でリクエストしてくれているからです。

レスポンスを待たないのでドラッグし続けられるし、

画面遷移しないのでいちいちリロードすることもありません。


つまるところ

XMLHttpRequest(HTTP通信を行うためのJavaScript組み込みクラス)による非同期通信を利用し、

リクエストは送るけどコレ非同期通信だから、


通信結果に応じてダイナミックHTML (DHTML) で動的にページの一部を書き換えるというアプローチを取る。

結果出たらそれに合わせて画面調整するから教えてね。その間に先進んどきます!


ということを可能にする仕組みがAjaxです。

語弊があったら指摘してください!!


Ajaxを使ってサーバーにアクセスする

さてここからが本題です。これによって何ができるのか?

まぁ、上にあげたことが全てではあるのですが、

理解が浅かったせいで気づかなかったんですね。

JavaScriptを使ってサーバーにアクセスするってことは、

ブラウザ側でデータ扱えるってことじゃないですか!


仕事でjQueryとかも書くようになってきた最近。

「あ〜。。。でもここJSだからデータ取ってこれないもんなぁ〜。。。」

ってことが度々ありました。

これを解決してくれるわけですね!

いや、そもそもそのためでしょ?ってのはよくわかってますから!

なので今更ながらAjaxの利用価値に気づいたというお話です。


使い方

では使い方。むしろ本題はこっちか。

Railsを使っているのでCoffeeScriptの記述方式です。

jquery-rails 4.3.1を使っています。

$.ajax "url"
    success: (value) =>
        // 通信成功時の処理内容
    error: =>
        // 通信失敗時の処理内容

$.ajax "url"

urlのサーバーにアクセスします。


success: (value) =>

これ以降に通信に成功した時の処理を記述します。

引数のvalue(名前は自由)にサーバーから返された値が入ります。


error

これ以降に通信に失敗した時の処理を記述します。

引数を取る場合はsuccessと同じようにしてください。


因みに、サーバー側から返す値はJSON形式にする必要があるようです。

def return_jquery
    # result = 処理
    render json: result
end

こんな感じで。


以上となります。

理解できたことが嬉しくて書きましたが、

単に自分の理解力の無さが露呈しただけで終わりました。。。

ご指摘がございましたらぜひともご教示ください。

【Ruby】RubyでURLにクエリ情報を追加する

f:id:song-of-life1352607:20180204234624j:plain

こんにちは、マリンです。

現在上司からjQueryの本を貸していただき、

その中から出された課題を解いています。

PHPを使ってYoutube Data APIにアクセスし動画情報を取得。

それをjQueryからAjaxを使って表示するという内容で、

PHPの部分をRubyに置き換えて行うというものです。


未だ課題クリアに至らないのですが、

その過程で学んだ様々なことを忘れないように書き記しておこうと思います。

今回は「RubyでURLにクエリ情報を追加する」というものです。

ちなみにこの課題、よせばいいのにRailsを使わず、

あくまでRubyだけで頑張っています。。。





Youtube Data API

そもそもYoutube Data APIとはなんぞや?

それはGoogleが提供するAPIの一つで、

Youtubeの機能をお手軽に使わせていただけるありがたい便利ツールです。


基本的にはお目あての機能のURLにアクセスすることで使用可能です。

(ただ書籍の仕様とはちょっと変わったみたいで、

APIキーなどの取得が必要となり、

まずそこで困惑したことは秘密です。。。)


今回はAPIのお話ではないので詳しい使い方は省きますが、

アクセスする際に特定のクエリパラメータを渡す必要があります。

今回はその部分をRubyを使って実装しよう!というお話です。


Youtube Data APIの使い方はこちらをどうぞ

YouTube Data API の概要  |  YouTube Data API (v3)  |  Google Developers




URLを書き換える

ソースコード

Rubyは2.4.0を使っています。

require 'uri'

uri = URI('https://www.googleapis.com/youtube/v3/search')

uri.query = URI.encode_www_form({
    part: 'snippet', q: ’〇〇', key: '〇〇'
  })

.query=.encode_www_formを使うため、

RubyのライブラリからURIライブラリを読み込んでいます。

class URI::Generic (Ruby 2.4.0)




詳細

Youtube Data APIURI

まず最初にYoutube Data APIにアクセスするためのURIを変数に入れています。

uri = URI('https://www.googleapis.com/youtube/v3/search')

今回使用する昨日は動画検索機能なので、

最後にsearchという文字が付いています。


.query=

RubyURIライブラリのURL::Genericクラスのメソッドです。

対象のインスタンスのクエリを設定します。

ここでは、youtubeのsearchのURIを格納したuriに対して設定しています。

uri = URI('https://www.googleapis.com/youtube/v3/search')

uri.query = ~




URI.encode_www_form

RubyURIライブラリのURIモジュールのメソッドです。

引数からapplication/x-www-form-urlencoded 形式の 文字列を生成します。

application/x-www-form-urlencodedはこちら

リクエストとレスポンスの仕組み



引数には通常は[key, value]の配列の形で渡します。

[key, value]の形ならハッシュも可です。

今回はAPIにパラメータを渡すために使用しています。

uri.query = URI.encode_www_form({
    part: 'snippet', q: ’〇〇', key: '〇〇'
  })

各パラメータの説明はこちら

Search: list  |  YouTube Data API (v3)  |  Google Developers

keyには最初の登録で取得したAPIキーを入れます。


まとめ

URIの書き換えはAPIに限らず役に立つと思うので、

今回勉強できてよかったです!

ついでにエンコードらへんの仕組みとかもサラッとなでれたし、

今度参考にさせていただいた記事をじっくり読み込んでみます。


ちなみに、現在Rubyでアクセスした結果をAjaxを使ってjQueryの方で処理する段階で、

なぜかRubyの実行結果ではなく、ソースコードがそのまま渡ってくる謎現象にハマっています。

お心当たりのある方、よろしければご教授願います。。。