【SQL】テーブル結合 ー外部結合ー
こんにちは、マリンです。
前回の続き、次は外部結合についてです。
内部結合についてはこちらです⬇️
外部結合
外部結合は、結合したテーブルの指定したカラムの値が一致するものに加え、
どちらかのテーブルにしかないレコードも取得します。
どちらかというのは、基準とするテーブル(つまり左か右か)によって変わります。
例に使うテーブル構造を記述しておきます。
[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_load
やpreload
などもあります。
内部結合でも様々な方法がありますので、
ご興味のある方は調べてみてください。
なかなか奥が深い上に咀嚼に時間のかかるテーブル結合でした・・・
自分で色々試しながら理解してきましたが、
まだまだ自信がない部分も多々あります。
何か間違っているところなど御座いましたらぜひご教示ください。
最後に、今回こちらの記事に大変助けられましたのでご紹介しておきます。
【SQL】テーブル結合 ー内部結合ー
こんにちは、マリンです。
今回は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_id
とowners.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 JOIN
のowners
の値も取得できます。
そちらも検証してみました。
*INNER JOIN
の方のカラムを取得する場合にはSELECT
でそのカラムを指定する必要があります。
詳しくは補足をご覧ください。
【番外】結合した方のカラムの値を取得してみる
結合後のレコードからowners
のname
を取得してみます。
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.name
をowner_name
に変更して値を取得します。
次に、上で取得・連結したレコードの中からrailsでowner_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 JOIN
のowners
の値も取得できます。
と書きましたが、
これはその後の番外で解説した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でサーバー側にアクセスする
こんにちは、マリンです。
今更ながら、「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の記述方式です。
$.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にクエリ情報を追加する
こんにちは、マリンです。
現在上司からjQueryの本を貸していただき、
その中から出された課題を解いています。
PHPを使ってYoutube Data APIにアクセスし動画情報を取得。
それをjQueryからAjaxを使って表示するという内容で、
PHPの部分をRubyに置き換えて行うというものです。
未だ課題クリアに至らないのですが、
その過程で学んだ様々なことを忘れないように書き記しておこうと思います。
今回は「RubyでURLにクエリ情報を追加する」というものです。
ちなみにこの課題、よせばいいのにRailsを使わず、
あくまでRubyだけで頑張っています。。。
Youtube Data 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 APIのURI
まず最初にYoutube Data APIにアクセスするためのURIを変数に入れています。
uri = URI('https://www.googleapis.com/youtube/v3/search')
今回使用する昨日は動画検索機能なので、
最後にsearch
という文字が付いています。
.query=
RubyのURIライブラリのURL::Genericクラスのメソッドです。
対象のインスタンスのクエリを設定します。
ここでは、youtubeのsearchのURIを格納したuri
に対して設定しています。
uri = URI('https://www.googleapis.com/youtube/v3/search') uri.query = ~
URI.encode_www_form
RubyのURIライブラリの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キーを入れます。
まとめ
今回勉強できてよかったです!
ついでにエンコードらへんの仕組みとかもサラッとなでれたし、
今度参考にさせていただいた記事をじっくり読み込んでみます。
ちなみに、現在Rubyでアクセスした結果をAjaxを使ってjQueryの方で処理する段階で、
なぜかRubyの実行結果ではなく、ソースコードがそのまま渡ってくる謎現象にハマっています。
お心当たりのある方、よろしければご教授願います。。。
【jQuery】要素をコピーする
こんにちは、マリンです。
今回は要素をコピーする方法をご紹介しようと思います。
概要
ユーザー一覧を表示しているテーブルの行にコピーボタンを表示。
そのボタンを押すとその行のコピーを直下に挿入します。
userモデルにはnameとemailのカラムがあるとします。
コントローラには@users = User.all
を記述しておきます。
ソースコード
views/users/index.html.erb
<table> <tbody> <% @users.each do |user| %> <tr class="copy-row"> <td><%= user.name %></th> <td><%= user.email %></th> <td><%= link_to 'copy', "#", class: 'copy-user' %></td> </tr> <% end %> </tbody> </table> <script> users.copy(); </script>
assets/javascripts/users.coffee
class UsersController copy: -> $('.copy-user').on 'click', () -> currentRow = $(@).parents('.copy-row') currentRow.clone(true).innsertAfter(currentRow) false this.users = new UsersController
解説
HTML
まずはビューの方の解説です。
あまり説明することはないのですが...
<tr class="copy-row">
行全体をコピー対象にするためtr
にクラスをつけます。
tr
だけでも良いのですが、もし入れ子になっていた時など、
予期しないtr
を取ってこないためにも指定した方が安全だと思います。
<td><%= link_to 'copy', "#", class: 'copy-user' %></td>
ここがコピーボタンになります。
link_to
である必要は特にないのですが、
jQueryのソースの最後に使っているfalse
の説明のためこれにしました。
copy-user
と言うクラスをクリックのセレクターにします。
<script> users.copy(); </script>
jQueryの呼び出しです。
CoffeeScript
では本題のjQueryの部分です。
class UsersController . . . this.users = new UsersController
まず最初と最後のこの記述ですが、
このように書くと、HTMLの最後に書いたような記述で
メソッドを指定して呼び出すことができます。
仕組みについては現在勉強中です。すみません...
ちゃんと理解したらまた記事に書きます。
$(.copy-user).on 'click', () -> currentRow = $(@).parents('.copy-row')
まずはリンクをクリックした時に、
そのリンク(またはボタン等)の親の行を持ってきます。
currentRow.clone(true).innsertAfter(currentRow)
ここがキモです。
まずcurrentRow
(コピー対象の行)をclone(true)
でコピーします。
引数のtrue
で対象のイベントや変数もコピーしてくれます。
ちなみに(true, false)
と第2引数をとることもでき、
この場合は子要素のイベントはコピーされません。
こちらを参考にさせていただきました。
jQuery リファレンス:clone
次にinnsertAfter(currentRow)
でオリジナルの直下に挿入しています。
.clone
はただ要素の中身諸々をコピーするだけですので、
このように必ずどこかに表示してあげないと画面には反映されません。
なお、もしコピーする行に固有のid
とかが付いていた場合、
それも一緒にコピーしてしまって予期しない動作が起こったりしますので、
その場合はそれらを削除する必要があります。
(私の場合はid番号が付いていてdelete
でオリジナルも消えました...)
コピーの動きについては以上です。
補足
コピーの話とは関係ありませんが、最後にあるfalse
についてです。
これは該当要素の本来の動きを打ち消してくれるようです。
今回で言えばクリックの対象をlink_to
にしていました。
false
なしだとクリックした時に、一瞬行が表示されて、そして消える。
というような不可解な挙動をしたりします。
これはクリックイベントの処理の後にlink
本来の動きをしたために起こることです。
この動きを打ち消すことで消えることなく無事表示されます。
まとめ
要素をコピーして表示するというのは結構見かける機能な気がします。
今回はただ単に一覧の行をコピーして入れただけですが、
実際には複数のデータを一括で編集するフォームに実装しました。
覚えておけばまたどこかで使えそうです。
なんだかんだ1年経ってた。
今回は何のためにもならないボヤキです。
タイトルの通りなんですけど、
年明けて改めて初投稿の日付け見たら
とっくに1年経ってましたww
と言うお話し。(笑)
この1年、あっという間ではありましたが、
それなりに環境は大きく変わったなと思います。
適当に何となく独学してた1年前から、
バイトを始めた約半年前。
てか大きく変わったのは半年前か…
あの時思い切って一歩踏み出して本当に良かったと思います!
基礎的な勉強だけでは分からなかった、
というか私の勉強方法では絶対に分からなかった事を沢山学びました。
まだ全然足りてないんですけど…
今さらですがブログの名前、
「主婦がアプリをリリースするまでの軌跡」
なんですよね。
なんて大それた名前付けちゃったんだろ…(笑)
でも今ならちょっとしたものなら作れる気がする!
とは言え、未だ職場でちゃんと戦力になれていなくて焦ってるので、
実現はまだまだ先になりそうです。
(アイデアも全然浮かばないし)
ということで、
1年経ってもブログ名の目標を達成していない事への言い訳でした。
とりあえず上半期の目標は、
バイト始めて1年になる7月までにはせめて、
ちゃんと戦力になって完全在宅になっている事を目指します!(笑)
【jQuery】クリックでテーブルの行をハイライトさせる。
皆さん明けまして(だいぶ経ちますが)おめでとうございます。
本年もまったり更新していこうと思いますので、どうぞよろしくお願い致します。
さて、2019年最初の一発目は、
jQuryです!
最近「勉強してください・・・」と上司にガッカリされましたorz
今回は、クリックしたテーブルの行をハイライトさせてみました。
ポイントはハイライトなので”1行だけ”というところです。
クリックした行全ての色が変わるのを防止します。
ソースコード
今回のコードはCoffeeScriptで書いています。
(基本Railsで書いてるので...)
highlightRow: -> $('.select-row').off 'click' $('.select-row').on 'click', () -> currentTr = $(@).parents('tr') if currentTr.hasClass('selected') currentTr.removeClass('selected') else $('tbody>tr').removeClass('selected') currentTr.addClass('selected')
select-row
というクラス名のボタンをクリックすると、
その行をハイライトし、もう一度クリックすると消えます。
// ハイライト用のスタイル .selected { background-color: #f5f5f5; }
ハイライトをする行にはclass="selected"
を付け、
スタイルシートでselected
にハイライト用のスタイルを適用させます。
ハイライトのON/OFFはこのselected
の有無で切り替えます。
解説
ハイライトOFF
まずは最初からハイライトを消すところまでです。
// 読み込まれた際に一度イベントハンドラーを削除。 $('.select-row').off 'click' $('.select-row').on 'click', () -> // クリックされたselect-rowの親のtrを持ってくる。 currentTr = $(@).parents('tr') // 親のtrが既にselectedを持っていたら(ハイライト状態なら) if currentTr.hasClass('selected') // selectedを削除してハイライトを解除する。 currentTr.removeClass('selected') else // ハイライト用
今回はボタンにselect-row
をつけ、それをクリックすることでハイライトを切り替えます。
なのでスタイルを行全体につけるため、
クリックした時にまずはボタンの親要素であるtr
を取得します。
次に、取得したtr
が既にselected
を持っていたら、
そのクラスを削除します。
これでハイライトを解除します。
ハイライトON
最後にハイライトをONにする部分です。
else
以降を書きます。
. . . else // 一度全trのselectedを削除する。 $('tbody > tr').removeClass('selected') // currentTrにだけselectedを追加。(ハイライト) currentTr.addClass('selected')
currentTr
へのselected
追加だけだと、
どこかをハイライトした状態で別の行のボタンをクリックすると、
そちらの行と前にクリックした行の両方がハイライトしてしまいます。
そのため、一度全部のtr
からselected
を削除します。
改めて対象の行にselected
を追加。
これでその行だけをハイライトすることができます。
まとめ
今まで人の書いたものを真似するだけでしたが、
今回が初めて自分で考えて作る作業となりました。
最初は「全部のtr
からクラスを削除する」ことをしなかったために、
クリックした行全てがハイライトされてしまったり、
$('tbody > tr')
のセレクターの取り方をせず、
「tbody
配下のtr
を一つずすeach
で回してselected
を調べて...」
なんてjQueryの意味がない!なんてことやってました。
結局上司の助言をいただいて完成した形になりましたが、
良い勉強になりました。
今年はjQueryもいっぱい勉強することになりそうです。
皆さま、本年もどうぞご教授のほど、宜しくお願い致します。