- 投稿日:2021-01-01T23:58:46+09:00
記事の並べ方(昇順・降順)について
自己紹介
こんにちは!
今回初めて投稿をします。
同じことで何度も悩んでしまわない為の、自分用のメモとして、またアウトプットする事によって記憶の定着に繋がればと思い始めました。それでも、もしかするとどなたかに拝見していただける機会があるかもしれませんので、少しだけ自己紹介をさせていただきます。
2020年10月中旬より本格的にプログラミングの勉強をスタートさせ、現在はプログラミングスクールも活用し、未経験の中途という形でエンジニア転職を目指している者です。さて今回の本題に!
投稿された記事をIDの若い順に並べてください。
この言葉にまず「若い順」ってどういう意味だろうと疑問に感じました。
結果から言うと、答えはそのままの意味で1.2.3.4....となるような数字の小さい順という事でした。
この若い順が一般的な昇順(asc)、その反対が降順(desc)になります。今回のIDの話で例えると、
・昇順:IDが小さい順。古い記事が上にくる。
・降順:IDが大きい順。新しい記事が先頭にくる。今回は、コントローラに記述する方法を使用したので残しておく事にします。
1.昇順、降順どちらも指定しない場合。
デフォルト値は降順になります。
2.昇順、降順指定をする場合。
掲載画像のコメントにも載せましたが、orderを記述する場合は手前のallは省略可能。
何かを投稿するようなSNSなどには必ず必要な表記になりそうですね。
忘れないようにここに記して、今回の投稿は以上で終了とさせていただきます。
- 投稿日:2021-01-01T22:36:05+09:00
【Rails】slick(スライダー機能)を簡単に導入する方法
はじめに
簡単
?に実装できると思います。
slick
とは画像等をスライドショーのように表示させる機能を付けられるjQueryプラグインです。本記事は導入方法と簡単な実装のみを紹介します。
「サイトをおしゃれに仕上げたいから、もっと発展的なことを教えてくれ!」という方。
ごめんなさい。
haml
やslim
ではなく普通のhtml
で記述していますので、初学者の人にとっても分かりやすいはず。。
haml.slimで書かれてる記事多すぎだぜ(つらい)また私が最初に導入してエラーを吐いたところも解決方法とともに紹介していきます。
誰かが躓くところは皆転ぶ!こんな人に向けて
1.haml.slimがよくわからない初学者
2.rails に slickを導入したいけど方法が分からない人
3.他の記事を見ながら実装し、エラーを吐かれて詰んだ人 (この記事で詰まったらごめんなさい)今回はrails 5.2.4を使っています。
またOSはWindowsですが、macでも同じだと思います。(見た目は少し違うかも。。。)1.導入準備
1.rails newコマンドでアプリケーションを既に作成していること
2.rails sでサーバーを起動したとき、ページが表示されるようになっていること(ルート・コントローラ・ビューが正しく記載されている)上記の2点を前提として続けていきます。
まず
slick
はjQueryを使っていますので、Gemfilegem "jquery-rails"を記述し、インストールします。
ターミナルbundle installインストールしたら別の場所にも以下を記述します。
app/assets/javascripts/application.js下2行を追加(←日本語の文字はいらないです) //= require jquery //= require jquery_ujs //= require rails-ujs //= require activestorage //= require_tree .以下の文は一応消しておきます。
//= require turbolinks
これで準備は完了です。
さっそく導入していきます。2.slickを導入する
1.公式からファイルをダウンロード
2.自分のアプリケーションの特定のフォルダにファイルを入れる
3.htmlに特定の記述をする
4.scssに特定の記述をする
の3段階で導入できるので分けて説明します。2-1.公式からダウンロード
slickからファイルをダウンロードします。
このボタンでダウンロードを開始します。(下の方にスクロールすると上記のような画面があります)2-2.特定のフォルダに入れる
slick-1.8.1.zip
というフォルダがダウンロードされます。そこから slick-1.8.1 → slick と進んでいくとファイルがいくつかあります。
その中から
・slick.min.js
・slick.scss
・slick-theme.scss
の3つを使います。(最低限必要なものだけを)
ファイル 格納場所 slick.min.js app/assets/javascripts/ slick.scss app/assets/stylesheets/ slick-theme.scss app/assets/stylesheets/ 上記の場所に入れてください。
2-3.htmlに記述をする
htmlに記述します。
app/views/layouts/application.html.erb<head> <title>Title</title> <%= csrf_meta_tags %> <%= csp_meta_tag %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <!--この下2行を追加--> <link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick.css"/> <link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick-theme.css"/> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> </head>2-4.scssに記述をする
scssをインポートするために、以下の記述をします。
app/assets/stylesheets/application.scss*= require_tree . *= require_self */ *以下の2行を追加 @import "slick-theme"; @import "slick";これで導入はできました。
3.slickを使用する
導入はできたのでこれから実際に使ってみます。
今回は基本的な以下の機能を実装します。(アレンジする場合は他の人の記事を見てくださいね)
・下にドットを表示する
・ドットを押せば写真がスライドする
・画像をフリックするとスライドするhtml.erb<div class="hoge"> <div class="nest-hoge">aaa</div> <div class="nest-hoge">bbb</div> <div class="nest-hoge">ccc</div> </div>
hoge
やnest-hoge
の部分は何でもいいです。(cssの命名規則は分からない。。)app/assets/javascripts/application.js$(function() { $('.hoge').slick({ dots: true, }); });親クラスを指定してあげれば動きます。
これで実装できました。
(簡単なのか?)4.エラー集(私のミスを含む)
最後に私が初めてslickを導入したときに起きたエラーを紹介します。
笑える人は笑ってください。4-1.bundle install 忘れ
動かない
gemを追加しているので、bundle installをしましょう。
4-2.ファイル格納場所間違え
正しい位置に入れましょう。
間違ってもjsのファイルをstylesheets下に入れないように
4-3.htmlに未記述
ファイルをダウンロードしているし、記述はいらないと思ってました。
デベロッパーモードでエラーがこんにちは
記述は必要みたいです。4-4.application.jsで注意マークが
18行目に注目。
/*global $*/
を追加すればOKみたいです。
さいごに
以上で終わりです。
スライダープラグインはslickだけでなくswiperなどいろいろなものがあります。
まとめサイトもありますので参考にしてみてください。ではでは。
- 投稿日:2021-01-01T22:29:45+09:00
【Rails奮闘記/Railsチュートリアル編】Railsチュートリアル3章で学んだこと
はじめに
Railsチュートリアル3章を終えました。
実務に入った上で、ルーティング・コントローラー・ビュー周りとテストを学習しました。
学習した中で、実務に使える内容をまとめました。コントローラー生成のコマンド
コントローラーを生成するときのコマンドは以下のようになります。
$ rails g controller (コントローラー名) (アクション名)generateスクリプトではアクション名をまとめて指定することができる。
Railsチュートリアルでは、アクション名がhome、help、aboutに当たる。もし、例えばコントローラー名のスペルを間違えた時など、コントローラーをコマンドですでに生成してまったら普通だったら1つ1つのファイルを削除することを考えるかと思います。
では、どうすれば良いか?
そんなときに便利なコマンドが以下のコマンドで、生成したコントローラーのファイルを一挙に削除することができます。$ rails destroy controller (コントローラー名) (アクション名)これだけで生成したコントローラーのファイルを削除して元に戻すことができます。
モデルの生成のコマンド
コントローラー生成と同じ要領で、モデル生成するときは以下のコマンドを叩きます。
$ rails g model (モデル名) (カラム名: データ型)すでに生成してしまったモデルを生成する前に戻したいときは、以下のコマンドを叩きます。
$ rails destroy model (モデル名)モデルを削除したいときはモデル名のあとの引数は不要です。
テスト
Railsチュートリアルでは、コントローラーのテスト(3章)、モデルのテスト(6章)、統合テスト(7章)の3つ。
テストは以下の順番で行う。
1.失敗するテストを最初に書く
2.アプリケーションのコードを書いて成功させる(テストをパスさせる)
3.必要ならリファクタリングを行う
これがテスト駆動サイクルと呼ばれるものになる。minitest reporters
minitest-reportersはgemの1つであり、これを使えるようにすることで、テスト成功と失敗が見やすくなります。
RailsのテストはRSpecが主流ですが、Railsチュートリアルではミニテストで最後までやっていこうと思います。Guard
Guardの設定を終えたら、以下のコマンドを叩きます。
$ bundle exec guardコマンドを実行することで、コントローラーのファイルを変更すると、そのコントローラーのテストを自動で実行してくれます。
コマンドを終了したいときは、Ctrl + Dで終了することができます。
テスト自動化は本当に便利なので、初期設定を早めに終わらせておいたほうが開発に専念できそうだなとQiitaで書いていて思いました。終わりに
以上がRailsチュートリアル3章のまとめになります。
自分の中で実務に活かせそうなことをQiitaにまとめした。
こんな感じで各章を終えたら、どこが実務で生きるかをまとめていこうと思います。
- 投稿日:2021-01-01T22:27:58+09:00
Simple Calendar gemの導入・基本的な使い方
RailsのgemであるSimple Calendarを使ったアプリ開発を行っているので、後学のために、Simple Calendarの導入と基本的な使い方を説明します。
内容的にはsimple_calendarの公式GitHubの日本語訳になります。
Simple Calendarとは
カレンダー表示機能を簡単に実装できるようにしてくれるgemです。
実行環境
- Ruby 2.6.5
- Rails 6.0.3.4
Simple Calenderのインストール
Gemfile
に以下のように記述し、ターミナルでbundle install
を入力します。Gemfilegem "simple_calendar", "~> 2.0"ターミナルbundle install
application.css
ファイルにデフォルトのスタイルシートを読み込みます。app/assets/stylesheets/application.css*= require simple_calendarもしくは
application.scss
ファイルに下記の記述をします。app/assets/stylesheets/application.scss@import "simple_calendar";メソッドを使ってビューファイルにカレンダーを生成
Simple Calendarのメソッドを使ってビューファイルにカレンダーを生成する方法を説明します。
month_calendarメソッド
month_calendar
メソッドを使えば月間カレンダーを生成できます。month.html.erb<%= month_calendar do |date| %> <%= date %> <% end %>week_calendarメソッド
week_calendar
メソッドを使えば週間カレンダーが生成できます。
オプションのnumber_of_weeks
で何週分表示するかを設定できます。number_of_weeks
を記述しない場合は、デフォルトで1週分表示します。week.html.erb<%= week_calendar(number_of_weeks: 2) do |date| %> <%= date %> <% end %>calendarメソッド(表示日数をカスタムする)
calendar
メソッドを使えばカレンダーの表示日数をカスタムすることができます。
オプションのnumber_of_days
で何日分表示するかを設定できます。number_of_days
を記述しない場合は、デフォルトで4日分表示します。custom.html.erb<%= calendar(number_of_days: 4) do |date| %> <%= date %> <% end %>Simple Calendarの導入から基本的な使い方まではここまでとなります。
Simple Calendarの見た目を自分で編集する
各カレンダーの見た目を編集したい場合は下記のコマンドを入力して、ビューファイルを自身のアプリにコピーします。
ターミナルrails g simple_calendar:views #以下の通りsimple_calendarフォルダと各ビューファイルが自身のアプリに生成されます create app/views/simple_calendar create app/views/simple_calendar/_calendar.html.erb create app/views/simple_calendar/_month_calendar.html.erb create app/views/simple_calendar/_week_calendar.html.erb参考資料
- 投稿日:2021-01-01T21:26:05+09:00
【Ruby】10の位と1の位を取得する方法
概要
二桁の整数から10の位と1の位を取得して、計算結果を出力するまでを書いていきます。
目次
実践
- 問題
- 解答(解説)
- 別解(digitsメソッド)
- 別解(divmodメソッド)
まとめ
参考文献
実践
問題
二桁の整数から10の位と1の位の数字の足し算と掛け算の結果を足し合わせて出力するプログラムを書いてください
解答(解説)
解答def addition(a, b) a + b end # 10の位と1の位の掛け算 def multiplication(a, b) a * b end def check_num(num) tens_place = (num / 10) % 10 # 10の位を10で割ることで1桁にしてから余りを計算している ones_place = num % 10 # 10で割ったときの余りが1の位になる addition_result = addition(tens_place, ones_place) # additionメソッドで足し算 multiplication_result = multiplication(tens_place, ones_place) # multiplicationメソッドで掛け算 p "足し算の結果と掛け算の結果の合計は#{ addition_result + multiplication_result }です。" end # ターミナルで入力する p '二桁の整数を入力してください' num = gets.to_i # メソッド呼び出し check_num(num)別解(digitsメソッド)
書き換えた箇所は10の位と1の位を計算しているところです。
digits.take
の引数に2
を指定しているのは1の位と10の位の2つの値を取得しているからです。注意点としてはdigits.take
で取得する際1の位
から順番に取得する点です。digitsdef addition(a, b) a + b end def multiplication(a, b) a * b end def check_num(num) ones_place, tens_place = num.digits.take(2) # 1の位と10の位を取得 addition_result = addition(tens_place, ones_place) multiplication_result = multiplication(tens_place, ones_place) p "足し算の結果と掛け算の結果の合計は#{ addition_result + multiplication_result }です。" end p '二桁の整数を入力してください' num = gets.to_i check_num(num)別解(divmodメソッド)
書き換えた箇所は10の位と1の位を計算しているところです。
divmod
の引数(今回の場合は10
)に数値を指定することで割ったときの商と余り取得することができます。divmoddef addition(a, b) a + b end def multiplication(a, b) a * b end def check_num(num) tens_place, ones_place = num.divmod(10) # 1の位と10の位を取得 addition_result = addition(tens_place, ones_place) multiplication_result = multiplication(tens_place, ones_place) p "足し算の結果と掛け算の結果の合計は#{ addition_result + multiplication_result }です。" end p '二桁の整数を入力してください' num = gets.to_i check_num(num)まとめ
- 10の位は二桁の整数を10で割り、さらに10で割った余り
- 1の位は二桁の整数を10で割った余り
- digitsメソッドを使用することで1の位から順番に数値を取得することができる
参考文献
- 投稿日:2021-01-01T19:28:35+09:00
スクレイピングでアクセスブロックを回避するために注意すること
普段、クローラー開発をメインに仕事をしている。
業務上、データを収集するために様々なサイトにアクセスする機会があり、日々アクセスブロックと格闘している。
今回は自分の備忘録も兼ねて、スクレイピングでアクセスブロックに合わないための技術や対処法をまとめておく。
扱うスクレイピング技術はRubyのopen-uri、curlコマンド、selenium。
改めて言うまでもないが、クロール先サイトの規約や関連法律の遵守はしよう。アクセスブロックされたときにチェックする項目
アクセスブロックには様々な種類があり、適切な手段をもって回避する
IP
1:アクセス頻度
頻繁にサイト側にリスエストを送信すると、ロボット判定される可能性がある。
解決策:sleep時間を増やす。クロール回数*sleep=所要時間<許容所要時間に収まる範囲で、sleepは長く取る。2:同じペースでリスエストを送信すると、ロボット判定される可能性がある。
解決策:ランダムなsleep時間を設定する。3:同一IPから同一サイトにリクエストを頻繁に送信した場合、IP単位でブロックされる可能性がある。
解決策:1IPあたりの連続接続可能回数・秒数を調べて、必要ならSSHサーバーを踏み台にしてIPローテーションする。
別々のサイトであってもCDNがAkamai共通で、AkamaiにIPブロックされた場合はどちらのサイトもブロックされる可能性がある。# rubyのopen-uri socksify gem Socksify::proxy("127.0.0.1", port) { open(url).read }# curl curl -x socks5h://loalhost:port url# selenium selenium_option = [ --proxy-server=socks5://127.0.0.1:port ]4:特定のIPからのアクセスをブロックするサイトがある。
解決策:サーバーとしてデータセンター(IDCFやAWS)を使っている場合、SSHサーバーを踏み台にしてIPをプロバイダ等を変えてみる。HTTP Header
1:デフォルトHTTP Header
リクエストを受け取るサーバー側は、不自然なHTTP Headerのリクエストがきたら怪しいリクエストだと認識して必要に応じてブロックするなどの処理をする。open-uriやcurl等のデフォルトHTTP Headerは明らかにBOTだとわかる。
解決策:User-AgentやAccept-Language等をブラウザでアクセスしたときと同じものを指定する。
ブラウザでアクセスしたときのHeaderは、Chrome→Developer tool→Networkタブ→Copy→Copy as cURLからコピーして確認する。2:同一ユーザからのアクセス頻度
HTTP Header(やIP)から、同一ユーザーが過剰なアクセスをしているとサーバー側が判断した場合、ブロックされる可能性がある。
解決策:User-Agent等をローテーションしてみる。Captcha
BOTの動きを判別して、人間が簡単に解決できる問題を解かせるサイトがある。
解決策1:Captchaテストをトリガーしない。
sleepを長くする、IPを変える、seleniumを使っているならwebdriverプロパティを削除する、headlessのオプションを外す等、様々な条件を試す。解決策2:自動的にテストを解く。
Captha突破API、もしくは機械学習またはディープラーニングスキルを使用してこのチェックに合格する画像認識技術を使う。補足
webdriverプロパティを削除する
seleniumを使っている場合、次のコードで簡単に自動操作していることがわかってしまう。
var isAutomated = navigator.webdriver; if(isAutomated){ blockAccess(); }webdriverプロパティを削除するには次のコードを実行する。
delete Object.getPrototypeOf(navigator).webdriver;headlessのオプションを外す
seleniumを使っている場合、headlessで実行するとサイト側にブロックされることがある。
headlessは人間でない証であり、headlessかどうかは次のコードで簡単にわかるからだ。
ditsilやgeetest系のボット防止技術を使っているサイトだと、headlessでは無理で、サーバーで実行する場合はGUI付きが必要。navigator.permissions.query({name:'notifications'}).then(function(permissionStatus) { if(Notification.permission === 'denied' && permissionStatus.state === 'prompt') { console.log("Headless Chrome"); } else { console.log("Not Headless Chrome"); } });CDNがAkamaiか確認する
digコマンドで、ドメイン名からIPアドレスを調べる
dig ドメイン名
例:dig www.armaniexchange.com
CDNがAkamaiなら、Answerセクションにakamaiedgeの記載がある。IPアドレスからドメイン名を調べる
digコマンドで、IPアドレスから逆引きする
dig -x IPアドレスポートフォワーディングができているかを確認する
digコマンドで自分のグローバルIPアドレスを確認して、digコマンドの-xオプションでドメインを逆引きする。
Answerセクションのドメイン名でポートフォワーディングができているか判断する。
IDCF:idcfcloud.net.
AWS EC2:amazonaws.com.
フレッツ:mesh.ad.jp.SSHサーバーを踏み台として使う
SSHサーバーを踏み台にすれば、接続先のWebサーバーにSSHサーバーのIPアドレスから接続してきたと思わせることができる。SSHサーバーの「ダイナミックフォワード」という機能を使ってSSHサーバーまでの「トンネル」を作り、「SOCKSプロキシ」として利用する。
ssh -D ポート番号 ユーザー名@ホスト名ランダムにSOCKSプロキシのポートを取り出す
IPローテーションする際、複数のSOCKSプロキシを立ち上げて、ランダムにポートを取り出す必要がある。
dynamic_portsメソッドを実行すると、Linuxコマンドpgrep -fal ssh
でsshサーバーを抽出し、SOCKSプロキシのポートを配列で返すため、sampleメソッドでランダムに一つだけ取り出せば良い。dynamic_ports.rbdef dynamic_ports lines = `pgrep -fal ssh`.split("\n") ports = [] lines.each do |line| opts = line.split d_options_index = opts.find_index("-D") if d_options_index.present? && d_options_index > 0 next if opts[d_options_index + 1].to_i <= 0 ports << opts[d_options_index + 1].to_i end end ports endSOCKSプロキシの種類
ローカルでの名前解決
curl --socks5 localhost:port
サーバーでの名前解決
curl --socks5-hostname localhost:port
curl -x socks5h://localhost:post
chrome_option = [ --proxy-server="socks5://127.0.0.1:port" ]参考文献
10 Ways to hide your Bot Automation from Detection | How to make Selenium undetectable and stealth
どこへ行っても安心!SSHサーバーを踏み台にしてWebアクセスする方法さいごに
アクセスブロックはサイトによって様々であり、その対策も千差万別である。
スクレイピングできないサイトはない!と言える技術力を身に着けたい。
- 投稿日:2021-01-01T19:22:24+09:00
cloud9でインスタンスを作成し直したい場合
初めて記事を書きます。
これは自分用のメモですcloud9の設定をミスってしまった。
勢い余ってEC2のストレージ容量を無料枠以上にアゲてしまった。
その他よくわからなくなってまた最初から始めたい。
そのようばあいgithubにpushしていることが前提です。
そのpushをcloud9にcloneします。loud9に新しいインスタンスを作成します。
作成時の設定はrails チュートリアルに従いました。gitが入っているかを確認(私の環境では既に入っていました)します。
次に新しく作成したインスタンスに自分のgithubの情報を教えてあげます。
git config --global user.name USER_NAME
git config --global user.email EMAIL_ADDRESS
USER_NAME,EMAIL_ADDRESSには自分のユーザーネームとemailアドレスを代入します。私の場合は、
git config --global user.name irojiroserika
となります。
特にレスポンスがあるわけではありませんが、大丈夫です。もしここでユーザーネーム等間違えてしまった場合はもう一度入力しなおせば良いです。
次にcloneしたいcommitのURLを見つけます。
画像参照(緑色のところをクリックすると出てきます。)最後に
git clone そのURLで、clone自体は終了です。
ファイルを確認してください。しかし、ここから開発を始めようと思ってもrails serverが立ち上がりませんので、bundle installを実行します。
ここで注意点
私はrailsチュートリアルに乗っ取りGemfileを書き換えているため、開発用と本番用で使用するdbが異なります。この場合bundle install --without production
も実行しなければbundle install時に本番環境のgemがインストールできないというエラーが発生し、結果的にrails serverが立ち上がりません。
ので
bundle install
と
bundle install --without production
も実行します。あ、そうそう
yarnが入っていない場合もrails serverが立ち上がりませんので、yarnをインストールしてください。
このとき
Your Yarn packages are out of date!
Please run
yarn install --check-files
to update.というメッセージが返ってくると思いますが、そもそもyarnが入っていない場合は
yarn install --check-files
をそもそも実行できませんので、source <(curl -sL https://cdn.learnenough.com/yarn_install)
(cloud9環境)を実行してくださいね。
これでrails serverが立ち上がります。
これで本当に最後です。
rails db:migrateを実行すれば、cloneしてきたアプリがエラーなく見れるようになります。
自分用ですが、為になれば嬉しいです。
- 投稿日:2021-01-01T19:04:00+09:00
Ruby/Racc: パースに失敗した位置(行、桁)を得る
パースに失敗したとき、失敗した位置をたとえば次のように表示したいですよね?
parse error: line 2, col 5 foo bar ^
短いのでとりあえず全部貼ります。
# parser.y class Parser rule program: "a" "b" "c" "d" ";" { puts "program found" result = val } end ---- header TokenValue = Struct.new(:value, :pos) ---- inner def initialize(src, tokens) @src = src @tokens = tokens end def next_token @tokens.shift end def parse do_parse end def get_lineno_and_range(pos) lineno = 1 line_start = 0 range = nil @src.each_line do |line| next_line_start = line_start + line.size range = line_start .. (next_line_start - 1) break if range.include?(pos) line_start = next_line_start lineno += 1 end [lineno, range] end def on_error(token_id, val, vstack) lineno, range = get_lineno_and_range(val.pos) colno = val.pos - range.begin + 1 line = @src[range] puts "parse error: line #{lineno}, col #{colno}" puts line print " " * (colno - 1), "^\n" end ---- footer def tokenize(src) tokens = [] pos = 0 while pos < src.size c = src[pos] case c when /\s/ pos += 1 else tokens << [c, TokenValue.new(c, pos)] pos += 1 end end tokens end src = File.read(ARGV[0]) tokens = tokenize(src) parser = Parser.new(src, tokens) result = parser.parse() puts "result: " + result.inspect
a
b
c
d
;
というトークン列だけを受理するパーサです。
入力となるソースコードではトークン同士をスペースや改行で区切ります。パースに成功する例:
a b c d ;たとえば
d
をX
に置き換えた次のソースコードを与えるとパースに失敗します。a b c X ;失敗する場合の実行例:
$ racc parser.y -o parser.rb $ ruby parser.rb sample_ng.txt parse error: line 4, col 3 c X ^ result: nil
短いので上に貼ったコードを読んだ方が早いと思いますが、一応簡単にメモ。
- トークンの開始位置(元のソースコードで何文字目か)をトークン値に持たせておく
- 元のソースコードを
Parser#src
として保持しておく- パースに失敗したら
Parser#src
と失敗したトークンの開始位置を使って 元のソースコード上の行と桁を割り出す関連
- 投稿日:2021-01-01T15:18:43+09:00
【Rails奮闘記/Railsチュートリアル編】Herokuコマンドのまとめ
はじめに
あけましておめでとうございます。
今日から2021年になりました。
本年度もよろしくお願いします。
今回はRailsチュートリアルのHerokuコマンドについて自分で学習したことを簡単にまとめました。
ここではHerokuのアカウントの新規アカウントの作成とHerokuをインストールについては省略します。Herokuコマンド
Herokuがインストールされてるかどうかを確認したいとき
$ heroku --versionHerokuを開かずにログインしたいとき
$ heroku login --interactiveHerokuに新しいアプリケーションを作成したいとき
$ heroku createGitを使ってHerokuにリポジトリをプッシュ
$ git push heroku masterアプリケーションの名前を変更したいとき
$ heroku rename (アプリの名前)本番環境のログを取得したいとき
$ heroku logsイベントが発生するたびに自動表示(Ctrl+Cで終了)
$ heroku logs --tail終わりに
今回はHerokuコマンドについて簡単に復習としてまとめました。
開発環境ばかりに集中して本番環境に手が回らないという人が多いのではないでしょうか?
実際、私も開発現場に入るまでは開発ばかりに気を取られてしまうことが多かったです。
本番環境にも目が行き届く余裕が欲しいと思う2021年になりそうです。
- 投稿日:2021-01-01T15:09:12+09:00
Gemを追加してbuildしたら「Could not find XXX in any of the sources」のエラーが出てハマった時に行ったこと
概要
「Could not find XXX in any of the sources」が出て1時間半ほどハマったので解決の過程をメモとして残しておく。
状況
「rails-controller-testing」をGemfileに追加してdocker-compose buildし、ビルドが完了したのを確認してテストを実行したところエラーをはいた。
Could not find rails-controller-testing-1.0.5 in any of the sources Run `bundle install` to install missing gems.追加したGemが見つからないと言われてるらしい。指示に従ってdocker-compose run web bundle installを実行。再びテストを実行するも同じエラーを吐いた。
試したこと
・Gemfileで指定されてる書き方をしているか
→問題なし。指定通りに記載されている。
・rails-controller-testing-1.0.5のバージョンは対応しているか
→rubygems.orgで確認したが、1.0.5は対応してるので問題なし。
・springを停止して試したらどうなるか
→springを停止しようとすると上記のエラーを吐くのでそもそも停止できない。
・bundleのパスは正しいか
→which bundleで確認したが、./rbenv配下をみてるので問題なし。
・変にキャッシュが残っているんじゃないか
→docker-compose build —no-cacheを実行するも変わらず。解決したやつ
Gemfile.lockを削除して再度bundle installし、テストを実行したところ別のエラーを吐いた。
ERROR: No container found for web_1今度はコンテナが見つからないと言われているらしい。
docker-compose upでコンテナを起動してどんなログが出るか確認してみることに。そしたら以下のエラーを吐いているのを確認。web_1 | Could not find sass-rails-5.1.0 in any of the sources web_1 | Run `bundle install` to install missing gems. rails_web_1 exited with code 7今度は別のGemが見つからないと言われてるらしい。。。
今回も指示に従ってbundle installしてコンテナを再起動したけどエラーは変わらず。
bundle installでバージョンが変わったのかと思い、rubygems.orgでsass-railsのバージョンを確認してみるも、5.1.0は対応している。
installがダメだったので、何となくbuildを試してみたらエラーが消えて正常にコンテナを起動できた。テストを実行したところ無事にテストできた。
Finished in 0.67023 seconds (files took 17.96 seconds to load) 3 examples, 0 failures結論
原因もなぜ解決できたのかも全くわからないけど、僕の場合はGemfile.lockを削除してbundle installとbuildすることで解決できた。
「Could not find XXX in any of the sources」とか情報少なすぎだしもうちょっと長いエラー吐いて欲しい。
参考記事
https://carefree-se.hatenablog.com/entry/2015/07/22/125904
https://qiita.com/jnchito/items/44ab1df134369ed76911
https://qiita.com/nakanowax/items/fe07e8ccd1721befebeb
https://fuqda.hatenablog.com/entry/2019/03/21/204118
- 投稿日:2021-01-01T14:55:19+09:00
Rails でDB に保存されたenum の値をattribute_before_type_cast で取得する
はじめに
Rails でDB に保存されたenum の値を
attribute_before_type_cast
で取得する方法の備忘録です環境
- macOS 10.15.6
- Ruby 2.5.7
- Rails 5.2.3
参考URL
https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/BeforeTypeCast.html
https://railsdoc.com/page/options_for_select
https://310nae.com/rails-selectbox/
https://qiita.com/ozackiee/items/17b91e26fad58e147f2e
attribute_before_type_cast とは?
- enum の文字列ではなくDB に保存された実態値を取得できる
- enum 定義した際に利用できるインスタンスメソッド
enum の名前定義の値と実態値について
enum 使用時は値の見え方がRails 上とDB に保存される値が異なるので注意が必要です
Railsのenumはコードの表記上、文字列(またはシンボル)で透過的に扱えるように実装されています
SQLを直接叩いたり、DBのGUIクライアントを使って保存されたレコード情報を見るとわかりますが実際は文字列ではなく数値が保存されています。
enum で定義した実態値はRails 上では名前定義として振る舞います。
sample.rb# 血液型(blood_type) をenum 定義する enum blood_type: { A型: 0, B型: 1, O型: 2, AB型: 3, # Rails 上での名前定義: DB に保存される実態値 }動作確認
下記の想定で動作確認を行います
- Person モデルにname カラム, blood_type カラムを作成
- Person モデルでblood_type をenum で定義
schema.rb# Parson モデルにname カラム, blood_type カラム を作成 create_table "persons", force: :cascade do |t| t.string "name" t.integer "blood_type" endparson.rb# model にblood_type をenum で定義 class Person < ApplicationRecord enum blood_type: { A型: 0, B型: 1, O型: 2, AB型: 3, } endattribute_before_type_cast メソッド
rails console
を使ってattribite_before_type_cast
の動作確認$ rails console > person = Person.create(name: "Alice", blood_type: 0) # person オブジェクトを作成, DB 保存 :name => "Alice" :blood_type => "A型" > person.blood_type # rails 上の値を取得 "A型" > person.blood_type # rails 上の値のクラスを取得 String < Object > person.blood_type_before_type_cast # DB の値を取得 0 > person.blood_type_before_type_cast # DB の値のクラスを取得 Integer < Numericattributes, attributes_before_type_cast メソッド
attributes
: インスタンスに対して属性名 => 値
が取得できるインスタンスメソッド
attributes_before_type_cast
: attributes のbefore 版。DB 上の実態値を属性名 => 値
の形で取得できるインスタンスメソッド
rails console
を使ってattributes
,attributes_before_type_cast
の動作の違いを確認します$ rails console > person = Person.create(name: "Alice", blood_type: 0) # person オブジェクトを作成, DB 保存 :name => "Alice" :blood_type => "A型" > person.attributes # rails 上の 名前定義を表示 "name" => "Alice" "blood_type" => "A型" > person.attributes_type_before_type_cast # DB の実態値を表示 "name" => "Alice" "blood_type" => 0使用例
私の場合はenum で定義した値から新規投稿フォームを生成するのに使用しました
# 出力したいHTML <select> <option value="1">type1</option> <option value="2">type2</option> <option value="3">type3</option> </select>person.rb# blood_type をenum で定義 class Person < ApplicationRecord enum blood_type: { A型: 0, B型: 1, O型: 2, AB型: 3, } endpersons_controller.rb# person オブジェクトを作成 def new @person = Person.new endデフォルト値(selected: value) の設定に
attirbute_before_type_cast
で取得した値を使用していますnew.html.erb# enum の値からフォーム生成 <%= form_with model: @person local: true do |f| %> <%= f.select :blood_type, options_for_select(Person.blood_types, @person.expense_before_type_cast), {} %> <%= f.submit %> <% end %># フォーム生成時の各値 <%= form_with model: @モデル名 do |f| %> <%= f.select :カラム名, options_for_select(モデル名.カラム名複数形, @モデル名.カラム名_before_type_cast), {} %> <%= f.submit %> <% end %>select タグの空カッコ({}) には注意点があります
必ず通常のオプションを設定しない場合でも空のカッコ{},をオプション部分に設定してください。
この空のカッコがないと、HTMLオプションが無視されてしまうので、id/classを設定したのに効いていない!ということになってしまいます。参考URL: https://310nae.com/rails-selectbox/
# options_for_select の文法 options_for_select(要素の配列 or ハッシュ, デフォルト値, {オプション}, {htmlオプション})
- オプション例
include_blank: true
(先頭行を空にする)selected: default_value
(デフォルト値)- HTMLオプション例
id: id_name
(id を付与)class: class_name
(class を付与)まとめ
- enum 使用時にDB に保存された実態値の取得には
attribute_before_type_cast
かattributes_before_type_cast
を使用する- enum の名前定義の値と実態値は取得方法が異なる
enum を使った事が無くポートフォリオ作成時に見事にハマってしまったので良い勉強になりました!
間違っている場合はコメント頂けると助かります!
- 投稿日:2021-01-01T14:49:03+09:00
rubyで住所文字列から最寄駅までの距離を取得する方法
rubyで住所から最寄駅の情報を取得できる様にしてみました。
やったことざっくり
- Yahoo APIで住所からを緯度経度を取得
- Heart Rails APIで緯度経度から最寄駅情報を取得
1. Yahoo APIで住所からを緯度経度を取得
1.1 yahoo app ID 取得
ここで取得する
https://e.developer.yahoo.co.jp/dashboard/1.2 リクエストする
・リクエストする住所をurl様にエンコード
・open-uriでリクエストする1.3 レスポンスから緯度経度をスクレイピング
REXMLを使って取得します。
coordinatesタグに格納されてます。2. Heart Rails APIで緯度経度から最寄駅情報を取得
2.1 1.で取得した緯度経度でリクエストする
urlはこちら
http://express.heartrails.com/api/xml?method=getStations&x=#{lon}&y=#{lat}"2.2 返ってきた最寄駅情報をスクレイピングする
タグに駅情報が入っています。
複数の駅情報が含まれるので最初のstationタグを指定します。完成したコード
コードはこんな感じになります。
require 'open-uri' require 'uri' require "rexml/document" ## 1. request Yahoo API ### 1.1 YAHOO_APP_ID = '[Yahoo app_id]' ### 1.2 ADDRESS ='東京都千代田区千代田1番1号' p ADDRESS query = URI.encode_www_form(query: ADDRESS) ## エンコーディング request_url = "https://map.yahooapis.jp/geocode/V1/geoCoder?appid=#{YAHOO_APP_ID}&#{query}" ### 1.3 res = OpenURI.open_uri(request_url) doc = REXML::Document.new(res.read) coordinates = doc.elements['YDF/Feature/Geometry/Coordinates'].text lon,lat = coordinates.split(',') p "経度 = #{lon} , 緯度 = #{lat}" ## 2. Heart Rails API ### 2.1 1.で取得した緯度経度でリクエストする heart_rails_request_url = "http://express.heartrails.com/api/xml?method=getStations&x=#{lon}&y=#{lat}" ### 2.2 返ってきた最寄駅情報をスクレイピングする res = OpenURI.open_uri(heart_rails_request_url) doc = REXML::Document.new(res.read) station = doc.elements['response/station[1]'] name = station.elements['name'].text line = station.elements['line'].text distance = station.elements['distance'].text p name p line p distance実行結果
皇居(東京都千代田区千代田1番1号)で最寄駅をリクエストしてみた結果。
"経度 = 139.75381447 , 緯度 = 35.68382285" "桜田門" "東京メトロ有楽町線" "740m"
- 投稿日:2021-01-01T14:49:03+09:00
rubyで住所文字列から最寄駅までの距離を取得してみた
rubyで住所から最寄駅の情報を取得できる様にしてみました。
やったことざっくり
- Yahoo APIで住所からを緯度経度を取得
- Heart Rails APIで緯度経度から最寄駅情報を取得
実行環境
- ruby2.7.2
- mac catalina
- 実行日時 2021/01/01
1. Yahoo APIで住所からを緯度経度を取得
1.1 yahoo app ID 取得
ここで取得する
https://e.developer.yahoo.co.jp/dashboard/1.2 リクエストする
・リクエストする住所をurl様にエンコード
・open-uriでリクエストする
レスポンスはこんな感じ
1.3 レスポンスから緯度経度をスクレイピング
REXMLを使って取得します。
coordinatesタグに格納されてます。2. Heart Rails APIで緯度経度から最寄駅情報を取得
2.1 1.で取得した緯度経度でリクエストする
urlはこちら
http://express.heartrails.com/api/xml?method=getStations&x=#{lon}&y=#{lat}"返ってくるレスポンスはこんな感じ (近い順に複数返ってきてます
)
2.2 返ってきた最寄駅情報をスクレイピングする
上記の様にstationタグに駅情報が入っています。
複数の駅情報が含まれるので最初のstationタグを指定します。完成したコード
コードはこんな感じになります。
require 'open-uri' require 'uri' require "rexml/document" ## 1. request Yahoo API ### 1.1 YAHOO_APP_ID = '[Yahoo app_id]' ### 1.2 ADDRESS ='東京都千代田区千代田1番1号' p ADDRESS query = URI.encode_www_form(query: ADDRESS) ## エンコーディング request_url = "https://map.yahooapis.jp/geocode/V1/geoCoder?appid=#{YAHOO_APP_ID}&#{query}" ### 1.3 res = OpenURI.open_uri(request_url) doc = REXML::Document.new(res.read) coordinates = doc.elements['YDF/Feature/Geometry/Coordinates'].text lon,lat = coordinates.split(',') p "経度 = #{lon} , 緯度 = #{lat}" ## 2. Heart Rails API ### 2.1 1.で取得した緯度経度でリクエストする heart_rails_request_url = "http://express.heartrails.com/api/xml?method=getStations&x=#{lon}&y=#{lat}" ### 2.2 返ってきた最寄駅情報をスクレイピングする res = OpenURI.open_uri(heart_rails_request_url) doc = REXML::Document.new(res.read) station = doc.elements['response/station[1]'] name = station.elements['name'].text line = station.elements['line'].text distance = station.elements['distance'].text p name p line p distance実行結果
皇居(東京都千代田区千代田1番1号)で最寄駅をリクエストしてみた結果。
"経度 = 139.75381447 , 緯度 = 35.68382285" "桜田門" "東京メトロ有楽町線" "740m"
- 投稿日:2021-01-01T14:27:13+09:00
騙されるな!プログラミングの勉強なんて最初はこれだけで十分!
「プログラマーなら最低限これくらい勉強しておかないと…」
「今時、〇〇を使わないなんて…」うるせーーーーーーー!!!!!!!
近頃、プログラミングについての情報発信が多いので、色々と勉強しないといけないと思っている人が多いです。
初心者がDockerを勉強していたり、CI/CDツールを使おうとしていたり…
楽しいならそれでいいのですが、特に必要性もないのに無理に難しい技術を使っても頭に入ってこないと思います。
プログラミングを効率よく習得するなら、勉強するより開発することです。
料理も座学で勉強しまくるより、作りまくったほうが上達しますよね?
プログラミングもそんなもんです。特にプログラミングをまだ面白いと思えていない方は、情報に振り回されて勉強ばかりしている可能性大です。
上達するためにも、楽しさを知るためにも、簡単なサービスでいいのでさっさと開発してみましょう。とはいえ知識0では開発することが難しいという意見も分かります。
そこで下記の対象者のような方が、何をどれくらい勉強すればいいのか簡単に紹介します。「対象者」
- 勉強を始めたばかりのプログラミング初心者
- 勉強はそこまで好きではないがプログラミングをしてみたい方
- プログラミングの知識はないけど個人開発をしてみたい方
- 開発せずに勉強に逃げている方
最後の「開発せずに勉強に逃げている方」は、もしかしたら今回紹介する勉強内容をすでに終えているかもしれません。
それなら次に勉強するものを探すのではなく、すぐに開発に取り組みましょう!まずはProgateで勉強
- HTML/CSS
- JavaScript
- Ruby
- Ruby on Rails
- Command Line
- Git
- SQL
分かりやすい良い教材です。
プログラミング初心者の方もとっつきやすいと思います。
様々なコースがありますが、まずは上記で紹介したコースを学ぶことをオススメします。
これらを学ぶことがどう役立つかは実際に作ってみないと分からない部分も多々あります。
とりあえず学んでみることをオススメします。
Ruby on Railsの知見を深める
さすがにProgateレベルの知識だけで開発をするのはしんどいと思います。
そこでRuby on Railsの知見を、もう少し深めましょう。
オススメは「Railsチュートリアル」という教材です。
(解説動画付きだと高額になりますが、テキストのみだと最新版でも980円+税で読めます)
ただし有名な教材だけあって質はいいのですが、難しいです。
そのため1周目で完璧に理解する必要はありません。
何なら挫折して当たり前くらいの気持ちで、挑戦してください。
Railsチュートリアルがあまりにも難しいと感じた方は、僕が作った「Railsビギナー」という教材に挑戦してみてください。
Railsチュートリアルに挫折する方が多いので、プロゲートとRailsチュートリアルの間の難易度の教材を自分で作ってみました。
もちろん無料で読めるので安心してください。
無料ですが合計で6万文字以上あるちゃんとした教材です。
https://maki-nomad.com/rails-beginner/
「Railsチュートリアルなんて初心者向けの教材なんだから簡単だよ!」というアドバイスは聞かなくていいです。
難しい教材を簡単だと紹介して自分のレベルを高く見せようとする、初心者に優しくないクソみたいなエンジニアのアドバイスは無視して大丈夫です。
さぁ、開発を始めよう
これだけ勉強すればさっさとサービスを作ってみてください。
めちゃくちゃしょぼいサービスしか作れないと思いますが、それでいいのです。
プログラミングの楽しさに気付けると思います。
こんなことを言うと「実際に仕事で使えるようになるには、もっと勉強が必要だ」とか、しょーもないことを言ってくるエンジニアもいます。
「仕事で使えるようになるのに必要な勉強量」なんて言っていません。
「まずはこれだけで十分」という話です。まずは楽しさを知ってください。
最初から難しい技術に挑戦して楽しめるのは天才だけです。楽しさに気づけたら自然と興味が湧いてきます。
「もっと分かりやすいコードを書くにはどうすれば?」
「もっとカッコよく動きのあるサービスを作ってみたいなぁ」そうなれば自然と学習をしていて、以前より苦しまずに勉強に取り組めますよ。
今回紹介した学習の道筋は、勉強がそこまで好きではない方に向けたものです。
勉強がけっこう好きな方には、もう少し学習のボリュームを増やしたオススメの学習の道筋もあります。
https://note.com/maki_yuya/n/n24618b7087ac
↑以前まで有料の記事でしたが、2021年に無料化しました!また有料化するかもしれないので、お早めにチェック!
あと、もしあなたが個人開発に興味があるなら、無理に難しい技術を使う必要はないということも知っておいてください。
実際に僕も個人開発をするとき、Dockerは使いませんし、デプロイする先はAWSではなくHerokuです。
そんな感じで僕が作ったサービスはこちら↓
/
— 真木 裕也@うつ病から独学でフリーランスになった僕 (@maki_nomad) December 31, 2020
初詣に行けない時代なので「tanomun」を作成!
\
Twitterで願い事を募集して、集まった願い事に返答しましょう!
返答はTwitterでシェアできます?
「神に頼めないときは私に頼め」がテーマです(笑)
詳細は下記URLをチェック!#拡散希望 #初詣 #プログラミングhttps://t.co/iqaFTgUCVmお願い事ができる&届くサービスです。
初詣に行きにくい人が多いと思ったので、せめて気分だけでも初詣を味わってください!
まとめ
勉強することが目的ではありません。
あなたの頭の中に知識が詰まっているだけでは意味がありません。
開発してサービスを生み出して初めて価値になります。
勉強に逃げず、開発をしてみましょう。
それが楽しさと成長に繋がります。
これからプログラミングの勉強を始めてフリーランスを目指す方は、こちらの記事も参考にしてみてください↓
https://note.com/maki_yuya/n/nb3ddcc27daf6
フリーランスになるまでの悪い面もリアルに書いたので、参考になると思います。
それでは2021年を良い年にしていきましょう!!!
- 投稿日:2021-01-01T11:46:50+09:00
【Heroku】デプロイ時 We're sorry, but something went wrong.解決方法
ローカル環境で構築して、Herokuにデプロイしたが、こんな画面がでてしまいました。
We're sorry, but something went wrong.
原因
開発環境(deveropment)はMySQLとしていたが、Herokuの標準データベースはPostgreSQLだが、MySQLのままだった。
対処方法
gemに下記を追記して、本番環境ではpostgreSQLを適用する。
group :production do gem 'pg', '>= 0.18', '< 2.0' end※
group :production do
で本番環境のみの適用となります。bundle installしますが、開発環境のみで本番環境では不要なので、
--without production
をつけます。$ bundle install --without production次にdatabase.ymlを編集します。
デフォルトではこのようになっていると思います。database.ymlproduction: <<: *default database: <app_name>_production username: <app_name> password: <%= ENV['<app_name>_DATABASE_PASSWORD'] %>これをこのように書き換えます。
database.ymlproduction: adapter: postgresql encoding: unicode pool: 5 database: <app_name>_production username: <app_name> password: <%= ENV['<app_name>_DATABASE_PASSWORD'] %>あとは、
heroku push
して、忘れずにheroku run rails db:migrate
すればOKです!
- 投稿日:2021-01-01T11:12:07+09:00
Docker上のRailsでコントローラーの変更がブラウザに反映されない時の対処法
問題
controller.rb
の変更がブラウザに反映されない。
コンテナを再起動すれば反映されるが、毎回再起動するのは手間がかかる。環境
Windows 10 home
Docker for Windows
Rails 6.1
Ruby 2.7
解決策
config\environments\development.rb
内の
config.file_watcher = ActiveSupport::EventedFileUpdateChecker
を下記コードに修正する。config.file_watcher = ActiveSupport::FileUpdateCheckerわからないこと
下記コードを記載しても解決できる。
Railsガイドを見ても上記コードとの違いがわからなかったので、違いが分かる人がいましたら、ご教授いただければ幸いです。config.reload_classes_only_on_change = false参照:『Railsガイド』- Rails アプリケーションを設定する
参考
- 投稿日:2021-01-01T05:22:38+09:00
hashで存在しないキーを呼び出した場合のハンドリング
チェリー本で学んだことの雑メモ。
rubyのhashは、存在しないキーを呼び出してもnilが返るだけでミスに気付きにくかったりするので、明示的なメッセージを出力するようにしてみた。hash = Hash.new('存在しないキーです。') hash.merge!({key1: :value1}) hash[:key1] # => :value1 hash[:key2] # => "実在しないキーです。"
- 投稿日:2021-01-01T00:58:45+09:00
初心者の自分がコードレビューを受けて指摘されたことまとめ
はじめに
アプリのコードレビューを初めて受けて何点か指摘があったので次からは気を付けて行きたいといった意味を込めて指摘を受けた部分をまとめていく。
なお、指摘を受けた内容はフリマアプリの制作段階でのことである。REDMEでのコードレビュー
・deviseを使用したのだがencrypted_passwordというカラムを記述するのを忘れていた。
・メールアドレスは一意性という条件が設けられているにも関わらず一意性制約の記述がなかったこと。
・見本アプリではユーザーの登録時、姓、名、姓(フリガナ)、名(フリガナ)と入力欄が細かく分かれているのに姓名を一緒にしてしまっていたこと。
・誕生日カラムをdate型で年、月、日と一つにするのではなく、単に数字だからという考えでinteger型にしていたこと。
・imageの実装はactive storageを使うためREDMEに記述する必要がないにも関わらず記述していたこと。
・郵便番号はハイフンも含めるためinteger型にする必要があるのにstring型にしていたこと。
・active hashを使用時データはidで保存されるため、integer型にしなければならないのに、string型にしていたこと。
・電話番号は数字の文字列で保存するためstring型にしなければならないこと。
新規登録・ログイン機能でのコードレビュー
・バリデーションをwith_optionsでまとめていなかったこと。可読性を上げるためにもまとめた方が良い。
・passwordでの文字数制限のバリデーションはdeviseでデフォルト設定になっているにも関わらずmaximumで設定しようとしていたこと。
・パスをprefixで記述していなかったこと。可読性を上げるためにもprefixで記述した方が良い。
・不要なコメントアウトの消し忘れ。可読性を上げるため。
商品を出品する機能でのコードレビュー
・before_action :authenticate_user!で制限を設ける際、application_controller.rb内に記述してしまっていたこと。
・with_optionsをネストせずに分けて記述していたこと。
・300円以下は登録できないというテストコードを実装する際、境界値の299で実装した方が良いのに200で実装していたこと。
商品の購入機能でのコードレビュー
・ @item = Item.find(params[:id])はdestroy,edit,update,showで共通なため、before_actionでまとめた方が可読性が上がるにも関わらずまとめていなかったこと。
・resources :items, only: [:index, :new, :create, :show, :edit, :update, :destroy]と全てのアクションが記述されているのに resources :itemとまとめて記述していなかったこと。
・フォームオブジェクトの中に、:user_idと:item_idを記述していなかったこと。ユーザーのIDと商品のIDが無い場合、確実に購入できないようにするために必要。
・任意である、建物名の「建物名が空でも購入できること」のテストコードを実装していなかったこと。建物名は任意入力となっているため建物名を記入せずに購入するユーザーが居る可能性を想定したテストコードを実施する。
最後に
改めてこのようにまとめてみると、初歩的なミスが多かったなと思った。同じミスせず効率よくコードを描けるように頑張って行きたい。
- 投稿日:2021-01-01T00:01:47+09:00
【環境構築】Ruby on Rails 6 開発環境を1時間以内に手に入れる
内容
「プログラミングをはじめたい!」「Webエンジニアを目指したい!」という思いを持ち始めたプログラミング初学者の方が、Ruby及びそれを使ったフレームワークであるRuby on Railsに挑戦するというのは王道の学習パターンなのではないかと思います。
Ruby on Railsをはじめるにあたって最初に大きな壁として立ちはだかるのが環境構築です。私自身も約3ヶ月前に異業種からの転職でRubyエンジニアとして働きはじめたばかりなので、環境構築などの「プログラミング学習を始める以前の準備」に時間を取られた時のことは記憶に新しいです。
本記事では、一人でも多くのプログラミング初学者の方にRailsの魅力を感じて欲しいという思いから「Ruby on Rails 6 開発環境を1時間以内に手に入れる」ことを目標に、そのための手順を紹介します。
ゴール
Ruby on Rails6の開発環境を備えたUbuntuの仮想環境をmacOS上に構築する(目標1時間以内)。
前提環境
macOSCatalina バージョン 10.15.7
※ Windowsの方はゴメンナサイ。また、macOSの方でもバージョンの差異で多少の違いが発生する可能性はあります。
Virtual Box 6.1.16
※ インストール手順は後述
Vagrant 2.2.14
※ インストール手順は後述
想定する読者
・macOSユーザーの方
・macOSのターミナルを使った経験があり、基本的なLinuxコマンド(cd, mkdir, lsなど)の意味を知っている方
・ProgateなどでRuby on Railsの概要を学んだことがある方
・AWS Could9などのクラウドベースの統合開発環境に限界を感じている方
・過去にRuby on Railsの環境構築に挫折した経験のある方仮想環境とは?
使っているOS(ホストOS:本記事ではmacOSを想定)の中に、あたかも別のOS(ゲストOS:本記事ではUbuntuを使用)が入っているような環境のことを言います。
ホストOS上に開発環境を直接構築する場合、誤った設定や削除を行ってしまったことによりホストOSに悪影響を与えてしまう可能性はありますが、仮想環境上で環境構築をする場合であれば、何かミスをしてしまった時はその仮想環境ごと削除してやり直せば良く、ホストOSに悪影響を与えることはありません。
また、AWS Could9などのクラウドベースの統合開発環境よりもリソース拡張の自由度が高く、CPUの性能限界やメモリ不足に悩まされることは(少なくともRailsでWebアプリケーションを開発するだけであれば)ほとんどないと言っていいと思います。Virtual Box
仮想環境を構築するための「仮想化ソフト」として、まずはVirtualBoxをインストールします。
下記のダウンロードページから、(本記事ではmacOSを想定しているので)「OS X hosts」のリンクをクリックしてインストーラをダウンロードしてください。
ダウンロードしたインストーラを起動すれば、インストール手順がわかりやすく書いてあるので、それに従えばVirtual Boxのインストールは終了となります。
(※ 2021年1月1日現在の最新版は6.1.16なので、ここからはそのバージョンでの動作を前提としております)Vagrant
次に、仮想化ソフトを管理するツールであるVagrantをインストールします。
下記ダウンロードページにアクセスし、上記のVirtualBoxと同様に、インストーラのダウンロード、インストーラ起動、インストールという手順を踏めばほとんど迷うことなく完了すると思います。
仮想化ソフトである「VirtualBox」を操作するためのツールが「Vagrant」である、という認識を持っていただければとりあえず最低限の知識としてはOKです。
(※ 2021年1月1日現在の最新版は2.2.14なので、ここからはそのバージョンでの動作を前提としております)環境構築手順
Virtual BoxとVagrantを問題なくインストールしたら、ここからは実際に仮想環境を構築して行きたいと思います。今回は、Ubuntu(18.04)というゲストOSが入っている仮想環境を構築します。
ここからの操作はmacOSのターミナルで行います。作業に入る前にvagrantが正しくインストールされていることを確認しましょう。ターミナルを開いて
vagrant -v
と入力してみてください。Vagrant 2.2.14
という出力が返ってくれば準備はOKです、早速はじめていきましょう!1. vagrant-vbguestのインストール
$ vagrant plugin install vagrant-vbguest仮想マシンでの操作を簡単にしてくれる役割がある、という理解でとりあえずはOKです。
2. 任意の場所にディレクトリを作成
$ mkdir rails6_dev $ cd rails6_dev3. Vagrantfile作成
$ vagrant init上記コマンドでデフォルトの
Vagrantfile
が作成されます。Vagrantfile(デフォルト|一部抜粋)# -*- mode: ruby -*- # vi: set ft=ruby : # All Vagrant configuration is done below. The "2" in Vagrant.configure # configures the configuration version (we support older styles for # backwards compatibility). Please don't change it unless you know what # you're doing. Vagrant.configure("2") do |config| ~ ~ config.vm.box = "base" ~ ~ # config.vm.network "forwarded_port", guest: 80, host: 8080 ~ ~ # config.vm.network "private_network", ip: "192.168.33.10" ~ ~ end上記のデフォルト状態の
Vagrantfile
の中身を、下記のコードに書き換えてください。Vagrantfile(書き換え後)# -*- mode: ruby -*- # vi: set ft=ruby : # All Vagrant configuration is done below. The "2" in Vagrant.configure # configures the configuration version (we support older styles for # backwards compatibility). Please don't change it unless you know what # you're doing. Vagrant.configure("2") do |config| GUEST_RUBY_VERSION = '2.6.6' GUEST_RAILS_VERSION = '6.0.3.4' config.vm.box = "bento/ubuntu-18.04" config.vm.box_check_update = false config.vm.network "forwarded_port", guest: 3000, host: 3000 config.vm.network "private_network", ip: "192.168.33.10" config.vm.synced_folder "./", "/home/vagrant/work" config.ssh.forward_agent = true config.vm.provider "virtualbox" do |vb| vb.gui = false end config.vm.provision "shell", inline: <<-SHELL echo '### installing tools ###' sudo timedatectl set-timezone Asia/Tokyo sudo apt update -y sudo apt upgrade -y sudo apt install build-essential -y sudo apt install -y libssl-dev libreadline-dev zlib1g-dev sudo apt install -y imagemagick SHELL config.vm.provision "shell", privileged: false, inline: <<-SHELL echo '### installing Ruby ###' git clone https://github.com/sstephenson/rbenv.git ~/.rbenv echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile echo 'eval "$(rbenv init -)"' >> ~/.bash_profile source ~/.bash_profile git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build rbenv install #{GUEST_RUBY_VERSION} rbenv global #{GUEST_RUBY_VERSION} echo '### installing Rails ###' gem install rails -v #{GUEST_RAILS_VERSION} echo '### installing SQLITE3 ###' sudo apt install libsqlite3-dev echo '### installing NodeJS ###' sudo apt install -y nodejs npm sudo npm install n -g sudo n lts sudo apt purge -y nodejs npm sudo apt -y autoremove sudo npm install yarn -g sudo chown -R $USER:$GROUP ~/.config echo ' -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-' echo 'You are now on Rails!' echo ' -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-' SHELL end本記事での解説は避けますが、このVagrantfileにはRailsを使えるようにするための設定が書いてあります。最初は難解に感じるかもしれませんが、ぜひ一度、読み解くことをオススメします。
もちろん私が書いたこのVagrantfileが唯一の正解では決してないので、「もっといい書き方があるよ」「こっちの方が使いやすいと思う」っていうご意見も大歓迎です!
(こちらのVagrantfileのソースコードはGithubにもあげてあります。)
4. 仮想環境構築
$ vagrant up上記コマンドで仮想環境を構築します(PCのスペックにもよりますが、15〜30分ほどかかります)。
先ほどのVagrantfileに書かれた設定を1行ずつ実行していくことでRailsの開発環境が作られていっているということだけは抑えて頂けるといいかなと思います。5. 仮想環境へSSH接続
$ vagrant ssh上記コマンドで出来上がった仮想環境にSSH接続します。
SSH接続とは、ネットワークを経由して自身のPCから他のPC(今回は仮想環境)を安全に遠隔操作するための仕組みである、ということだけは抑えておいてください。ここまでがmacOSのターミナルでの操作です。次の「6. Railsアプリケーション作成」と「7. ssh接続から抜ける」ではmacOSからssh接続をして、ゲストOSのUbuntuを操作しているということをご認識ください。
6. Railsアプリケーション作成
vagrant@vagrant:~$ cd work vagrant@vagrant:~/work$ rails new sample-app vagrant@vagrant:~/work$ cd sample-app vagrant@vagrant:~/work/sample-app$ rails s -b 0.0.0.0この状態で
http://localhost:3000/
にアクセスすると、Yay! You’re on Rails!
のデフォルト画面が表示されます。
立ち上げたRailsサーバーは
command + C
で停止することができます。7. ssh接続の終了
$ exit上記コマンドでSSH接続を終了することができます。
8. 仮想環境のマシンをシャットダウンする
vagrant halt上記コマンドで仮想環境上のゲストOSをシャットダウンすることができます。
再度立ち上げたい時は、vagrant up
で立ち上げvagrant ssh
で接続します(2回目以降は数分で完了します)。9. Railsアプリケーションの開発を進める方法
「2. 任意の場所にフォルダを作成」で作成したディレクトリ内に「6. Railsアプリケーション作成」で作成したRailsアプリと同名のファイルが作成されているはずなので、そこのコードを書き換えることで開発を進めます。
rails g controller Users
やbundle install
等のコマンドはSSH接続をした状態で、作成したRailsアプリケーションのディレクトリ上で叩くことになります。
終わりに
いかがでしたでしょうか?スムーズに行けば、
Yay! You’re on Rails!
の表示まで1時間以内にいけるではないかなと思っております。Rubyという言語、Railsというフレームワークは触っていると本当に面白くて飽きないものなので、この記事で環境構築をしたことをきっかけに少しでもその魅力にハマっていただければ嬉しい限りです。
本記事についての質問や改善点のご指摘等がございましたら、コメントやTwitterでのDMなどをいただければ幸いです!