- 投稿日:2020-05-18T23:50:42+09:00
railsアプリでホームのビューを指定する[root]
rootについて
railsのアプリでメイン画面を指定したい時があるかと思います。
そんな時にroutes.rbにrootを指定するだけで簡単に指定できます。config/routes.rbroot to: "コントローラー名#アクション名"これでメイン画面を指定できます。
例を書いてみます。
posts_controllerのindexアクションのビューをメイン画面に指定したいときは、config/routes.rbroot to: "posts#index"と記載します。
この場合、posts_controllerにindexアクションを書かなくても、app/views/posts/index.html.erbさえあればビューとして表示することが可能です。
最後までご覧いただきありがとうございます。
- 投稿日:2020-05-18T23:19:36+09:00
【Rails】Railsチュートリアルでの学び
- 投稿日:2020-05-18T22:57:47+09:00
AtCoder Beginner Contest 168
3回目の挑戦。
A問題
case文を使うための例題、なのだが全部書き下ろしてパス
abc168a.rbn = gets.chomp.to_s[-1,1] #puts n #puts n[-1,1] if n=="3" puts "bon" else if n== "0" puts "pon" else if n== "1" puts "pon" else if n== "6" puts "pon" else if n=="8" puts "pon" else puts "hon" end end end end endB問題
出力を場合分けするより、長い場合は切り取って末尾に3点ドット付け足した方がスマートですね。
abc168b.rbk = gets.chomp.to_i s = gets.chomp.to_s if s.length <= k puts s else print s[0..k-1] print "..." endC問題
2針とも先端の座標が求まるので、2点間の距離を直接計算。
各数値を整数のまま扱ってテストケースの半分AC半分WAとなったので、しばらく考えてfloatに変換してAC.
解説にあったように余弦定理で解くと三角関数3個分計算量減るけど、ループないからこれでも良いかな?abc168c.rbimput = gets.chomp.split(" ").map!{|item| item.to_i} a = imput[0].to_f b = imput[1].to_f h = imput[2].to_f m = imput[3].to_f hang = Math::PI*(30*h + m/2)/180 mang = Math::PI*m*6/180 hy = Math.sin(hang)*a hx = Math.cos(hang)*a my = Math.sin(mang)*b mx = Math.cos(mang)*b puts Math.sqrt((hy-my)**2 + (hx-mx)**2)この辺りで60分超えてD問題読んで解けそうにないので断念。
D/E/Fに挑むにはアルゴリズムの例題解いて身に付けるしかないか。
今回のA問題のように力技依存しないように定番過去問の数こなす必要ありそう。
- 投稿日:2020-05-18T22:26:44+09:00
ブラウザではじめるRubyゲームプログラミング:Nyle-canvas(DXRubyスタイル)入門
概要
この記事は中学高校生向けプログラミング教室の教材として作ったものを一部改変したものです。
ブラウザだけでRubyのゲームプログラミングがすぐに始められる、Nyle-canvasの使い方を学んでいきます。
そして、応用として「ブロック崩し」などのゲームを自分で作っていくことを目指します。
技術解説
Nyle-canvasとは
Nyle-canvas は、ブラウザ上で動くRubyエディタ・実行環境一体型の統合開発環境です。これは、最近ではScratchなどさまざまなプログラミング言語での開発にも採用されている方式です。
その一番の特長は、パソコンやタブレットのブラウザ(Chromeなど)とネット環境があれば、簡単にRubyのプログラミングを始めることにあります。
Nyle-canvasの特長
- Rubyのインストール不要
- エディタ、ターミナルソフト(「コマンドプロンプト」、「PowerShell」、「ターミナル」など)不要
- さまざまなOSで動作(WindowsやmacOS、Linux、Android、iPadOS、iOSなど)
- タブレット端末でも動作可能(外付けキーボード、マウス推奨)
- プログラムはOSに依存せず動作
- 保存操作なしで、直ちに実行可能
- 画像データも一体で管理
- DXRuby互換の書式で記述可能
Nyle-canvasの動作環境
- ブラウザ(Chromeなど)
- インターネット接続
従来、プログラミングを始める前に必要だった煩雑な準備が不要で、すぐにプログラミングが始められます。また、ブラウザが動く環境であれば、パソコンだけでなく、タブレット(iPadなど)などさまざまなマシン上で動作します。そして、書いたプログラムは保存操作なしで直ちに実行可能で、プログラミングした結果の確認が素早く何度でも簡単にできるようになります。さらに、プログラムファイルや画像データの管理や、複数のソフトの切替え操作からも解放されます。
以上に加え、Nyle-canvasは、Rubyの2Dゲームライブラリとしてよく使われているDXRubyとほぼ同じ記述で動かせるのも魅力です。そのため、DXRubyで書かれたプログラム資産の活用や、Mac上でDXRubyの書き方でゲーム開発をしたいという要望にも応えてくれます。
なお、Nyle-canvasは、第12回フクオカRuby大賞(2019年度)優秀賞受賞作品です。
http://www.digitalfukuoka.jp/topics/144?locale=jaNyle-canvas(DXRubyスタイル)
Nyle-canvasの記述スタイルの内、DXRuby互換のDXRubyスタイルを採用します
バージョン
Nyle-canvas(DXRubyスタイル);dev1(2020/3/15リリース)
実行環境
ブラウザ;
Google Chrome(バージョン 81.0.4044.138,64 ビット,macOS版)実行OS;
macOS(Catalina 10.15.4)その他、Safari/macOS,Chrome/Windows10 でも適宜動作確認
ホームページ
Nyle-canvas Wiki
https://github.com/spoolkitamura/nyle-canvas-doc-jp/wikiNyle-canvasホームページ
https://spoolkitamura.github.io/nyle-canvas/dev1/site/index.htmlNyle-canvasマニュアル;エディタの操作方法
https://spoolkitamura.github.io/nyle-canvas/dev1/site/manual_editor.htmlNyle-canvas(DXRubyスタイル)エディタ;実際にプログラミングするエディタ画面
https://spoolkitamura.github.io/nyle-canvas/dev1/nyle-canvas.html?style=dx参考サイト
DXRuby のホームページ
http://dxruby.osdn.jpDXRuby 1.4.6 リファレンスマニュアル
http://mirichi.github.io/dxruby-doc/index.htmlDXRuby 1.4.1 リファレンスマニュアル
http://dxruby.osdn.jp/DXRubyReference/20095313382446.htmDXRubyスタイルのオリジナルであるDXRubyのページです。
- Ruby用2Dゲームライブラリ DXRuby:使い方の初歩 - Qiita
https://qiita.com/noanoa07/items/bced6519d9b53685b651
この記事の元になった、DXRubyの入門記事です。
https://yhara.github.io/dxopal/index.html
- Rubyで始めるゲームプログラミング - DXOpal編 - Rubyist Magazine 0057号 https://magazine.rubyist.net/articles/0057/0057-GameProgramingWithDXOpal.html
こちらもブラウザで動くDXRuby(互換)ライブラリです。
ソースコード
https://github.com/noanoa07/nyle-canvas-intro
ライセンス
本解説文および解説内のRubyソースコードはともにパブリックドメイン
(Nyle-canvas本体のソースコードは、MITライセンス)プログラム解説
1. Nyle-canvasの使い方
初めに、Nyle-canvasの基本的な使い方を体験してみます。
1-1. Nyle-canvasエディタ
Nyle-canvasは、ブラウザで以下のサイトにアクセスすることで、プログラム編集画面(エディタ)が表示されます。
なお、ここではブラウザとしてGoogle Chromeを使って説明していきます。(実行環境はmacOS。)
https://spoolkitamura.github.io/nyle-canvas/dev1/nyle-canvas.html?style=dx
1-2. エディタ画面の解説
エディタ画面にはあらかじめ基本のプログラムが表示されています。
また、画面左上には各種ボタンが並んでいます。
右から、
- ▶︎ ボタン;プログラム実行
- ↓ ボタン;プログラム保存(ダウンロード)
- Tボタン;フォント(文字サイズ)設定
- ?ボタン;ヘルプ(リファレンス)画面へ1-3. プログラムの実行
あらかじめ基本のプログラムが表示されているので、とりあえず ▶︎ボタンを押してプログラムを実行してみます。
rb_dx00.rb# 初期設定用のコード (your setup code here) Window.width = 640 Window.height = 480 Window.bgcolor = DX::C_BLACK Window.loop do # 画面描画用のコード (your draw code here) endすると、ブラウザの新しいタブが開き、黒い四角形が表示されます。これが、基本のウィンドウ画面になります。
1-4. プログラムの保存
このプログラムを保存してみます。↓ボタンを押すと、ダイアログが出て、OKを押すと、プログラムがダウンロードされます。ダウンロード先は、ブラウザの設定によりますが、「ダウンロード」フォルダになることが多いようです。
このように、ダウンロードフォルダに日付と時刻を元にした名前が付けられたファイルが保存されています。
ここで、保存されたプログラムファイルが、HTMLファイルなのに注意してください。
このファイルには、Rubyのプログラム部分だけでなく、ブラウザで実行するためのデータ、さらには画像データなどもすべて含まれています。HTMLファイルの中身がどうなっているか見たいと思ったら、エディタで開くと中身が確認できます。
rb_dx00.html<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Nyle-canvas</title> <!-- Nyle-canvas editor v0.7.0 --> </head> <body> <script type="text/javascript" src="https://cdn.opalrb.com/opal/0.11.4/opal.min.js" onload="Opal.load('opal')"></script> <script type="text/javascript" src="https://cdn.opalrb.com/opal/0.11.4/opal-parser.min.js" onload="Opal.load('opal-parser')"></script> <script type="text/javascript" src="https://cdn.opalrb.com/opal/0.11.4/native.min.js" onload="Opal.load('native')"></script> <script type="text/javascript" src="https://spoolkitamura.github.io/nyle-canvas/dev1/nyle-canvas.js"></script> <script type="text/javascript"> </script> <script type="text/ruby"> # 初期設定用のコード (your setup code here) Window.width = 640 Window.height = 480 Window.bgcolor = DX::C_BLACK Window.loop do # 画面描画用のコード (your draw code here) end </script> </body> </html>このように、HTMLファイルの中にRubyプログラムが埋め込まれているのが分かります。
また、ファイルとしてはHTMLファイルなので、直接ダブルクリックするか、ブラウザの任意のウィンドウにドラッグ&ドロップすると、Rubyのプログラムが実行されます。
1-5. 保存したプログラムの名前の変更
保存されたプログラムフォルダの名前は、普通のファイル名変更のやり方で自分の好きな名前に変更できます。
1-6. プログラムの読み込み
保存してあるプログラムの内容を見たり、編集するには、プログラムファイル(HTMLファイル)をブラウザのNyle-canvasエディタ画面にドラッグ&ドロップします。
すると、ダイアログが開いて、「ドロップされたファイルを読み込みますか?」と聞いてくるので、OKを押すと読み込まれます。
ちなみに、読み込んだファイルを再度保存すると、同じ名前で上書き保存されそうですが、実際は上書きはされず、
xxxx(1).html
のような違う名前で区別されて保存されます。(細かい挙動は、実行環境に依存します。)1-7. プログラムの新規作成
プログラムを新規作成したくなったら、ブラウザのNyle-canvasエディタ画面を再読み込みすると、最初の状態に戻ります。
再読み込みは、ブラウザ上部の「↻」ボタンを押すか、メニュー>ファイル>表示>ページを再読み込み を選ぶとできます。1-8. コンソールの開き方
エラーメッセージやputsの結果は、ブラウザのコンソールに出力されます。まずは、コンソールを表示させてみましょう。
Chromeでの開き方は;(実行画面で)
- macOSの場合; メニュー>表示>開発/管理>Javascriptコンソール を選択。
(ショートカットは、Command + Option + J)
- Windowsの場合; メニュー> その他のツール>デベロッパーツール> 開いたデベロッパーツールの中の「Console」を選択。
(ショートカットは、Ctrl + Shift + J)
あるいは、macOS、Windowsとも;
F12(あるいは fn + F12)キーを押すか、
画面上の任意の場所で 右クリック(2本指クリックなど)>検証>開いたデベロッパーツールの中の「Console」を選択。
参考)コンソールの表示位置の変え方
Chromeのコンソール(デベロッパーツール)の表示される位置は、設定によって下側だったり、右側だったりします。
好みのレイアウトに変えるには、右端の(赤く囲った)縦3点「︙」ボタンをクリックすると、メニューが現れるので、「Dock side」のアイコンの中から選びます。
1-9. コンソールの使い道
A) エラーメッセージの確認
プログラムを実行させてエラーが起きた時に、エラーメッセージを見ることができます。
この実行画面では、エラーにより真っ白な画面になってしまいました。
コンソールが開いた画面がこちらです。
ここでは、赤い行にエラーメッセージが表示されています。
ただし、このエラーメッセージはなかなか分かりにくいことがあります。(内部で、Ruby→JavascriptパーサOpalを通してJavascript実行されているため。)
今後の機能改善に期待したいところです。少なくとも、”今、エラーが出ているか?” という確認や、エラーのヒントとして十分役に立ちます。
B) puts や p の出力を見る
コンソールは、puts や p の出力先にもなっています。
rb_dx00a.rb# 初期設定用のコード (your setup code here) Window.width = 640 Window.height = 480 Window.bgcolor = DX::C_BLACK puts "Hello!" # ◆追加 p "こんにちは!" # ◆追加 Window.loop do # 画面描画用のコード (your draw code here) endこのプログラムを実行すると、コンソールに Hello!、"こんにちは!" と出力されるのが分かります。
1-10. ヘルプ(リファレンス)
Nyle-canvasエディタ画面左上の「?」ボタンを押すとヘルプ(リファレンス)画面が開きます。
→ [Nyle-canvas] APIリファレンス (DXRubyスタイル)
https://spoolkitamura.github.io/nyle-canvas/dev1/site/_man_api_dx/index.htmlNyle-canvasのAPIが簡潔にまとめられているので、困ったときにはどんどん活用してください。
1-11. 全角文字に注意
Nyle-canvasだけではありませんが、ほとんどのプログラミング言語では全角の文字は命令として使えません。特に、全角のスペース(空白文字)が入っていると、エラーになっても見つけにくいので要注意です。
1-12. 便利機能
Nyle-canvasエディタには、プログラム作成に便利な機能が備わっています。
キーボードショートで呼び出します。
- 検索:command + F(macOS)、ctrl + F(Windows)
- 置換:command + option + F(macOS)、ctrl + H(Windows)1-13. Nyle-canvasでのプログラミングのやり方
Nyle-canvasでは、編集したプログラムを保存しないでも、すぐに実行することできます。そのため、“ちょっと書き直したら、ちょっと動かしてみる” というやり方が向いています。
以下の練習でもそのやり方でやってみましょう。
2. Nyle-canvasの練習
2-0. ウィンドウを出す
1-3.で体験した通り、Nyle-canvasエディタ画面を開くと、あらかじめ基本のコードがすでに書かれています。
(書き換えている場合は、「1-7.プログラムの新規作成」の通りに、画面を再読み込みしてください。)
以下、Rubyのプログラム部分だけを載せていきます。
rb_dx00.rb# 初期設定用のコード (your setup code here) Window.width = 640 Window.height = 480 Window.bgcolor = DX::C_BLACK Window.loop do # 画面描画用のコード (your draw code here) end初期設定では、横640、縦480、黒色のウィンドウが開きます。
座標は、左上が原点(0, 0)、横(x)は右方向に増加、縦(y)は下方向に増加です。
Window.loop do 〜 end
の間に書いたコードは、1秒間に60回繰り返し実行されます。→ DXRubyリファレンス:チュートリアル 1. 基本の形
http://mirichi.github.io/dxruby-doc/tutorial/basic.html2-1. 初期設定を修正
初期設定に
include DX
と書くことで、色定数の
DX::C_BLACK
がC_BLACK
と、よりDXRubyと互換性が高くなるので追加します。これ以降のプログラムでも、
include DX
はすべて書いておくことにします。rb_dx01.rb# 初期設定用のコード (your setup code here) include DX # ◆追加 Window.width = 640 Window.height = 480 Window.bgcolor = C_BLACK # ◇変更 Window.loop do # 画面描画用のコード (your draw code here) end2-2. ウィンドウの大きさを変える
ウィンドウの大きさを変えるには、
Window.width =
、Window.height =
を使います。プログラムの内、最初の1回だけ実行されて以後変える必要のないものは、
Window.loop do 〜 end
より前に書いておきます。rb_dx02.rb# 初期設定用のコード (your setup code here) include DX Window.width = 200 # ◇変更 Window.height = 150 # ◇変更 Window.bgcolor = C_BLACK Window.loop do # 画面描画用のコード (your draw code here) end2-3. ウィンドウの背景の色を変える
ウィンドウの背景の色を変えるには、
Window.bgcolor =
を使います。色の指定は、Nyle-canvasエディタのヘルプボタンを押して表示される、 「APIリファレンス」の「色に関する情報」を見てください。
(2-2.で、初期設定に
include DX
を加えたので、DX::
は省略できます。)rb_dx03.rb# 初期設定用のコード (your setup code here) include DX Window.width = 640 # ◇変更(戻す) Window.height = 480 # ◇変更(戻す) Window.bgcolor = C_CYAN # ◇変更 Window.loop do # 画面描画用のコード (your draw code here) end2-4. 画面に文字を出す
画面に文字を出すには、
font = Font.new(文字サイズ)
で文字サイズ(とフォント名)を指定しておいて、
Window.draw_font(x位置, y位置, "文字列", フォント, {:color => 色})
で表示します。
rb_dx04.rb# 初期設定用のコード (your setup code here) include DX Window.width = 640 Window.height = 480 Window.bgcolor = C_BLACK # ◇変更(戻す) font = Font.new(32) # ◆追加 Window.loop do Window.draw_font(200, 100, "ブロック崩し", font, {:color => C_GREEN}) # ◆追加 end2-5. キー入力をとらえる
キー入力は
Input.key_down?(キーコード定数)
を使います。キーコード定数については、「APIリファレンス」の「キーコードに関する情報」を見てください。
(
include DX
が書いてあれば、DX::
は省略できます。)rb_dx05.rb# 初期設定用のコード (your setup code here) include DX Window.width = 640 Window.height = 480 Window.bgcolor = C_BLACK font = Font.new(32) Window.loop do Window.draw_font(150, 100, "A のキーを押してください", font, {:color => C_GREEN}) # ◇変更 if Input.key_down?(K_A) # ◆追加 Window.draw_font(300, 250, "A", font, {:color => C_WHITE}) # ◆追加 end # ◆追加 end2-6. 図形の表示
ウィンドウに基本的な図形を表示します。
表示できるのは、線、直線、四角、円です。表示するには、それぞれ以下の命令を使います。
- 点 :Window.draw_pixel
- 直線 :Window.draw_line
- 四角 :Window.draw_box
- 四角(塗りつぶし):Window.draw_box_fill
- 円 :Window.draw_circle
- 円(塗りつぶし) :Window.draw_circle_fill画像を読み込んだり、動かしたり、いろいろと操作するには、これとは別に Imageクラスが用意されています。
rb_dx06.rb# 初期設定用のコード (your setup code here) include DX Window.width = 640 Window.height = 480 Window.bgcolor = C_BLACK Window.loop do Window.draw_box_fill(100, 100, 540, 380, C_YELLOW) # ◇変更 end2-7. 画像の読み込み
Nyle-Canvasでは、画像ファイルの取り扱い方が DXRubyとは少し異なります。
まず、使いたい画像ファイルをエディタ画面に直接ドラッグ&ドロップしていきます。すると、画像ファイルはNyle-canvas内にコピーされ、エディタ画面下側に画像ファイルの一覧として表示されるようになります。
(ちなみに、いらなくなった画像ファイルは、一覧の右側の「取り消し」ボタンを押すと、一覧からなくなります。)
試しに、
src/imageフォルダ
にあるapple.png
ファイルをエディタ画面にドラッグ&ドロップしてみます。
画像ファイルapple.png
がコピーされ、一覧に表示されました。このように、画像ファイルとプログラムを一体で管理するのが、Nyle-canvasの大きな特徴です。
次に、プログラムから画像ファイル読み込んで使うには、
Image.load(画像ファイル)
を使います。画像ファイル名の前に場所を示すパス名などは不要です。読み込んだ画像は、Imageクラスになります。
Imageクラスの表示は、
Window.draw(x座標, y座標, イメージ)
を使います。なお、座標の基準はイメージの左上になります。rb_dx07.rb# 初期設定用のコード (your setup code here) include DX Window.width = 640 Window.height = 480 Window.bgcolor = C_BLACK apple = Image.load('apple.png') # ◆追加 Window.loop do Window.draw(100, 100, apple) # ◆追加 end参考)画像を含んだプログラムを保存すると、画像はどうなる?
保存したプログラムのHTMLファイルをエディタで開いてみます。
(一部省略)rb_dx07.html<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Nyle-canvas</title> <!-- Nyle-canvas editor v0.7.0 --> </head> <body> <script> (省略) </script> <script type="text/javascript"> Store.createImage('apple.png', 100, 100, 'data:image/png;base64,iVBORw0KGgoAAAANSU....(途中省略)....ElFTkSuQmCC') </script> <script type="text/ruby"> # 初期設定用のコード (your setup code here) include DX Window.width = 640 Window.height = 480 Window.bgcolor = C_BLACK apple = Image.load('apple.png') # ◆追加 Window.loop do Window.draw(100, 100, apple) # ◆追加 end </script> </body> </html>このように、
'apple.png', 100, 100, 'data:image/png;base64,iVBOR....
の部分で、apple.png
の画像データはBase64でエンコードされて一緒に保存されていることが分かります。そのため、プログラムで使う画像データの管理に気を使うことなく、プログラミングに集中できる仕組みになっているのです。
2-8. 画像の背景色の透明化
イメージで
set_color_key(色)
を使うと、指定した色を透明にできます。註)
2020/3/15リリースの
dev1
ではこの機能は未実装になっています。【注意】
内部処理がまだ実装されていないため、このメソッドを実行しても指定色は透明化されません。
その代わりに、Image.loadおよび Image.load_tilesメソッド内で暫定的に白色を自動的に透明にするようになっています。
(リファレンスより)そのため、今のところ
set_color_key(C_WHITE)
を実行する必要はありませんが、将来のバージョンアップ時に対応するために記述しておきます。ちなみに、この
apple.png
は、背景が白色なので、自動的に透明化されています。rb_dx08.rb# 初期設定用のコード (your setup code here) include DX Window.width = 640 Window.height = 480 Window.bgcolor = C_BLACK apple = Image.load('apple.png') apple.set_color_key(C_WHITE) # ◆追加 Window.loop do Window.draw(100, 100, apple) end2-9. 画像の拡大・縮小
イメージを拡大・縮小して表示したい時は、
Window.draw_scale(x位置, y位置, イメージ, 横の拡大率, 縦の拡大率)
を使います。rb_dx09.rb## 初期設定用のコード (your setup code here) include DX Window.width = 640 Window.height = 480 Window.bgcolor = C_BLACK apple = Image.load('apple.png') apple.set_color_key(C_WHITE) Window.loop do Window.draw_scale(100, 100, apple, 0.5, 0.5) # ◇変更 end2-10. カーソルキーで移動
カーソルキーが押されると、左右方向は
Input.x
、上下方向はInput.y
が-1
,0
,1
に変化します。これを利用することで、画面上を移動させることができます。
rb_dx10.rb# 初期設定用のコード (your setup code here) include DX Window.width = 640 Window.height = 480 Window.bgcolor = C_BLACK apple = Image.load('apple.png') apple.set_color_key(C_WHITE) x = 200 # ◆追加 y = 200 # ◆追加 Window.loop do x = x + Input.x # ◆追加 y = y + Input.y # ◆追加 Window.draw(x, y, apple) # ◇変更 end2-11. カーソルキーで移動(別の書き方)
ball.x = ball.x + Input.x
を別の書き方である、
ball.x += Input.x
に書き換えてみます。同じ意味ですが、こちらの方が文字数が少なくて済むので、間違いが減らせるかも。rb_dx11.rb# 初期設定用のコード (your setup code here) include DX Window.width = 640 Window.height = 480 Window.bgcolor = C_BLACK apple = Image.load('apple.png') apple.set_color_key(C_WHITE) x = 200 y = 200 Window.loop do x += Input.x # ◇変更 y += Input.y # ◇変更 Window.draw(x, y, apple) end2-12. マウスに合わせて移動
マウスのx座標、y座標はそれぞれ
Input.mouse_x
、Input.mouse_y
で取得できます。なお、座標の基準はイメージの場合、左上になります。
rb_dx12.rb# 初期設定用のコード (your setup code here) include DX Window.width = 640 Window.height = 480 Window.bgcolor = C_BLACK apple = Image.load('apple.png') apple.set_color_key(C_WHITE) Window.loop do x = Input.mouse_x # ◇変更 y = Input.mouse_y # ◇変更 Window.draw(x, y, apple) end以上で、Nyle-canvasの練習は一通り終わりです。
応用問題
Nyle-canvasの使い方に慣れたところで、「ブロック崩し」を作ってみましょう!
- 投稿日:2020-05-18T21:55:04+09:00
Railsのエラー undefined method `image_name' for nil:NilClass の対処
- 投稿日:2020-05-18T15:36:02+09:00
【rails】新しいバージョンのRuby on Rails環境を用意した。
アプリケーションを作るため、新しいバージョンのRuby on Railsが必要になり、ローカル環境に用意した。
(既存アプリに影響を与えないことを条件とした)
Ruby Rails 必要なバージョン 2.7.1 6.0.3 既存のバージョン 2.5.1 5.0.7.2 参考
https://qiita.com/pharma_tech3/items/2ab578eb5b07ff0ca296
環境構築方法
rails 6.0.3の導入
terminal$ gem install rails -v 6.0.3 $ rails _6.0.3_ new linebot -d mysql ... * bin/rake: Spring inserted * bin/rails: Spring inserted rails webpacker:install sh: node: command not found sh: nodejs: command not found Node.js not installed. Please download and install Node.js https://nodejs.org/en/download/途中で
webpackage install
が実行されたときに、node.js
がないとのメッセージが出ている。node.jsをインストールする。
terminal$ brew install node $ node -v v14.2.0再度
rails webpacker:install
を実行する。terminal$ rails webpacker:install Yarn not installed. Please download and install Yarn from https://yarnpkg.com/lang/en/docs/install/今度は、yarnがインストールされていないからダウンロードしてインストールしてね。とのこと
terminal$ brew install yarn $ yarn -v 1.22.4
yarn
がインストールされた。terminal$ rails webpacker:install ... ✨ Done in 6.92s. Webpacker successfully installed ? ?
Webpacker
のインストールが成功した。terminal$ cd linebot $ rails -v Rails 6.0.3railsの新しいバージョンが使えるようになった。
新しいプロジェクトを作成する。
terminal$ rails _6.0.3_ new linebot -d mysql $ cd linebotRuby 2.7.1の導入
Ruby 2.7.1をインストールするコマンドを実行する。
terminal$ rbenv install 2.7.1 ruby-build: definition not found: 2.7.1 See all available versions with `rbenv install --list'. If the version you need is missing, try upgrading ruby-build: brew update && brew upgrade ruby-build
brew update
とbrew upgrade ruby-build
を実行してね。とのことインストール可能なリストを確認する。
terminal$ rbenv install -l ... 2.6.4 2.6.5 2.7.0-dev 2.7.0-preview1 2.7.0-preview2 2.7.0-preview3 2.7.0-rc1 2.7.0-rc2 jruby-1.5.6 jruby-1.6.3 ...インストール可能なリストの中に、2.7.1がない。
terminal$ brew update Already up-to-date.terminal$ brew upgrade ruby-build ==> Upgrading 1 outdated package: ruby-build 20191223 -> 20200401 ... ==> Caveats ==> ruby-build ruby-build installs a non-Homebrew OpenSSL for each Ruby version installed and these are never upgraded. To link Rubies to Homebrew's OpenSSL 1.1 (which is upgraded) add the following to your ~/.zshrc: export RUBY_CONFIGURE_OPTS="--with-openssl-dir=$(brew --prefix openssl@1.1)" Note: this may interfere with building old versions of Ruby (e.g <2.4) that use OpenSSL <1.1.インストール可能なリストの中に、2.7.1出現した。
terminal$ rbenv install -l ... 2.7.0-preview3 2.7.0-rc1 2.7.0-rc2 2.7.0 2.7.1 2.8.0-dev jruby-1.5.6 jruby-1.6.3 ...バージョンを指定してインストールする。
terminal$ rbenv install 2.7.1 Downloading openssl-1.1.1d.tar.gz... -> https://dqw8nmjcqpjn7.cloudfront.net/1e3a91bc1f9dfce01af26026f856e064eab4c8ee0a8f457b5ae30b40b8b711f2 Installing openssl-1.1.1d... Installed openssl-1.1.1d to /Users/Taiti/.rbenv/versions/2.7.1 Downloading ruby-2.7.1.tar.bz2... -> https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.1.tar.bz2 Installing ruby-2.7.1... ruby-build: using readline from homebrew Installed ruby-2.7.1 to /Users/Taiti/.rbenv/versions/2.7.1プロジェクトフォルダ内のみ、バージョン2.7.1を適用する。
$ rbenv local 2.7.1 $ rbenv rehash $ ruby -v ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin19]完了
- 投稿日:2020-05-18T15:19:26+09:00
railsアプリをherokuでデプロイする方法(Mysqlでも確実にデプロイできます)
本記事について
railsアプリをherokuでデプロイする方法を調べていたのですが、開発環境(developmentやtest環境)でRailsアプリに最初からついているDB(SQLite3)を使用している事を前提に書かれた記事が多く、混乱してしまったので、DBにMysqlを採用している方に向けて記事を書いていこうと思います。
※変更内容の意味を理解していればどのDBを使っていようが同じ手順だと気づくのですが、初心者の僕は混乱して躓いてしまったので、同じ様な方が少しでも楽に理解できる様に執筆しています。
環境
- Ruby 2.5.1
- Rails 5.0.7.2
- git 2.25.2
- heroku/7.41.1 darwin-x64 node-v12.16.2
事前に準備して欲しいもの
- Railsで作成したアプリ(下記二つの条件を満たしているもの)
- Gitで管理している
- ローカル環境でエラーが出ていない(デプロイ中にエラーが出た場合、デプロイ時に起こったエラーかローカル環境でのエラーが関係しているのか分からなくなってしまうので、それを防ぐ為)
- herokuのユーザー登録
- heroku-cil(herokuの機能を自分のPCに紐付けるもの→herokuのコマンドをPCで使える様にする)のインストール
今回はherokuについての記事なので、Gitについての説明は割愛させて頂きます。
デプロイ作業を始める前に
デプロイ作業を始める前に、デプロイしたいRailsアプリのコードを一部編集する必要があります。
編集するのは以下の三箇所です。
- Gemfile(各環境で使うDBの設定を変更する)
- config/datebase.yml(実際に本番環境で使うDBを接続する記述を追加する)
- config/environments/production.rb(本番環境でのプリコンパイルをオンにする)
編集する内容について一つずつ理由とともに解説していきますので、変更する場所だけ確認できたら読み進めて貰って大丈夫です。
Gemfileの設定
削除するコードが一箇所、追記するコードが二つあります。
- 削除する箇所
Gemfilegem 'mysql2'
- 追記する箇所
Gemfilegroup :development, :test do gem 'mysql2' end※group :development, :test do ~ end内に他にもgemが書いてあったと思いますが、消さないでください。
Gemfilegroup :production do gem 'pg' end何をしてんだ?
herokuではPostgreSQL(pg)というDBをデフォルトで使う様に設定されています。
普通に作っている方は、全ての環境下でmysqlを使う様に表記していると思うので、その表記を削除し、開発環境、テスト環境下のみでmysqlを使える様にgroup :development, :test do ~ end内にgem 'mysql2'の表記を追加しています。
また、本番環境でPostgreSQL(pg)が使える様にgroup :production do ~ end内にgem 'pg'を表記しています。config/datebase.ymlの設定
追記するコードが一つあります。
config/datebase.ymlproduction: <<: *default adapter: postgresql encoding: unicode pool: 5※production:内にあった元々の記述は全て削除して、上記の様に書き換えて下さい。
何をしてんだ?
先ほどgemを追加し、機能をインストールするための準備は整えたのですが、実際にDBと接続する記述はまだ完了していません。どのDBに接続するのか?という設定をする箇所がconfig/database.ymlです。
※開発環境、テスト環境で使用するDBの設定もここに書かれています。追加したコードの意味は以下の様になります。
adapter: postgresql - postgreSQLのデータベースに接続。
encoding: unicode - unicodeという文字コードを使用。
pool: 5 - DBに接続できる上限の数を指定。DBに接続する為の設定をしたんだ!ってことが分かればOKです。
config/environments/production.rbの設定
追記するコードが一つあります。
config/environments/production.rb#デフォルトでfalseとなっている以下の箇所をtrueに変更 config.assets.compile = true何をしてんだ?
Railsは本番環境でのプリコンパイルがデフォルトでオフになっています。
assetsを圧縮して少しでも軽くする為だそうです。
assets以下のフォルダから動的にコンパイルしながらページを読み込む為にtrueに変更しています。
難しく書きましたが、本番環境でも画像を読み込んでくれよ~って表記にしただけです。いよいよデプロイ作業開始
これでデプロイをする前の事前準備が終わったので、いよいよデプロイ作業に移ります。
デプロイまでの流れは以下の通りです。
- herokuにログイン
- 公開されるRailsアプリのurlを決める
- pushしてデプロイ
- 本番環境でマイグレーションをする
AWSとかと比べて超絶簡単なので気負いせずにさくっと終わらせましょう!
1.herokuにログイン
ターミナル$heroku login上記コマンドでherokuにログインします。
コマンド入力に成功すると(なんか格ゲーみたい)herokuに登録したEmailとpasswordの入力を求められるので、ゆっくり正確に入力しましょう。
入力に成功すると下記の様にターミナルに表示されます。
(as ~ は自分のメールアドレスです。)ターミナルLogged in as ~~~~~@icloud.com公開されるRailsアプリのurlを決める
https://nameless-atoll-34353.herokuapp.com/
上記のURLは僕が初めて作った個人アプリなんですが、これでいうところのnameless-atoll-34353の部分を自身で決めることができます。
heroku createだけでも問題はないのですが、僕みたいになんのアプリか分からない変なURLになるのでしっかり設定しておきましょう!ターミナル$heroku create 好きな文字列pushしてデプロイ
以下のコマンドを打つだけです。楽勝です。
この時、gitのmasterで管理されているコードがpushされるので、brunch生やして作業している方は一旦masterにpushしましょう。ターミナル$git push heroku masterこんな感じで進んでいたら順調です。
ターミナルEnumerating objects: 148, done. Counting objects: 100% (148/148), done. Delta compression using up to 4 threads Compressing objects: 100% (125/125), done. Writing objects: 100% (148/148), 39.65 KiB | 2.09 MiB/s, done. Total 148 (delta 24), reused 0 (delta 0) remote: Compressing source files... done. remote: Building source: remote: remote: -----> Ruby app detected remote: -----> Installing bundler 2.0.2 remote: -----> Removing BUNDLED WITH version in the Gemfile.lock remote: -----> Compiling Ruby/Rails remote: -----> Using Ruby version: ruby-2.6.6 remote: -----> Installing dependencies using bundler 2.0.2 remote: Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment remote: The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`. remote: Fetching gem metadata from https://rubygems.org/............下記のコードの5行目に書かれているのが、今回デプロイしたアプリのURLです。
8行目のは全然関係ないです。僕はそれで悩んでました。ターミナルremote: -----> Compressing... remote: Done: 58.8M remote: -----> Launching... remote: Released v4 remote: https://nameless-atoll-34353.herokuapp.com/ deployed to Heroku remote: remote: Verifying deploy... done. To https://git.heroku.com/nameless-atoll-34353.git * [new branch] master -> masterこれで終わりと思いきや、、まだ本番環境にDBが作成されてないので、マイグレーションをしなきゃいけません。
それで終わりだよん。
4. 本番環境でマイグレーションをする
以下のコマンドでマイグレーションしてください。
ターミナル$heroku run rails db:migrateheroku runをつけるとrailsのコマンドをherokuを動かしているときにも使える様になります。
はい。終わりです。先ほどのURLを貼っつけて、正常に見れるか確認しましょう。
見れた方、お疲れ様でした。
見れてない方、調べても分からない方は僕のTwitterにでも相談しにきて下さい。
いつでも答えますよ?(@rurukasan0212 )
- 投稿日:2020-05-18T14:29:05+09:00
初投稿
これから書き方から学んで投稿していきます。
コードを書くときは自分のアウトプット用として、いずれ誰かの助けになるようなものまで書いていけるようになりたい。更新頻度を落とさないように習慣化を目指します!
- 投稿日:2020-05-18T13:35:18+09:00
RubyでOAuth認証を使ってWeb APIへPOST HTTPリクエストの送信
RubyでHTTPリクエストを送信する
今回は一番ベーシックなnet/httpを使用したサンプルを挙げるが、RubyのHTTPクライアントは複数ある。
サンプルコード
リクエストパラメータについて、
GETの場合はパラメータをクエリストリングに含めるが、
POSTの場合はリクエストボディに含めるという点にてちょっとハマった。後で書き直す。
require 'uri' require 'net/http' require 'openssl' require 'base64' ## 1. Oauth認証によるアクセストークンの取得 # client_idと client_secretを使用 client_id = ENV['API_CLIENT_ID'] client_secret = ENV['API_CLIENT_SECRET'] credential = Base64.strict_encode64(client_id + ':' + client_secret) uri = URI.parse('https://example.oauth2/token') # アクセストークンを取得するHTTPリクエストの作成 https = Net::HTTP.new(uri.host, uri.port) https.use_ssl = true # 以下は使用するWeb APIの仕様により異なる。 request_header = { 'Authorization': "Basic #{credential}", 'Content-Type': 'application/x-www-form-urlencoded' } request = Net::HTTP::Post.new(uri.request_uri, request_header) request.body = 'grant_type=client_credentials' # リクエストの送信・レスポンスからアクセストークンの取得 response = https.request(request) response_body = JSON.parse(response.body) access_token = response_body['access_token'] ## 2. Web APIへHTTPリクエストの送信 # アクセストークンを使用するHTTPリクエストの作成 endpoint_uri = URI.parse('https://example.api.com' + '/v1/hoge/huga') https = Net::HTTP.new(endpoint_uri.host, endpoint_uri.port) https.use_ssl = true # 以下は使用するWeb APIの仕様により異なる。 request_header = { 'Authorization': "Bearer #{access_token}", 'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'application/json' } request = Net::HTTP::Post.new(endpoint_uri.request_uri, request_header) data = { api_key: "abcd1234", name: "test", email: "example@foo.com" } request.body = URI.encode_www_form(data) # リクエストの送信・レスポンスの取得 response = https.request(request)参考
- Ruby 2.7.0 リファレンスマニュアル library net/http
- 一番分かりやすい OAuth の説明
- net/httpsでWebAPIにPOSTリクエストを投げる
- そのリクエストパラメータ、クエリストリングに入れますか、それともボディに入れますか
利用するWeb APIの仕様やサンプルコードがあればそれもちゃんと読みましょう。
net/http以外のRubyでHTTPを扱うライブラリ
faraday
oauth2
- 投稿日:2020-05-18T12:12:18+09:00
SCSS記法チートシート
この内容について
この内容は、私が運営しているサイトに、より見やすく掲載しているので、よければそちらもご活用ください。
【Sass】SCSS記法チートシートSCSS記法とは
SCSS記法とはSassの書き方の1つで、SassにはSCSS記法とSASS記法があり、SCSS記法の方がCSSと互換性があるので使われることが多い。
拡張子は「.scss」にする。Sassとは
「Syntactically Awesome StyleSheet」の略で、CSSを効率的に記述できるように設計・開発されたRuby製のCSSメタ言語のこと
基本的な書き方
SCSSdiv{ p{ color: red; } }ネスト構造系
ネスト構造
入れ子構造(HTMLのような形)に記述
See the Pen
Sass_scss_nest by engineerhikaru (@engineerhikaru)
on CodePen.
親セレクタ参照
親セレクタの名称を参照し記述
See the Pen
Sass_scss_parent-reference by engineerhikaru (@engineerhikaru)
on CodePen.
ネームスペースネスト
CSSでネームスペースで記述しているもの(font-familyなど)をネスト構造で記述
See the Pen
Sass_scss_namespace-nest by engineerhikaru (@engineerhikaru)
on CodePen.
変数系
変数
よく使う値を変数でまとめる
See the Pen
Sass_scss_variable by engineerhikaru (@engineerhikaru)
on CodePen.
配列変数
よく使う値を配列変数でまとめる
See the Pen
Sass_scss_array-variable by engineerhikaru (@engineerhikaru)
on CodePen.
グループ変数
よく使うスタイルをまとめる
See the Pen
Sass_scss_group-variable by engineerhikaru (@engineerhikaru)
on CodePen.
継承系
インポート
分割したSCSSファイルをインポートする
SCSS// basic.scssというSCSSファイルを読み込む場合 @import "basic";継承
他の場所で使用したスタイルを継承する
See the Pen
Sass_scss_extend by engineerhikaru (@engineerhikaru)
on CodePen.
文法
条件分岐
条件によってスタイルを変更する
See the Pen
Sass_scss_if-else by engineerhikaru (@engineerhikaru)
on CodePen.
繰り返し
スタイルを繰り返す
See the Pen
Sass_scss_for by engineerhikaru (@engineerhikaru)
on CodePen.
繰り返し(配列変数)
配列変数を使用した繰り返し
See the Pen
Sass_scss_foreach by engineerhikaru (@engineerhikaru)
on CodePen.
演算・色
四則演算
スタイルの中で演算
See the Pen
Sass_scss_calculation by engineerhikaru (@engineerhikaru)
on CodePen.
文字列結合
スタイルの中で文字列結合
See the Pen
Sass_scss_concatenation by engineerhikaru (@engineerhikaru)
on CodePen.
明度の調整
ベースの色の明度を調整
See the Pen
Sass_scss_brightness by engineerhikaru (@engineerhikaru)
on CodePen.
彩度の調整
ベースの色の彩度を調整
See the Pen
vYNVVjr by engineerhikaru (@engineerhikaru)
on CodePen.
透明度の調整
ベースの色の透明度を調整
See the Pen
Sass_scss_transparency by engineerhikaru (@engineerhikaru)
on CodePen.
色相の調整
ベースの色の色相を調整
See the Pen
Sass_scss_hue by engineerhikaru (@engineerhikaru)
on CodePen.
色の補色&反転
ベースの色の補色or反転にする
See the Pen
Sass_scss_inversion by engineerhikaru (@engineerhikaru)
on CodePen.
色を混ぜる
ベースの色(2つ)を混ぜる
See the Pen
Sass_scss_color-mix by engineerhikaru (@engineerhikaru)
on CodePen.
その他
コメントアウト
SCSS// 1行コメント /* 複数行コメント(コンパイル後も残る) */引用符の付け外し
文字列の引用符("")の付け外し
See the Pen
Sass_scss_quote by engineerhikaru (@engineerhikaru)
on CodePen.
大文字&小文字化
文字列の大文字or小文字化
See the Pen
Sass_scss_upper-case by engineerhikaru (@engineerhikaru)
on CodePen.
絶対値を返す
数値の絶対値を返す
See the Pen
Sass_scss_abs by engineerhikaru (@engineerhikaru)
on CodePen.
切り上げを返す
数値の切り上げを返す
See the Pen
Sass_scss_ceil by engineerhikaru (@engineerhikaru)
on CodePen.
切り捨てを返す
数値の切り捨てを返す
See the Pen
Sass_scss_floor by engineerhikaru (@engineerhikaru)
on CodePen.
四捨五入を返す
数値の四捨五入を返す
See the Pen
Sass_scss_round by engineerhikaru (@engineerhikaru)
on CodePen.
この内容について
この内容は、私が運営しているサイトに、より見やすく掲載しているので、よければそちらもご活用ください。
【Sass】SCSS記法チートシート
- 投稿日:2020-05-18T11:57:03+09:00
Rubyでhash[:a][:b][:c] = 0 したら、キーが存在しなくても再帰的に拡張して欲しい
TL;DR
unixの
mkdir -p
みたいなことをRubyのハッシュでもやりたいhash = Hash.new {|h,k| h[k] = h.class.new(&h.default_proc) }hash[:a][:b][:c] = 'Good!!' p hash # {:a=>{:b=>{:c=>"Good!!"}}}解説
Hash.newについて
Hash.new
は、ハッシュ自身とキーを受け取り、キーの内容が存在しない場合のデフォルト値をブロックで定義することができます。hash1 = Hash.new { |h, k| 0 } hash1[:a] = 100 p hash1[:a] # 100 p hash1[:b] # 0上記は単純に、キーが見つからなかった場合は0を戻すハッシュを定義しています。
:a
は設定されているのでハッシュの内容を参照し、:b
は存在しないのでブロックが実行され0が戻るという状態です。ハッシュにデフォルト値を設定する
キーが見つからなかった場合のみブロックが実行されるという特性を利用すると、以下のようにハッシュ自体にデフォルト値を適用することができます。
hash2 = Hash.new { |h, k| h[k] = 0 } hash2[:a] += 100 hash2[:b] += 200 p hash2 # {:a=>100, :b=>200}以下は
:a
:b
ともに未定義の状態から、+=
を使って加算処理を行っていますが、hash2[:a]
hash2[:b]
を評価した時点でデフォルト値の0がハッシュ自体に設定されるため、見事に100と200が設定された状態になります。ハッシュをデフォルト値で拡張させる
さらに応用して、キーがネストしている状態でもハッシュを掘れるようにします。
hash3 = Hash.new { |h,k| h[k] = {} } hash3[:a][:b] = 100 p hash3 # {:a=>{:b=>100}
hash3[:a]
を参照した時点でブロックが実行され、hash3[:a] = {}
が適用されたあとのハッシュが返ってきます。これに対して[:b] = 100
が実行されるので、最終的にネストされた状態のハッシュができあがります。しかしこのままだと、ネストが3重になると失敗してしまいます。
hash3 = Hash.new { |h,k| h[k] = {} } hash3[:a][:b][:c] = 100 # undefined method `[]=' for nil:NilClass (NoMethodError)というのも、
hash3[:a]
によってデフォルト値が設定されていますが、これはただの{}
であり、これ自体にはデフォルト値の設定が定義されていません。そのため、
hash3[:a][:b]
はデフォルト値のないただのハッシュなので、hash3[:a][:b][:c]
を参照しようとするとエラーが発生してしまうわけです。ハッシュをデフォルト値で
再帰的に
拡張させる前項の
hash3[:a][:b]
はデフォルト値を持たない通常のハッシュになってしまいましたが、これにも同様のデフォルト値が設定されていてほしいものです。安直に書くと以下になります。
hash4 = Hash.new { |h,k| h[k] = Hash.new { |h,k| h[k] = {} } } hash4[:a][:b][:c] = 100 p hash4 # {:a=>{:b=>{:c=>100}}}三重ネストでも対応することが出来ました。しかし当然四重ネストには対応できません。地獄です。
hash4 = Hash.new { |h,k| h[k] = Hash.new { |h,k| h[k] = {} } } hash4[:a][:b][:c][:d] = 100 # undefined method `[]=' for nil:NilClass (NoMethodError)ネストがどれだけ深かろうと、再帰的にしっかりとデフォルト値を定義したハッシュをデフォルト値にしたいわけです。
そこで使えるのが Hash#default_proc です。
default_proc
はハッシュに設定されたデフォルト値定義のブロックをproc
オブジェクトで取得できます。
proc
はcall
メソッドで実行できるので、以下を見るとイメージが湧くと思います。hash5 = Hash.new { |k, v| 'default value'} p hash5.default_proc.call(nil, nil) # "default value"そしてブロックは、
&proc
の形で渡すことができるので、以下のように書くことができます。hash6 = Hash.new { |h, k| h[k] = Hash.new(&h.default_proc) } hash6[:a][:b][:c][:d] = 100 p hash6 # hash6[:a][:b][:c][:d] = 100腹落ちしましたでしょうか?
hash6
は自分自身のデフォルト値の定義
を適用したHash
を、自分自身のデフォルト値
にしています。
これによって、ネストが何重になろうと、常にデフォルト値の定義が引き継がれるわけでした。備考
書ききってから気づいたけど、同じような話を解説付きでしてる記事がチラホラあった。
まぁ自分の学んだ内容を整理するって意味で投稿しておきます。
- 投稿日:2020-05-18T11:37:28+09:00
【httpclient】でのリクエストからcontrollerまでの流れについて確認とリファクタリング
はじめに
以前、JQueryのautocomplete、ajax、そしてhttpclientを使いオートコンプリートを実装したが、内容についてぼんやりとしか把握できていなかった。リファクタリングを行いつつ、内容を確認していく。
まず、外部APIにアクセスしている部分は、クラスに切り出し、libディレクトリに入れる。
lib/api_suggest.rbrequire 'httpclient' require 'json' class ApiSuggest API_KEY = Rails.application.credentials.api[:API_KEY] API_URI = Rails.application.credentials.api[:API_URI] def self.suggest(keyword, max_num) uri = API_URI headers = { Authorization: "Bearer #{API_KEY}", } params = { keyword: keyword, max_num: max_num, } client = HTTPClient.new req = client.get(uri, body: params, header: headers) req end endリファクタリング前は、
client = HTTPClient.new req = client.get(uri, body: params, header: headers) res = JSON.parse(req.body) resと、
JSON.parse(req.body)
を行っていたが、
リファクタリング後は、req = client.get(uri, body: params, header: headers)client.getした結果をである
req
部分をそのままコントローラーに返し、コントローラー側では、
app/controllers/suggests_controller.rbrequire 'api_suggest' class SuggestsController < ApplicationController SUGGEST_MAX_COUNT = 5 def search @suggests = ApiSuggest.suggest(params[:keyword], SUGGEST_MAX_COUNT) render body: @suggests.body, status: @suggests.code end end7行目の、renderで、
render body: @suggests.body, status: @suggests.code各パラメータに入れる事で
JSON.parse
する必要がなくなった。そして、そのパラメータが、
app/assets/javascripts/suggest.js$("#form").autocomplete ({ source: function (req, res) { $.ajax({ url: '/suggest', type: 'GET', cache: false, dataType: "json", data: { keyword: req.term }, n success: function (data) { res(data); }, error: function (xhr, ts, err) { n res(xhr, ts, err); } }); } });ajaxのsuccess以下に返されるという流れになっている。
全体の流れを確認
ajaxのオプションで指定している
url: '/suggest'
にリクエストが送られ、
ルーティングでget 'suggest', to: 'suggests#search'
app/controllers/suggests_controller.rb
のsearchメソッドが呼ばれ、def search @suggests = ApiSuggest.suggest(params[:keyword], SUGGEST_MAX_NUM) render body: @suggests.body, status: @suggests.code end
ApiSuggest.suggest
によりhttpclientでの外部APIリクエストを介した結果、
render body: @suggests.body, status: @suggests.code
が返されて、
app/assets/javascripts/suggest.js
のajaxsuccess: function (res) { resp(res); }, error: function (xhr, ts, err) { resp(xhr, ts, err); }成功、失敗それぞれのケースに返される。
という流れ。ajax部分について詳しく
render bodyのオプションが、戻り値の本体を返していて、
statusがステータスコード(200, 404, 500など)の外部APIの結果が返される。ajax側でそれを受け取ると、
ajaxの中では、そのstatus codeを参照して、200系、300系を正常として判定して、success側を実行。それ以外のstatus codeがきたらerror側を実行、
という処理を行っている。以上。
終わりに。
最後まで読んで頂きありがとうございます
転職の為、未経験の状態からRailsを学習しております。正しい知識を着実に身に着け、実力のあるエンジニアになりたいと考えています。継続して投稿していく中で、その為のインプットも必然的に増え、成長に繋がるかと考えています。
今現在、初心者だからといって言い訳はできないですが、投稿の内容に間違っているところや、付け加えるべきところが多々あるかと思いますので、ご指摘頂けると幸いです。この記事を読んで下さりありがとうございました。
- 投稿日:2020-05-18T10:42:12+09:00
Ruby 正規表現
正規表現とは
・文字列の一部分を置換
・文字列の一部分を抽出
・文字列が制約を満たしているか調べるなどの操作を行うための技術が正規表現です。
正規表現のほとんどの記述はどの言語間でも共有可能です。
メソッドと使用例
subメソッド
文字列の指定した部分を別の文字列に置き換える
irb(main):001:0> str = "リンゴを食べる" => "リンゴを食べる" irb(main):002:0> str.sub(/リンゴ/,"オレンジ") => "オレンジを食べる"変数strに文字列 "リンゴを食べる" が代入されています。
次にstrに対し、subメソッドを使用し、第一引数にリンゴ、第二引数にオレンジを指定しています。
出力すると、リンゴを食べる → オレンジを食べるになっています。
このように第一引数に置き換えたい文字列を「 / (スラッシュ)」囲み、第2引数に変換後の文字列を指定します。
matchメソッド
文字列がメソッドの左の文字列に含まれているか否かをチェックする
irb(main):001:0> str = "Hello, World" => "Hello, World" irb(main):002:0> str.match(/Hello/) => #<MatchData "Hello"> irb(main):003:0> str.match(/Good/) => nil変数strに文字列 "Hello, World" が代入されています
次にstrに対し、matchメソッドを使用し、引数にHelloを指定しています
"Hello, world" には指定した "Hello" という文字列は含まれているので、MatchDataオブジェクトの返り値として指定した文字列 "Hello" が得られます。
"Good" は含まれていないので、返り値はnilになります。
matchメソッドもsubメソッドと同じように引数を「 / (スラッシュ)」で囲みます。
gsubメソッド
文字列の指定した部分を全て別の文字列に置き換える
irb(main):001:0> tel = '080-1234-5678' => "080-1234-5678" irb(main):002:0> tel.sub(/-/,'') => "0801234-5678" irb(main):003:0> tel.gsub(/-/,'') => "08012345678"変数telには電話番号が代入されています。
次にsubメソッドでハイフンを空の文字列に置き換えることで取り除こうとしますが、最初のハイフンだけが置き換えられています。
指定した初めの文字列だけを置き換えるならsub,全て置き換えるならgsubを使います。
正規表現のメタ文字
メタ文字は、特殊な意味・機能を持った文字で、これを使用することで様々な制約が可能になります。
種類が多いので、パスワードの制約を例に挙げる中でいくつか紹介します。
irb(main):001:0> pw = 'Abcd1234' => "Abcd1234" irb(main):002:0> pw.match(/[a-z\d]{8,10}/i) => #<MatchData "Abcd1234">上記は、
・aからzの英字、数字のいずれかの文字
・8文字以上10文字以内
・文字は大小どちらでも可という制約をかけています。
引数の中身を分解し、それぞれの文字の意味を説明していきます
/[a-z\d]{8,10}/i
↓
/[a-z\d]{8,10}/ i(スッラッシュの中身の文字列は大文字小文字どちらでも可)
↓
[a-z\d] {8,10}(直前の文字が8から10文字出現するものにマッチ)
↓
[a-z] \d (数字にマッチ)
↓
[a-z] (aからzまでの文字いずれかにマッチ)
※今回はa-zに加え、数字も角括弧に囲まれているため、英数字いずれかにマッチする)
まとめ
種類 意味 [ ] 囲まれたいずれか1つの文字にマッチ \d 数字にマッチ {a,b} 直前の文字がa回以上b回以下出現するものにマッチ i (オプション) 大文字・小文字を区別しない 基本的に紹介した2つのメソッドと正規表現のパターンを組み合わせることで様々な制約が実装できます。
パターンに関してはここに記したのは一例です。他にも正規表現を用いてできることはたくさんあります。
- 投稿日:2020-05-18T10:36:54+09:00
FontAwesomeの導入と使い方解説
今回はFontAwesomeの導入方法から表示させるまでについてを解説していきます。
FontAwesomeの導入
1.Gemfileに以下の記述を追記
gem "font-awesome-sass"$ bundle install2.application.scssに以下を記述。
@import "font-awesome-sprockets"; @import "font-awesome";これで導入は完了です。
ビューで表示
iconヘルパーメソッドを使っていきます。
使い方の模範はこんな感じです。icon('接頭辞名', 'アイコン名')実際に使うとこんな感じです。
= icon('fab', 'facebook-square') #例参考資料
接頭辞名とアイコン名については以下のサイトで調べて使いましょう!
https://fontawesome.com/
- 投稿日:2020-05-18T02:30:59+09:00
備忘録 Ruby 『p』と『puts』の違い
2020/05/17
Atcoderで競技プログラミングをしていたときに、
やらかしてしまったミスを備忘録として残しておく。Atcoder168_B
出力に以下が表示されればOK
$ ruby Bmain.rb 4 #入力 aaaaa #入力 aaaa... #出力以下のようなコードを書いた。
K = gets.to_i S = gets.chomp if S.length <= K then p S elsif S.length > K then p S[0..(K-1)]+"..." end出力
出力に""が表示されてしまっているためエラーとなる。$ ruby Bmain.rb 4 #入力 aaaaa #入力 "aaaa..." #出力pをputsに変更
K = gets.to_i S = gets.chomp if S.length <= K then puts S elsif S.length > K then puts S[0..(K-1)]+"..." end次は、""なしで表示された。
$ ruby Bmain.rb 4 #入力 aaaaa #入力 aaaa... #出力pはデバッグ用途で使用するためのものなのでわかりやすいように""をつけるとのこと。
- 投稿日:2020-05-18T02:05:29+09:00
Rubyの基礎2~わかりにくいところ復習~
メソッド
メソッドは使えるオブジェクトが決まっている。
eachメソッドの場合は配列オブジェクトや範囲オブジェクトにしか使えません。
また、eachメソッドを配列オブジェクトに使った場合の返り値は配列オブジェクトそのものです。クラス
クラスとは、とあるオブジェクトの共通の属性とメソッドをまとめておく型のようなもの。
"Hello"と"こんにちは"はそれぞれ別のオブジェクトですが、文字を持つと言う点においては共通です。
この性質は予めクラスの性質として定義されているものなのです。
この型を予め用意しておけば、その肩に沿って効率的にオブジェクトを生成できます。インスタンス
クラスから生まれたオブジェクトのことをインスタンスと言います。
オブジェクトから先に生まれることはなく、クラスからインスタンスというオブジェクトが生まれます。
属性と属性値とメソッドが入った状態でインスタンスが生成されます。
つまり、クラスで属性が定義されていて、具体的な属性値を持った状態でインスタンスが生成されます。例えば文字列オブジェクトの "Hello" は Stringクラスで定義された属性=文字に、属性値="Hello"が入った状態、かつlengthメソッドやto_iメソッドなどのメソッドを持った状態でインスタンスが生成されます。
Rubyに予め定義されているクラス
Rubyには予め定義されたクラスがある。
文字列オブジェクトのStringクラス
配列オブジェクトのArrayクラス
数値オブジェクトのIntegerクラス
ハッシュオブジェクトのHashクラスnewメソッド
newメソッドは全てのクラスで定義しなくても使うことができます。
newメソッドを使うことによってインスタンスを生成できます。
返り値として利用したクラスのインスタンスを返します。
クラスメソッドである。なぜならインスタンスを生成するのはクラスが行うべきだから。クラスメソッド
クラスメソッドはクラスメソッドを定義したクラス自身が利用できるものでクラスで共通の情報を使った処理に使います。
メソッド名の前にself
をつけます。インスタンスメソッド
インスタンスメソッドは、インスタンスが利用できるメソッドです。インスタンスメソッドを定義したクラスのインスタンスに使用できる。インスタンスごとの個別の情報を使った処理に使えます。
クラスメソッドとインスタンスメソッドの違い
特徴 インスタンスメソッド クラスメソッド 定義方法 メソッド名の前に selfを付けない メソッド名の前にselfを付ける 用途 インスタンスごとの属性を用いるとき 属性が関係のない共通の処理をするとき 呼び出せるオブジェクト クラスのインスタンス クラス自身 呼び出し方 インスタンス名.メソッド名(引数) クラス名.メソッド名(引数) クラスの変数
クラスでは共通の属性は変数を使って定義します。
その変数に代入した値が属性値です。
クラスに定義できる変数は、クラス変数とインスタンス変数があります。クラス変数
クラス変数はクラス全体で使用できる変数です。つまり、クラスメソッド内でもインスタンスメソッド内でも使用することができます。クラスを通して値が共通の情報に使用する変数。
インスタンス変数
インスタンス変数は、共通の属性としてインスタンスに定義できる変数です。
値はそれぞれのインスタンスごとに設定できます。
各インスタンスでのみ使用ができます。
定義場所はインスタンスメソッド内で行います。
インスタンスメソッド内で定義されたインスタンス変数の値は、そのインスタンスメソッドを利用したインスタンスが持つインスタンス変数の値になる。initializeメソッド
initializeメソッドはインスタンスを生成したと同時に実行したい処理を自動で実行できます。
クラスの継承
あるクラスに定義されたメソッドを別のクラスで利用できるようにすることを継承と言います。
継承したいクラスのことを親クラスといい継承する側のクラスのことを子クラスと言います
class 子クラス名 < 親クラス名 で親クラスを継承できます。pメソッド
pメソッドはpの右側に書かれたオブジェクトやインスタンスを出力するものです。putsメソッドと似ていますがputsメソッドが返り値nilを返すのに対しpメソッドはそのオブジェクトやインスタンス自体を返り値として返します。
for文
while文と同じ繰り返しを行う文法です。
for num in 1..10 do puts num end 変数numに1〜10を代入して出力しています。 inの後ろにあるオブジェクト順番に変数numに代入しています。 1..10は1~10という意味です。
- 投稿日:2020-05-18T00:52:21+09:00
Ruby と Python で解く AtCoder ABC168 A case式
はじめに
AtCoder Problems の Recommendation を利用して、過去の問題を解いています。
AtCoder さん、AtCoder Problems さん、ありがとうございます。今回のお題
AtCoder Beginner Contest A - ∴ (Therefore)
Difficulty: 2今回のテーマ、case式
Ruby
本戦では、
if
式で解いていますが、editorial に余談ですが,Ruby では case 文がこれにあたり,もっと高機能です.と書かれていますので、
case
で書いてみたいと思います。これまでにcase
を書いたことはないです
まずは、if
ruby.rbn = gets.to_i n %= 10 if n == 3 puts "bon" elsif n == 0 || n == 1 || n == 6 || n == 8 puts "pon" else puts "hon" endlast.rbn %= 1010で割った余りで1の位を取得していますが、
gets.chomp
として文字列としn[-1]
とすることもできます。case.rbn = gets.chomp case n[-1] when "3" then puts "bon" when "0", "1", "6", "8" then puts "pon" else puts "hon" endeditorial の解説にある 高機能 とは
,
を用いて複数条件を指定することができるという意味です。Python
python.pyn = int(input()) % 10 if n == 3: print("bon") elif n in {0, 1, 6, 8}: print("pon") else: print("hon")pythonは
case
が無いようなので、似た感じにしてみました。
python のin
は SQL のin
に似ていますね。まとめ
- ABC 168 A を解いた
- Ruby に詳しくなった
- Python に詳しくなった
参照したサイト
Python に switch や case 文がないのはなぜですか?
pythonにswitchはないけれど