- 投稿日:2020-05-21T22:51:34+09:00
Rails5.2系+webpackerでログアウト機能を実装しようとしたらno route matches [get] "/logout"のエラーが出てしまい、postメソッドが上手く動作しなかった件について
はじめに
投稿系のアプリケーションを作成中、Rails5.2にwebpackerを導入してログアウト機能を実装しようとした際、
no route matches [get] "/logout"
エラーが出てdeleteリクエストを送信できなくなってしまったので、これを解決します。環境
Ruby 2.6.5
Rails 5.2.4.2
webpacker 5.1.1エラー発生地点
webpackerビルド後に、application.html.slimにwebpackerのスクリプトタグを読み込んだ瞬間から。
app/views/layouts/application.html.slimhead . . . - = javascript_include_tag 'application','data-turbolinks-track': 'reload' + = javascript_pack_tag 'application' . . .
解決策
1.まずはyarnのパッケージファイルに
rails-ujs
を追加します。そしてpackage.jsonにこれが追加されていることを確認します。$ yarn add rails-ujspackage.json{ "name": , "dependencies": { "@rails/webpacker": "5.1.1", "rails-ujs": "^5.2.4-3", }, }
2.app/javascript/packsディレクトリ配下に
rails-ujs.js
ファイルを作成し、下記の記述を追加します。app/javascript/packs/rails-ujs.jsimport Rails from 'rails-ujs'; Rails.start();
3.app/javascript/packs/application.jsファイルに、rails-ujs.jsファイルを読み込ませます。
app/javascript/packs/application.jsrequire("./rails-ujs.js");
4.app/views/layouts/application.html.slimファイルに、webpackerスクリプトを記述します。app/views/layouts/application.html.slimhead . . . = javascript_pack_tag 'application' . . .以上で、DELETEリクエストを受けてくれるようなったかと思います。
何故これで動作するのか
色々調べた結果、辻褄を合わせただけのため断言はできませんが、こうだろうみたいな予想を立ててみました。
もし間違っていたら、ご指摘して頂けるととてもありがたいです!
まず前提として、デフォルトの状態ではHTMLはGET,POSTのリクエストを送信することしかできません(なのでログインなどは通常通り行えます)
しかしRailsにてDELETE,PATCHなどのRESTful APIを発行する場合は、JavaScriptに処理を任せているため
gem rails-ujs
もしくはgem jquery-rails
を用いています。Rails5.1以降ではJavaScriptの統括ファイルにこの
rails-ujsがデフォルトで読み込まれています
(下記ファイルを参照)。なので我々は特に気にしなくとも、ただRails側でmethod: :deleteなどのオプションを記述すれば、あとはJavaScriptが勝手に処理してくれるため、HTMLからDELETEリクエストを送信することができるようになっています。
ちなみにjquery-ujsはRails5.1以降サポートが廃止されています(Railsガイドより。)
app/assets/javascript/application.js//= require rails-ujs //= require activestorage //= require turbolinks //= require_tree .
しかしwebpackerを導入すると、デフォルトの状態ではrails-ujsがそもそも導入されていないので、サポートを受けることができません。なのでrails-ujsを導入し、packs/application.jsファイルに新たにrails-ujs読み込みさせてあげなければ、RESTfulなAPIの処理を使用できないのは当然だったのかなと思いました。
参考
http://docs.komagata.org/5456
https://www.inodev.jp/entry/2019/12/03/234210
- 投稿日:2020-05-21T22:51:34+09:00
Rails5.2系にwebpackerを導入した途端元から実装してあったログアウト機能がno route matches [get] "/logout"エラーで動かなくなった
はじめに
投稿系のアプリケーションを作成中、Rails5.2にwebpackerを導入した途端、元から実装してあったログアウト機能が動作しなくなりました。
no route matches [get] "/logout"
エラーが出てdeleteリクエストを送信できなくなってしまったので、これを解決します。環境
Ruby 2.6.5
Rails 5.2.4.2
webpacker 5.1.1エラー発生地点
webpackerビルド後に、application.html.slimにwebpackerのスクリプトタグを読み込んだ瞬間から。
app/views/layouts/application.html.slimhead . . . - = javascript_include_tag 'application','data-turbolinks-track': 'reload' + = javascript_pack_tag 'application' . . .
解決策
1.まずはyarnのパッケージファイルに
rails-ujs
を追加します。そしてpackage.jsonにこれが追加されていることを確認します。$ yarn add rails-ujspackage.json{ "name": , "dependencies": { "@rails/webpacker": "5.1.1", "rails-ujs": "^5.2.4-3", }, }
2.app/javascript/packsディレクトリ配下に
rails-ujs.js
ファイルを作成し、下記の記述を追加します。app/javascript/packs/rails-ujs.jsimport Rails from 'rails-ujs'; Rails.start();
3.app/javascript/packs/application.jsファイルに、rails-ujs.jsファイルを読み込ませます。
app/javascript/packs/application.jsrequire("./rails-ujs.js");
4.app/views/layouts/application.html.slimファイルに、webpackerスクリプトを記述します。app/views/layouts/application.html.slimhead . . . = javascript_pack_tag 'application' . . .以上で、DELETEリクエストを受けてくれるようなったかと思います。
何故これで動作するのか
色々調べた結果、辻褄を合わせただけのため断言はできませんが、こうだろうみたいな予想を立ててみました。
もし間違っていたら、ご指摘して頂けるととてもありがたいです!
まず前提として、デフォルトの状態ではHTMLはGET,POSTのリクエストを送信することしかできません(なのでログインなどは通常通り行えます)
しかしRailsにてDELETE,PATCHなどのRESTful APIを発行する場合は、JavaScriptに処理を任せているため
gem rails-ujs
もしくはgem jquery-rails
を用いています。Rails5.1以降ではJavaScriptの統括ファイルにこの
rails-ujsがデフォルトで読み込まれています
(下記ファイルを参照)。なので我々は特に気にしなくとも、ただRails側でmethod: :deleteなどのオプションを記述すれば、あとはJavaScriptが勝手に処理してくれるため、HTMLからDELETEリクエストを送信することができるようになっています。
ちなみにjquery-ujsはRails5.1以降サポートが廃止されています(Railsガイドより。)
app/assets/javascript/application.js//= require rails-ujs //= require activestorage //= require turbolinks //= require_tree .
しかしwebpackerを導入すると、デフォルトの状態ではrails-ujsがそもそも導入されていないので、サポートを受けることができません。なのでrails-ujsを導入し、packs/application.jsファイルに新たにrails-ujs読み込みさせてあげなければ、RESTfulなAPIの処理を使用できないのは当然だったのかなと思いました。
参考
http://docs.komagata.org/5456
https://www.inodev.jp/entry/2019/12/03/234210
- 投稿日:2020-05-21T22:09:58+09:00
個人アプリの制作日記3
今日の実装
viewの作成 tewwt #index
見た目を整え、教えてほしい問題の連絡記事を閲覧できるようにした。
7割は終わった。tewwt indexをroot_pathにあて、1ページですべての種類の記事を見られるようになった。1ページにまとめることでstu-suppo(アプリケーション)がどんなサイトなのかひと目で見られうようにするのが狙いだ。users_controller #edit #updeta サインアウト
deviseにあるもとのカラム以外にname,image,introduction,subjectカラムを追加したのでfrom-forを用いでデーターベースに更新できるようにした。
苦戦したこと
railsのversionが5.0なのにform withメソッドを使うことを使おうとしていた。
後でわかったことだがform withメソッドはrailsのversionが5.0は非対応。tewwt index で未実装なもの
SCSSでおしゃれなレイアウトにする
動画の埋め込み
インクリメンタルサーチまとめ
今日はだいぶ手間取ってしまったから、朝にしっかりタスクを分けて計画的進む必要あり。
また、睡眠時間をしっかり確保し体調を整える。
- 投稿日:2020-05-21T20:47:32+09:00
Railsアプリケーションにfullcalendarを導入
本投稿について
現在作成しているRailsアプリケーションに予定を書き込めるカレンダーを表示させるために、jQureryのFullCallendarを導入しました。カレンダーの表示方法を探している方の助けになればいいなと思います。
前提条件
ビューはhamlとSCSSで書いております。
Rails "5.0.7.2"を使用しています。コマンド
scaffold で Eventモデルを作成しました。
FullCalenderで予定を書き込む場合、Eventというモデル名じゃないと機能しないらしいです。$ rails g scaffold event title:string body:string start_date:datetime end_date:datetime $ rails db:migrate RAILS_ENV=development導入するGemFile
以下の3つを書いてbundle install
gem 'jquery-rails' gem 'fullcalendar-rails' gem 'momentjs-rails'
SCSSへの記入
application.scssに以下を記入
app/assets/stylesheets/application.scss*= require_tree . *= require_self *= require fullcalendar */JavaScript
コピーしてそのまま貼り付けてください。これによりカレンダーが日本語で表示されます。
app/assets/javascripts/application.js//= require jquery //= require moment //= require fullcalendar $(function () { // 画面遷移を検知 $(document).on('turbolinks:load', function () { if ($('#calendar').length) { function Calendar() { return $('#calendar').fullCalendar({ }); } function clearCalendar() { $('#calendar').html(''); } $(document).on('turbolinks:load', function () { Calendar(); }); $(document).on('turbolinks:before-cache', clearCalendar); //events: '/events.json', 以下に追加 $('#calendar').fullCalendar({ events: '/events.json', //カレンダー上部を年月で表示させる titleFormat: 'YYYY年 M月', //曜日を日本語表示 dayNamesShort: ['日', '月', '火', '水', '木', '金', '土'], //ボタンのレイアウト header: { left: '', center: 'title', right: 'today prev,next' }, //終了時刻がないイベントの表示間隔 defaultTimedEventDuration: '03:00:00', buttonText: { prev: '前', next: '次', prevYear: '前年', nextYear: '翌年', today: '今日', month: '月', week: '週', day: '日' }, // Drag & Drop & Resize editable: true, //イベントの時間表示を24時間に timeFormat: "HH:mm", //イベントの色を変える eventColor: '#87cefa', //イベントの文字色を変える eventTextColor: '#000000', eventRender: function(event, element) { element.css("font-size", "0.8em"); element.css("padding", "5px"); } }); } }); });カレンダーの表示方法
"#calendar"だけで表示されます(HTMLで書く場合はidがcalendarのdiv要素を書いてください)。
app/views/events/index.html.haml%p#notice= notice %h1 Events %table %thead %tr %th Title %th Body %th Start date %th End date %th{:colspan => "3"} %tbody - @events.each do |event| %tr %td= event.title %td= event.body %td= event.start_date %td= event.end_date %td= link_to 'Show', event %td= link_to 'Edit', edit_event_path(event) %td= link_to 'Destroy', event, method: :delete, data: { confirm: 'Are you sure?' } %br/ = link_to 'New Event', new_event_path //今回は既にあるコードの下に書きました。 #calendar※注意点
turbolinksの機能をOFFにしてください。app/views/layouts/application.html.haml%body{"data-turbolinks" => "false"} = yieldルーティングの設定
起動してすぐに確認できるようにルーティングを設定しておきます。
Rails.application.routes.draw do root "events#index" resources :events end"rails s"でアプリを起動すると以下のようにカレンダーが表示されるようになるはずです。
New eventsをクリックして入力することでカレンダー上にイベントが表示されます。
カレンダー上のイベントをクリックするとイベントの詳細を確認できます。
感想
jQureryのライブラリを利用することで、簡単にカレンダーを表示させることができました。
今後ともライブラリを積極的に使っていきたいものです。参考文献
- 投稿日:2020-05-21T20:44:27+09:00
100日後に1人前になる新人エンジニア(1日目)
100日後に1人前になる新人エンジニア(1日目)
どうもこんばんは今日が1日目になります。
ちなみに昨日から始まっていますのでよかったらこちらからどうぞ
100日後に1人前になる新人エンジニア(0日目)今日やったこと
本日より本格的に業務に取り組みました。
さっそくissueに取りかかり頑張るぞ...
と思ってましたが、Dockerの使い方がわからん...
ということでまずそこで悪戦苦闘した前半。その後Railsでフォームの改修に取り組みましたが...
プロジェクトのフォルダ多すぎて何が何だかわからんぞという始まり方でした。
少しずつ理解を深めていきアーキテクチャとかクラスごとの繋がりも分かってきたら
面白いんだろうなあって思っています。Dockerあれこれ
今日はここからでした。いくつか使ったコマンドを
dockerコマンドdocker-compose build #サービス(web,DB)のビルドを実行 docker-compose up #コンテナを作成して、起動 docker-compose down #コンテナを停止し、そのコンテナとネットワークを削除 docker-compose ps #コンテナの一覧を表示 コンテナの状態がわかるよきっと他にもいっぱいあるので少しずつキャパを増やして行こう。
あれ..ファイルの変更時に情報が反映されないぞ...そんな時は
dockerコマンドdocker-compose build #サービス(web,DB)のビルドを実行 docker-compose up -d #デタッチド・モード:バックグラウンドでコンテナを実行し、新しいコンテナ名を表示なるほどねー。これで大丈夫みたい。
なんで情報の変更を反映時はバックグラウンドで起動するんだろ?
あと変更した時にこれを行わないで画面リロードで良い時もあったけど何が違うんだ?
本日の疑問点です。明日までに解決します。そしてコツコツとドキュメントを読んでいきます
--追記--
docker-compose.yml or ./docker/rails/Dockerfile に書かれている内容に変更があったら 再度buildする必要あり。疑問点は無事解決Rails あれこれ
プロジェクトがとても大きい...
どんなroutesになってるのかこんがらがっちまったよ・僕が知っていた方法...
config/routes見れば全部書いてあるだろ!!
って思ってたけど大変そうでした。よって以下の方法で確認$ rails routes他にも色々とあるようでして
Tipsを先輩社員の方からいただきました。・localhost:3000/rails/infoで
すげーroutes全部出てきたしちゃんと検索もできる!!・docker-compose upから
ログが出力されているのでどのコントローラを使って
画面が遷移しているのかが確認できるよありがたきアドバイスでした。
デバッグって
コードの途中にraiseを入れると...
アプリを立ち上げるとエラー画面になっているけど
その画面でコンソール?を打ち込むと各情報が得られました。すげー例えばform controllerのコードの途中にraiseを入れておいて
アプリを立ち上げ→エラー画面からコンソールを入力
params と入力してみるとどんな値が送られているのかちゃんと確認できました。
明日から使います。ありがたや...他にもやり方は色々とあるはずなのでそこは確認してみます。
formに関してはまだ完成していないので続きは明日に回します。
今日のさいごに
今日が連載初日でした。
何事も積み重ねだと思うので一日ひとつづつ。フィルヒースの言葉をいただきます。
Winning is habitualですね1人前のエンジニアになるまであと99日
- 投稿日:2020-05-21T20:12:34+09:00
【Rails】Carrierwaveを導入する
タイトルと本文のみの投稿ができるブログアプリに
写真の投稿機能を追加した時の、Carrierwaveを導入する
手順に付いてまとめました。1. Gemfileファイルを編集する
Gemfilegem 'carrierwave' gem 'mini_magick'ターミナル% bundle install2. アップローダーを作成する
ターミナルrails g uploader image実行後、app/uploaders 下に image_uploader.rbが作成されます。
3. アップローダーをマウントする
app/models/message.rbclass Message < ApplicationRecord belongs_to :group belongs_to :user belongs_to :heven validates :content, presence: true, unless: :image? mount_uploader :image, ImageUploader ⬅️ この1行 end4. 画像のリサイズを可能にする
include CarrierWave::MiniMagick のコメントアウトを外し、
任意の行にprocess resize_to_fit: [800, 800]と追記。
これにより、縦横比を維持したまま、縦横を800px以内にリサイズ可能になります。app/uploaders/image_uploader.rbclass ImageUploader < CarrierWave::Uploader::Base # Include RMagick or MiniMagick support: # include CarrierWave::RMagick include CarrierWave::MiniMagick ⬅️ 有効化 # 〜省略〜 process resize_to_fit: [600, 600] ⬅️ 追記 # 〜省略〜 end
以上で画像のアップロードの準備ができました。
ご覧いただきありがとうございました。
- 投稿日:2020-05-21T19:28:05+09:00
Ruby 技術者認定試験 Silver に合格しました
はじめに
2020-05-21 に Ruby技術者認定試験 Silver に合格しました。
この記事が受験を考えている方の参考になれば幸いです。勉強方法
勉強は次の3つを行いました。
- 試験対策本
- 模擬試験
- AtCoder
試験対策本
試験対策本は次の本を使用しました。
Ruby技術者認定試験合格教本 Silver/Gold対応 Ruby公式資格教科書
購入:4月中旬改訂2版も出ていますが、こちらも
v2.1
に対応していますので問題ないと思います。中古価格が安い
気になる方は正誤表のダウンロードをお勧めします。
サポートページ
私自身は、分からないところや気になったところを辞書的に引いたくらいなので、正誤表をダウンロードしましたが見比べなどはしなかったと思います。使用頻度:中
模擬試験
模擬試験問題は次のページを使用しました。
+ REx - Ruby Examination
+ DIVE INTO EXAM
+ 模擬問題(Silver試験用)上の2つは繰返し解くことができますので、学習効果が高いと思います。
最初は、試験対策本を見ながら若しくはVScode等で実際にコードを実行しながらで構わないと思います。
Ruby AtCoder向けVSCode設定問題を覚えすぎない程度の回数でいいと思います。
使用頻度:高
AtCoder
私自身は、繰返し実行して覚えるタイプの人間ですので、AtCoder さんの問題を解くことでかなり勉強させていただきました。
9月末に Java でスタートし、2020年頃から Perl に切り替え、更に4月頃に もっとプログラマ脳を鍛える数学パズル を読んでから Ruby に切り替えと Ruby 歴は浅いです。
しかし、灰色diff問題を解くことで文法を覚え、茶色diff問題を解くことで String/Array/Hashクラス等のメソッドを覚えました。
AtCoder 茶diff 一覧使用頻度:特高
まとめ
試験勉強に一番のお薦めは、AtCoder さんです。
AtCoder Problems さんを併用して活用することにより学習の進捗を確認しながら勉強を進めることができます。但し、使用するクラス・メソッドの幅が狭くなる(例えば、
key?
を使用する人はinclude?
has_key?
member?
を覚えない、ヒアドキュメントって何?美味しいの)と思われますので、模擬試験サイトや試験対策本で補う必要はあると思います。また、Qiita に投稿されている先輩諸氏の記事も参考になりましたので、一読をお勧めします。
最後に、投稿した記事にコメントをいただいた皆様に感謝を申し上げます。
ruby.rbbegin print "Happy Programming\n".chomp end
- 投稿日:2020-05-21T17:04:43+09:00
Rails 基礎
current_userメソッド
deviseでログイン機能を実装すると使えるようになるメソッド。
idが1のレコードの場合、User.find(1)と同じ意味を持ちます。
current_user.name
などで値を取得できます。ルーティングでユーザーごとに異なるページを表示するには普通とは違う記述方法を使います。
routes.rbget 'users/:id' => 'users#show'whereメソッド
Active Recordの1つ
モデル.where(条件)
で引数にとった条件に一致したレコードのインスタンスを配列型で取得できます。
条件を連続で記述すれば複数の条件にあったレコードを取得できます。Sample.where('id < 3').where('user_id: 1')アソシエーション
モデル間の関係を定義することで、モデルを跨いだデータの呼び出しが簡単になります。
- 投稿日:2020-05-21T16:54:29+09:00
AtCoderでRuby学習9【第一回アルゴリズム実技検定 3番目】配列要素の並び替え
はじめに
Ruby学習の一環として「アルゴリズム実技検定」に挑戦します。
そのための学習の中で学んだことをアウトプットしていきます。
今回は「第一回アルゴリズム実技検定」の三問目(3番目)より。
第一回アルゴリズム実技検定 過去問自分の解答と、解答する中で学んだ表現・メソッドなどを紹介していきます。
問題
6つの相異なる整数 A, B, C, D, E, Fが与えられる。
このうち 3番目に大きい数を調べるプログラムを作成せよ。制約
・1≦A,B,C,D,E,F≦100
・A,B,C,D,E,Fは全て異なる
・入力中の値はすべて整数である。入力は以下の形で与えられる。
A B C D E F 入力例 4 18 25 20 9 13出力例 => 13解答
まずは僕が提出した解答から。
ary = gets.split(" ").map(&:to_i) r_ary = ary.sort print r_ary[3]入力される文字列を整数として配列で受け取り、
sortメソッドを使って並び替え、3番目に大きな整数を出力しています。ここからは今回初めて使用したsortメソッドについてまとめていきます。
sortメソッド
配列の内容をソート(並び替え)をします。
要素同士の比較は <=> 演算子を使って行い、sort はソートされた配列を生成して返します。文字列の並び替え
文字列が入った配列に対してソートすると、「a,b,c...」や「あ、い、う…」といった順番に並び替えをしてくれます。
ary1 = [ "d", "a", "e", "c", "b" ] p ary1.sort #=> ["a", "b", "c", "d", "e"]数字が文字列の要素として配列に入っている場合は、以下のような感じ。
ary2 = ["9", "7", "10", "11", "8"] p ary2.sort #=> ["10", "11", "7", "8", "9"]整数の並び替え
初めから整数の要素として配列に入っている場合は、解答のように簡潔に書けますが、
文字列として配列に入っている場合は、ブロック{}を使って以下のようにします。ary2 = ["9", "7", "10", "11", "8"] p ary2.sort{|a, b| a.to_i <=> b.to_i } #=> ["7", "8", "9", "10", "11"]ただ、ブロックの中で比較を行うためにto_iメソッドを使って整数に変換しているのであって、
生成された配列では文字列に戻っているところに注意したいです。これと同じことがsort_byメソッドでも行えます。
ary2 = ["9", "7", "10", "11", "8"] p ary2.sort_by{|a| a.to_i} #=> ["7", "8", "9", "10", "11"]最後に
以上、「第一回アルゴリズム実技検定」の三問目(3番目)を解く中で学んだソートについてまとめました。
もし間違いなどございましたら、ご指摘いただけると嬉しいです。
- 投稿日:2020-05-21T16:54:29+09:00
AtCoderでRuby学習9【第一回アルゴリズム実技検定 3番目 】配列要素の並び替え
はじめに
Ruby学習の一環として「アルゴリズム実技検定」に挑戦します。
そのための学習の中で学んだことをアウトプットしていきます。
今回は「第一回アルゴリズム実技検定」の三問目(3番目)より。
第一回アルゴリズム実技検定 過去問自分の解答と、解答する中で学んだ表現・メソッドなどを紹介していきます。
問題
6つの相異なる整数 A, B, C, D, E, Fが与えられる。
このうち 3番目に大きい数を調べるプログラムを作成せよ。制約
・1≦A,B,C,D,E,F≦100
・A,B,C,D,E,Fは全て異なる
・入力中の値はすべて整数である。入力は以下の形で与えられる。
A B C D E F 入力例 4 18 25 20 9 13出力例 => 13解答
まずは僕が提出した解答から。
ary = gets.split(" ").map(&:to_i) r_ary = ary.sort print r_ary[3]入力される文字列を整数として配列で受け取り、
sortメソッドを使って並び替え、3番目に大きな整数を出力しています。ここからは今回初めて使用したsortメソッドについてまとめていきます。
sortメソッド
配列の内容をソート(並び替え)をします。
要素同士の比較は <=> 演算子を使って行い、sort はソートされた配列を生成して返します。文字列の並び替え
文字列が入った配列に対してソートすると、「a,b,c...」や「あ、い、う…」といった順番に並び替えをしてくれます。
ary1 = [ "d", "a", "e", "c", "b" ] p ary1.sort #=> ["a", "b", "c", "d", "e"]数字が文字列の要素として配列に入っている場合は、以下のような感じ。
ary2 = ["9", "7", "10", "11", "8"] p ary2.sort #=> ["10", "11", "7", "8", "9"]整数の並び替え
初めから整数の要素として配列に入っている場合は、解答のように簡潔に書けますが、
文字列として配列に入っている場合は、ブロック{}を使って以下のようにします。ary2 = ["9", "7", "10", "11", "8"] p ary2.sort{|a, b| a.to_i <=> b.to_i } #=> ["7", "8", "9", "10", "11"]ただ、ブロックの中で比較を行うためにto_iメソッドを使って整数に変換しているのであって、
生成された配列では文字列に戻っているところに注意したいです。これと同じことがsort_byメソッドでも行えます。
ary2 = ["9", "7", "10", "11", "8"] p ary2.sort_by{|a| a.to_i} #=> ["7", "8", "9", "10", "11"]最後に
以上、「第一回アルゴリズム実技検定」の三問目(3番目)を解く中で学んだソートについてまとめました。
もし間違いなどございましたら、ご指摘いただけると嬉しいです。
- 投稿日:2020-05-21T16:13:47+09:00
Rails5でherokuにデプロイ後にWebサイトの画像が表示されない問題の解決方法
自作のWebサービスで画像がHerokuにデプロイ後に読み込まれなかった問題を解決したので方法を紹介していきます。
環境
・Rails 5.2.2
・Ruby 2.5.3
・Amazon Web Service
・Windows 10
問題点
Herokuにデプロイ後にWebサイトの画像が読み込まれないこと
実現したい事
Webページの画像を表示したい
手順
①
config/environments
の中にあるproduction.rb
ファイルを開く
production.rb
ファイルのコードを修正する。修正前
production.rb# Do not fallback to assets pipeline if a precompiled asset is missed. config.assets.compile = false修正後
production.rb# Do not fallback to assets pipeline if a precompiled asset is missed. config.assets.compile = true修正後のproduction.rbの全体のコード
production.rbRails.application.configure do # Settings specified here will take precedence over those in config/application.rb. # Code is not reloaded between requests. config.cache_classes = true # Eager load code on boot. This eager loads most of Rails and # your application in memory, allowing both threaded web servers # and those relying on copy on write to perform better. # Rake tasks automatically ignore this option for performance. config.eager_load = true # Full error reports are disabled and caching is turned on. config.consider_all_requests_local = false config.action_controller.perform_caching = true # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"] # or in config/master.key. This key is used to decrypt credentials (and other encrypted files). # config.require_master_key = true # Disable serving static files from the `/public` folder by default since # Apache or NGINX already handles this. config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? # Compress JavaScripts and CSS. config.assets.js_compressor = :uglifier # config.assets.css_compressor = :sass # Do not fallback to assets pipeline if a precompiled asset is missed. config.assets.compile = true # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb # Enable serving of images, stylesheets, and JavaScripts from an asset server. # config.action_controller.asset_host = 'http://assets.example.com' # Specifies the header that your server uses for sending files. # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX # Store uploaded files on the local file system (see config/storage.yml for options) config.active_storage.service = :local # Mount Action Cable outside main process or domain # config.action_cable.mount_path = nil # config.action_cable.url = 'wss://example.com/cable' # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ] # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. # config.force_ssl = true # Use the lowest log level to ensure availability of diagnostic information # when problems arise. config.log_level = :debug # Prepend all log lines with the following tags. config.log_tags = [ :request_id ] # Use a different cache store in production. # config.cache_store = :mem_cache_store # Use a real queuing backend for Active Job (and separate queues per environment) # config.active_job.queue_adapter = :resque # config.active_job.queue_name_prefix = "scheduleapplication_#{Rails.env}" config.action_mailer.perform_caching = false # Ignore bad email addresses and do not raise email delivery errors. # Set this to true and configure the email server for immediate delivery to raise delivery errors. # config.action_mailer.raise_delivery_errors = false # Enable locale fallbacks for I18n (makes lookups for any locale fall back to # the I18n.default_locale when a translation cannot be found). config.i18n.fallbacks = true # Send deprecation notices to registered listeners. config.active_support.deprecation = :notify # Use default logging formatter so that PID and timestamp are not suppressed. config.log_formatter = ::Logger::Formatter.new # Use a different logger for distributed setups. # require 'syslog/logger' # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') if ENV["RAILS_LOG_TO_STDOUT"].present? logger = ActiveSupport::Logger.new(STDOUT) logger.formatter = config.log_formatter config.logger = ActiveSupport::TaggedLogging.new(logger) end # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false end参考サイト・記事
・アセットパイプライン Railsガイド Version6.0
・Rails4 asset pipeline関連設定まとめ
- 投稿日:2020-05-21T16:10:51+09:00
Rubyで「角度」や「座標」を扱う際に必要な、最低限の知識 + Aさんから見てB君はどの方向にいる?のアルゴリズム
先日Rubyで座標や角度を扱う機会があったので、それらを扱う上で必要となる全知識をコンパクトにして、丁寧にまとめてみました。
後半には例として「Aさんから見て、B君はどの方角にいるか」みたいなのを8方位単位で調べられる簡単なコードを載せています。参考になれば幸いです。(バージョン:ruby 2.5.1)角度には、よく使われる2つの単位がある
長さを表す単位にも「メートル」や「フィート」等、規格の異なる表し方があるように、角度にも複数の表し方があります。私達が角度を表す際、一般的によく使うのは90°(90度)みたいな感じですよね。しかしRubyが用意しているモジュール上では、ラジアン(rad)という単位が用いられています。
度( ° )の考え方
この単位は、1周を360°としています。なので、例えば「右(or左)に360°回転」すると、元と全く同じ方向に戻ることが出来ます。
ラジアン( rad )の考え方
この単位は、1周を2×π rad としています。なので、例えば「右(or左)に2×π rad 回転」すると、元と全く同じ方向に戻ることが出来ます。(π = 円周率 ≒ 3.14)
私のように学生の頃の記憶を失ってしまった方のために申し上げると、πというのは、円の直径に対して円周の長さがどれくらいあるか?の比率であり、その比率は約3.14倍と決まっています。円の直径が1cmだとしたら、その円の円周は 1×π cm 、つまり約3.14cmになります。
π(円周率)の詳細についてはコチラよって
以下のように度(°)をラジアン(rad)に変換することが出来ます。
0° = 0 × π = 0.00000… rad
45° = (2 × π) ÷ 8 = 0.78539… rad (45°は、"2×π"の8等分)
90° = (2 × π) ÷ 4 = 1.57079… rad (90°は、"2×π"の4等分)
180° = (2 × π) ÷ 2 = 3.14159… rad (180°は、"2×π"の2等分)
270° = (2 × π) ÷ 4 × 3 = 4.71238… rad (270°は、"2×π"の3/4)
360° = (2 × π) = 6.28318… rad (360°は、"2×π")少々回りくどい説明になってしまいましたが、180(°) = π (rad) という基準を抑えておけば覚えやすいですね。
Rubyの世界では π = 「 Math::PI 」
ここでひとつRubyの必須知識を抑えましょう。π(≒3.14)をコード上で表現するには、「Math」というモジュールの助けを借りる必要があります。
モジュールを呼び出す方法は、コード上部にてinclude Math
を表記します。モジュールを呼び出しておけば、PI
と表記するだけで、πを表現することが出来ます。include Math puts PI # 出力結果:: 3.141592653589793ファイル全体ではなく単発でモジュールを呼び出したいときは、以下の方法で呼び出します(include Math不要バージョン)。
puts Math::PI # 出力結果:: 3.141592653589793参考… 以下リンクでも、度(°)⇔ラジアン(rad)の相互変換方法について紹介されてます。
「ラジアンと度の変換をするRubyコード」by @niwasawa さん座標から角度を求める「 Math::atan2 」の使い方
上記のようにx軸とy軸が用意されている中で、座標(xとyの値)が与えられていれば、前述のMathモジュールが用意している別の関数
atan2
を利用して、角度(rad)を求めることができます。include Math def radian(x, y) return atan2(y, x) # 引数xと引数yの順序が逆なことに注意 end puts radian(5, 3) # 出力結果:: 0.5404195002705842これだとあまり馴染みのないラジアン(rad)による出力結果なので、以下では度(°)に変換すべく「÷ π × 180」をメソッド内に追記し、最後に四捨五入もしてみます。
include Math def degree(x, y) return atan2(y, x)/PI*180 end puts degree(5, 3).round # 出力結果:: 31無事に、31度という角度を求めることが出来ました。
Aさんから見て、B君はどの方角にいるか?
上の図のようにAさんの座標とB君の座標を与えられた場合に、8方位上どの方角にいるかをアンサー出来るよう、コードを作ってみます。ついでに、2人の間の距離も図ってみたいと思います。(距離の単位: m とします)
仕様
Aさんの座標(x, y)と、B君の座標(x, y)を入力
↓
Aさんから見てB君がいる方角と、距離を出力する入力Aさんの座標(x, y)を、半角数字で2つ、間に半角スペースを入れて入力してください Aさんの座標は? ◯ ◯ ←ココに入力 B君の座標(x, y)を、半角数字で2つ、間に半角スペースを入れて入力してください B君の座標は? ◯ ◯ ←ココに入力
出力B君はAさんから見て◆◆の方向にいて、▲▲m離れています。
例外処理二人は同じ場所にいます。
ポイント1 Aさんを起点(中心)にして考える
以下イメージのように、"Aさんから見て"どの方向にいるのかを調べる為には、Aさんを起点(中心)にして考えます。
この場合だとAさんを中心に持っていく為にはAさんをx方向に-3m、y方向に+2m移動させればOKなので、同じくB君にも同距離を移動してもらいます。A(3, -2) xを-3、yを+2する → A(0, 0) = 中心にこれました!
同様に…
B(-2, -4) xを-3、yを+2する → B(-5, -2) この座標の方角をMath::atan2
で調べればOK!ポイント2
Math::atan2
の返り値の範囲今回は全方位を調べます。
atan2
の活用によって、0°〜360°の間の値が得られることを期待しましたが、実はatan2
が返してくる値の範囲は -π 〜 π (度数でいうと-180°〜180°)と決まっています。時計の針でいう「3時〜9時の間」の場合だと、マイナスの値が帰ってきちゃう…ということですね。この仕様に合わせてアルゴリズムを組んでも問題は無いのですが、勉強の為、得られた角度値をこちらの都合の良い値に変換する方法をとってみたいと思います。
参考:「Rubyで角度を(0〜359度の)正の角度に変換する」by @masassiez さん# -180 〜 180 の間にある値を、 0 〜 360 の間の値に変換する方法(-120を例にした場合) (-120).modulo(360) # もしくは -120 % 360 # これにより、240 に変換される上記の
%
もmodulo
も、やっていることは全く同じです。360で割った際の剰余(あまり)を求めることで、自動的に 0〜360 の範囲内に変換されることになります。(ちなみにmoduloは、include Mathしなくても使えます)ポイント3 距離は三平方の定理を用いる
2点間A(x, y)とB(x, y)の距離を求める方法は、三平方の定理を使いましょう。
AB= \sqrt{(x_b−x_a)^2+(y_b−y_a)^2}これをRubyでやると、以下みたいになります。
def distance(a_x, a_y, b_x, b_y) return ((b_x - a_x)**2 + (b_y - a_y)**2)**(1/2.0) end # **2 ← 2乗しています # **(1/2.0) ← ルート(平方根)しています完成コード
sampl.rb(完成)# 今回は atan2 や PI を使いたいので、最初に include Math を宣言します include Math # 角度を求めるメソッド def degree(x, y) (atan2(y, x)/PI*180)%360 end # 方角を求めるメソッド def compass(degree) if degree > 15 && degree < 75 "北東" elsif degree >= 75 && degree <= 105 "北" elsif degree > 105 && degree < 165 "北西" elsif degree >= 165 && degree <= 195 "西" elsif degree > 195 && degree < 255 "南西" elsif degree >= 255 && degree <= 285 "南" elsif degree > 285 && degree < 345 "南東" else "東" end end # 2点間の距離を求めるメソッド def distance(a_x, a_y, b_x, b_y) ((b_x - a_x)**2 + (b_y - a_y)**2)**(1/2.0) end puts "Aさんの座標(x, y)を、半角数字で2つ、間に半角スペースを入れて入力してください" print "Aさんの座標は? " a_x, a_y = gets.split.map(&:to_i) puts "Bさんの座標(x, y)を、半角数字で2つ、間に半角スペースを入れて入力してください" print "Bさんの座標は? " b_x, b_y = gets.split.map(&:to_i) if a_x == b_x && a_y == b_y puts "二人は同じ場所にいます。" exit end direction = compass(degree(b_x - a_x, b_y - a_y)) distance = distance(a_x, a_y, b_x, b_y).round(1) puts "B君はAさんから見て#{direction}の方向にいて、#{distance}m離れています。" # 2メートル以内は、密です distance > 2 ? (puts "ソーシャルディスタンスが保たれています。") : (puts "密です!")出力結果
Aさん(3,-2)、B君(-2,-4)の場合Aさんの座標(x, y)を、半角数字で2つ、間に半角スペースを入れて入力してください Aさんの座標は? 3 -2 Bさんの座標(x, y)を、半角数字で2つ、間に半角スペースを入れて入力してください Bさんの座標は? -2 -4 ↓ 結果 ↓ B君はAさんから見て南西の方向にいて、5.4m離れています。 ソーシャルディスタンスが保たれています。
Aさん(-1,-7)、B君(1,-7)の場合Aさんの座標(x, y)を、半角数字で2つ、間に半角スペースを入れて入力してください Aさんの座標は? -1 -7 Bさんの座標(x, y)を、半角数字で2つ、間に半角スペースを入れて入力してください Bさんの座標は? 1 -7 ↓ 結果 ↓ B君はAさんから見て東の方向にいて、2.0m離れています。 密です!
Aさん(4,3)、B君(4,3)の場合Aさんの座標(x, y)を、半角数字で2つ、間に半角スペースを入れて入力してください Aさんの座標は? 4 3 Bさんの座標(x, y)を、半角数字で2つ、間に半角スペースを入れて入力してください Bさんの座標は? 4 3 ↓ 結果 ↓ 二人は同じ場所にいます。
以上、「Rubyで「角度」や「座標」を扱う際に必要な、最低限の知識 + Aさんから見てB君はどの方向にいる?のアルゴリズム」でした。ご覧いただき、ありがとうございました!
- 投稿日:2020-05-21T16:08:37+09:00
RSpecとFactoryBotを利用してRailsアプリの単体テストを実施してみた
概要
ポートフォリオとして作成した個人開発アプリのテストを実施したので
個人的なアウトプットとしてテストの流れを振り返りたいと思います。
今回はモデルのバリデーションに関するテストの基礎的な内容になります。前提
プログラミングにおけるテストとは、「プログラムが意図した通りに動くことを確かめる」ことを指します。
環境
Ruby 2.5.1
Rails 5.2.3gem 'devise'を使用してユーザーモデル作成済み
はじめに
まずはテストに使用するGemをインストールしていきます。
今回使用するGem
- rspec-rails ▶︎RSpecというテストに特化した言語のRails用gem
- factory_bot ▶︎簡単にダミーのインスタンスを作成できるgem
Gemfilegroup :development, :test do 省略 gem 'factory_bot_rails' gem 'rspec-rails' endターミナル$ bundle installこれでgemのインストールが完了。
RSpecの設定をする
まずはRSpec用のファイルを生成する必要があるので下記のコマンドを実行する。
ターミナル$ rails g rspec:installこれで下記のファイルが生成される。
ターミナルcreate .rspec create spec create spec/spec_helper.rb create spec/rails_helper.rb.rspecに以下の記述を追加する
.rspec--format documentation
ここまでくれば下記のコマンドでテストは実行できます。ターミナル$ bundle exec rspecモデルクラスのテストコードを書く
いよいよテストコードを書いていくわけですが
テストコードを書くspecファイルは途中で生成されたspecという名前のディレクトリに配置します。
また、モデルのspecファイルはモデル用のディレクトリにまとめておくため、テキストエディタでディレクトリとファイルを作成していきましょう。
- specディレクトリの配下にmodelsというディレクトリを作成する。
- spec/modelsディレクトリの中にモデル用specファイルを作成する。
※specファイルの命名規則はspecファイルは、対応するクラス名_spec.rbという名前になります。
今回はUserモデルのバリデーションに関するテストを実施するという想定で進めていくのでuser_spec.rbを作成します。
まずは新規ユーザー登録時の各バリデーションが適用されるか、一つずつテストしていきます。
今回、Userモデルのバリデーションは以下の条件です。app/models/user.rbclass User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable validates :nickname, :email, :password, :password_confirmation, presence: true endvalidatesのpresence: trueが適用されている4カラムをテストしていきます。
まずは基本となる記述でnicknameのバリデーションをテストします。
spec/models/user_spec.rbrequire 'rails_helper' describe User do describe '#create' do it "nicknameがない場合は登録できないこと" do user = User.new(nickname: "", email: "test-account@gmail.com", password: "1234567", password_confirmation: "1234567") user.valid? expect(user.errors[:nickname]).to include("can't be blank") end end end1行目はテストする上で読み込むファイルを記載。
2行目はモデルクラスを記載。
3行目はテストするアクション名を記載。4~8行目のitからendの括りが一つあたりのテストコードになります。
4行目はテストする内容を記載。
5行目はインスタンスの作成を記載するのですが、nicknameが空という事以外はリアルな想定で記載。
6行目は作成したインスタンスに大してvalid?メソッドを記載すると、ActiveRecord::Baseを継承しているクラスのインスタンスを保存する際に「バリデーションにより保存ができない状態であるか」を確かめることができます。
7行目は6行目の内容に対して予想されるテスト結果を記載します。
valid?メソッドの返り値はtrue or falseですが、valid?メソッドを利用したインスタンスに対してerrorsメソッドを利用すると、バリデーションにより保存ができない状態である場合なぜできないのかを確認することができます。
今回の場合、to以下のincludeマッチャを利用して「"can't be blank"というエラーメッセージが出るだろう」という予想をします。ザックリ日本語で言うと
「ユーザーのニックネームが空だから、"空にはできませんよ"というエラーが返ってくるだろうと予想を書く」
といった感じです一旦ここでテストを実行してみましょう
ターミナル$ bundle exec rspec 1 example, 0 failures上の表示のように、"1つのテストに対して失敗が0"というメッセージが表示されればOKです。
あとは他のバリデーションもテストしていくのですが、
最初に導入したfactory_botを使用することでuserインスタンス作成部分のテストコードを共通化できるので、かなり便利です。factory_botを使用する
まずはspecディレクトリ配下にfactoriesというディレクトリを作成しましょう。
その中にusers.rbというファイルを作成します。
※ファイルの命名はモデル名複数形で統一そして空のファイルにモデルのインスタンス作成で共通となる部分を記述していきます。
spec/factories/users.rbFactoryBot.define do factory :user do nickname {"田中太郎"} email {"test-account@gmail.com"} password {"1234567"} password_confirmation {"1234567"} end end特に説明することもありませんが
テストコードでユーザーモデルのインスタンスを作成すると記載した内容で毎回実行してくれます。#これが user = User.new(nickname: "田中太郎", email: "test-account@gmail.com", password: "1234567", password_confirmation: "1234567") #これで実現できる user = FactoryBot.build(:user)なんとさらにこのコードを簡略化できます。
user_spec.rbの中に'rails_helper'を読み込む記述がしてありますが、
このrails_helper.rbファイルの中に少し手を加えます。spec/rails_helper.rb#省略 RSpec.configure do |config| #下記の記述を追加 config.include FactoryBot::Syntax::Methods #省略 endこれで準備は完了です。
そうするとですね...。#これが user = User.new(nickname: "田中太郎", email: "test-account@gmail.com", password: "1234567", password_confirmation: "1234567") #これで実現できる user = FactoryBot.build(:user) #さらに省略できる user = build(:user)かなりコード量が減りますね...。
自分は最初これを知ったとき、全部のカラムに値を入れてるけど、バリデーションのテストする上で空のカラムとか再現できるの?
という疑問がありました➡︎問題なくできます残りのテストコードで見ていきましょう。
spec/models/user_spec.rbrequire 'rails_helper' describe User do describe '#create' do it " nicknameがない場合は登録できないこと" do user = build(:user, nickname: "") user.valid? expect(user.errors[:nickname]).to include("can't be blank") end it "emailがない場合は登録できないこと" do user = build(:user, email: "") user.valid? expect(user.errors[:email]).to include("can't be blank") end it "passwordがない場合は登録できないこと" do user = build(:user, password: "") user.valid? expect(user.errors[:password]).to include("can't be blank") end it "passwordが存在してもpassword_confirmationがない場合は登録できないこと" do user = build(:user, password_confirmation: "") user.valid? expect(user.errors[:password_confirmation]).to include("doesn't match Password") end it " passwordが5文字以下であれば登録できないこと " do user = build(:user, password: "00000", password_confirmation: "00000") user.valid? expect(user.errors[:password]).to include("is too short (minimum is 6 characters)") end #登録ができる場合のテストも実施 it "nicknameとemail、passwordとpassword_confirmationが存在すれば登録できること" do user = build(:user) expect(user).to be_valid end it " passwordが6文字以上であれば登録できること " do user = build(:user, password: "000000", password_confirmation: "000000") user.valid? expect(user).to be_valid end end end上記の解説です
user = build(:user) user = build(:user, nickname: "")2行目のように再度カラム名と値を指定することで
事前にセットした値を上書きできます。
この例の場合はnickname: "田中一郎" をnickname: "" に上書きしています。
こうすることで事前にセットした値を柔軟に変えることができます(nilでも可)
it "passwordが存在してもpassword_confirmationがない場合は登録できないこと" do user = build(:user, password_confirmation: "") user.valid? expect(user.errors[:password_confirmation]).to include("doesn't match Password") endまた、上記のincludeマッチャ部分ですが
"can't be blank"もそうだけど
"doesn't match Password"っていうエラーメッセージは
どこから来たの?
それっぽいことを書こうとは思うんだけど
最初からわからないとエラーメッセージの予想とかできなくね...?そう思っていた時期が私にもありました(注:まだ初学者です)
これらのエラーメッセージはRailsのGemで元々用意されているモノですが
極論、これでもテストは実行できます.to include("")そうすると、テストの実行結果がターミナルに表示されるわけですが
あなたは、""というエラーメッセージが出ると予想していたけど実際出たエラーメッセージは"doesn't match Password"だったわよ!
と返ってきます。
そうすると、
ああ!そうそう!ワイがテストで書きたかったのはそういうことなんや!
と、わかるわけですねコンソールを開いて流れを検証して確認するということもできますが
初学者レベルで個人開発アプリのテスト量が少ない場合はこの方法で十分な気がします。
(怒られそう)また、最後の2つのテストはユーザー登録ができる場合のテストをしているわけですが
be_validマッチャというのが出てきます。
これは"全てのバリデーションをクリアするだろう"という場合に使用します。最後にテストを実行してみて
ターミナル$ bundle exec rspec 7 example, 0 failuresテストの数に対して失敗が0ならOKです。
まとめ
RSpecとFactoryBotを利用して、Railsの簡単なモデルテストを振り返ってみました。
今回実施したテストはほんの一部ですが、基本的な流れと小ネタを書いたので学習初めてまもない方の一助となりましたら幸いです。
また、記載している内容で不備等ございましたら教えていただけると助かります。
最後に私の学習中に参考にさせていただいたQiita記事を記載しておきます。
ありがとうございました。参考記事
- 投稿日:2020-05-21T15:05:15+09:00
【学習記録】Rubyで現在時間を取得して、時間毎に違う挨拶文を出力してみた。
はじめに
ProgateでRubyの学習を始めて約1か月。インプット過多になり始めていたので、
初めてテーマを決めてプチ成果物を作ってみました。
記事投稿練習を兼ねて投稿します!
所要時間は3時間ほどかかりました。。簡単な流れとしては、
現在時間を取得 → 出力を変えたい時間をグループ分け → if文で挨拶文を出力
といった感じです。time = Time.nowまず現在時間を取得します。
require "time" # morning = m m1 = Time.parse("6:00:00") m2 = Time.parse("10:59:59") # afternoon = a a1 = Time.parse("11:00:00") a2 = Time.parse("16:59:59") # evening = e e1 = Time.parse("17:00:00") e2 = Time.parse("1:59:59") #上記以外の時間帯は(2:00:00 ~ 5:59:59) zzz...で出力if文で現在時刻と指定時刻を比較したいので、朝・昼・夜でそれぞれ時間指定をします。
この時、Time.parse("時:分:秒")とすることで、ただの文字列からTimeオブジェクトに変換しています。
詳しくは下記に参考文献を載せていますのでご覧ください。if m1 <= time && time <= m2 puts "おはようございます" elsif a1= time && time <= a2 puts "こんにちは" elsif time <= e2 || e1 <= time puts "こんばんは" else puts "Zzz..."グループ分けした指定時刻と、現在時刻を比較して挨拶文を出力します。
少しわかりにくいですが、朝(6:00:00)~(10:59:59)の時間帯→ おはようございます
昼(11:00:00)~(16:59:59)の時間帯→ こんにちは
夜(17:00:00)~(1:59:59)の時間帯→ こんばんは
その他(2:00:00 ~ 5:59:59)の時間帯→ zzz...と出力されます。
感想(主につまづいたところ)
- 現在の"時間"のみの取得
- 指定時刻を文字列から変換
- if文の作成(時間軸の関係で最後のelsifだけ"または"になる)
参考文献
- 投稿日:2020-05-21T14:42:01+09:00
Ruby on rails を初心者向けに解説④ ~命名規則とform_Tagの使い方について~
はじめに
今回は前回の記事の続きになります。
よろしければ以前の記事も御覧ください。
Ruby on rails を初心者向けに解説①
Ruby on rails を初心者向けに解説② ~リンクの作成~
Ruby on rails を初心者向けに解説③ ~データベースの作成~Railsの命名規則について
ここまで、コントローラーやモデルを作成してきました。
それらには、命名規則があります。学んでいきましょう。
Modelの命名規則
モデルとは、データベースを作成するための設計図です。
設計図は一つであるため、モデルクラス名は
単数形
で作成します。テーブルは、そのモデルのデータが複数あるため、自動的に
複数形
で表されます。前回の記事で
user
という名前でモデルを作成しました。そうすると、
users
という名前でテーブルが作成されます。また、クラス名は
User
というふうに、最初が大文字になります。Viewの命名規則
Viewフォルダは配下に複数のファイルを持つため、
複数形
になります。Controllerの命名規則
Controllerは複数のアクションを持つため、
複数形
で作成します。データベースにデータを登録
以前の記事では、railsのコンソールを使用してデータベースにデータを登録しました。
今回は、ブラウザをユーザーに操作してもらうことでデータベースにデータを登録しましょう。
その前に、一度データベースの確認を行います。
ターミナルに以下のコマンドを打ち込みましょう。
rails dbconsole次のコードでカラム名の表示をONにできます。
sqlite> .headers onこの状態で、次のSQLの文を書くと中身を確認することができます。
sqlite> select * from users; id|name|password|created_at|updated_at 1|poco|maru|2020-05-20 10:50:13.177731|2020-05-20 10:50:13.177731現在は、usersテーブルにnameカラムとpaswordカラムが格納されていることが分かりますね。
それでは、入力フォームを作成してユーザーから送られてくるデータをデータベースに格納してみましょう。
/users/new.html.erbファイルに以下のコードを書いてください。
new.html.erb<%= form_tag("/users/create") do %> <p>ユーザー名</p> <input name="name"> <p>password</p> <input name="password"> <input type="submit" value="送信"> <% end %>
form_tag
は、viewファイルからコントローラーに何か値を送ったり、削除したりするときに使います。いわゆるPOSTリクエスト
と呼ばれるものです。getリクエストとpostリクエストの違いについては、こちらの記事を参考にしてください。
type="submit"
となっているボタンがユーザーから送られると、users/create
に対応するpostリクエストが実行されます。今回は、以下のようにルーティングしています。
routes.rbpost "users/create" => "users#create"つまり、上記のデータはusersコントローラーのcreateアクションに送信されます。createアクションでは以下のコードを書きます。
users_controller.rbdef create user = User.new(name: params[:name], password: params[:password]) user.save endこのコードで、userモデルのUserクラスを用いて、データベースのusersテーブルにデータを格納しています。
form_tagで送られてきたデータにおいて、name属性が指定されているタグが存在した場合、コントローラー内において
params[name属性]
として値を扱うことができます。この場合、
<input name="name">
内の値がparams[:name]
に、<input name="password">
の値がparams[:password]に格納されます。その送られてきたデータに対して
User.new(name: params[:name], password: params[:password])
を用いることでモデルを作成し、データベースに格納しています。ユーザーからは以下のようになっています。
この状態で
送信
を押してみましょう。すると、usersコントローラーのcreateアクション内において、thisという文字列がparams[:name]に格納され、testという文字列がparams[:password]に格納されます。以下のようにデータを格納することができました。
3|this|test|2020-05-21 05:30:36.718523|2020-05-21 05:30:36.718523
しかし、このままだと送信を押しても特に変化はありません。退屈なので、他のファイルにリダイレクトさせましょう。
送信を押した場合にリダイレクト
送信を押すとusersコントローラーのcreateアクションが実行されるので、このcreateアクション内にリダイレクトのコードを書けば、他のファイルにリダイレクトされるようになります。
usersコントローラーに以下のようにコードを追記しましょう。
users_controller.rbdef create user = User.new(name: params[:name], password: params[:password]) user.save redirect_to("/users/index") endこのように書くと、送信を押した場合に
/users/index
に対応するファイルにリダイレクトされます。ちなみに、リダイレクトを書く場合は、パスの書き始めに
/
を入れることを忘れないようにしてください。終わりに
今回の記事はここまでになります。
お疲れさまでした。
- 投稿日:2020-05-21T13:29:44+09:00
google-api-ruby-clientを0.8.3からバージョンアップ
障害対応時にgoogle-api-ruby-clientをバージョンアップして解決できたのでメモしておく。
2020/5/11-12の間を境にGoogle Custom Search APIの呼び出しが失敗するようになったので調査。
Rubyのバージョン
ruby 2.2.0p0 (2014-12-25 revision 49005) [x86_64-linux]google-api-clientのバージョン
google-api-client (0.8.3)APIサーバー側で問題になっていそうな箇所を抜き出して
検証用コードを作成#!/usr/bin/env ruby require 'google/api_client' API_KEY = 'XXXXX' CSE_ID = 'xxxxx' # カスタム検索エンジンID def google_api_client client ||= Google::APIClient.new.tap do |cli| cli.authorization = nil end end def custom_search_api api ||= google_api_client.discovered_api('customsearch', 'v1') end query = { num: 3, start: 1, total_num: 25, q: '検索ワード', cx: CSE_ID } json = google_api_client.execute( api_method: custom_search_api.cse.list, key: API_KEY, parameters: query ).body puts json実行結果。404が返っている。
W, [2020-05-21T12:31:15.200344 #19166] WARN -- : Google::APIClient - Please provide :application_name and :application_version when initializing the client W, [2020-05-21T12:31:15.236307 #19166] WARN -- : Google::APIClient - Please provide :application_name and :application_version when initializing the client <!DOCTYPE html> <html lang=en> <meta charset=utf-8> <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width"> <title>Error 404 (Not Found)!!1</title> <style> *{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px} </style> <a href=//www.google.com/><span id=logo aria-label=Google></span></a> <p><b>404.</b> <ins>That’s an error.</ins> <p>The requested URL <code>/discovery/v1/apis/customsearch/v1/customsearch/v1?cx=012429992898212448897%3Aqfb0vzczcjq&key=AIzaSyDUnb5XYQ4ziNU6Li0o2_8oKgMMTIWhCFg&num=3&q=%E6%A4%9C%E7%B4%A2%E3%83%AF%E3%83%BC%E3%83%89&start=1&total_num=25</code> was not found on this server. <ins>That’s all we know.</ins>バージョンアップして正しく動くか確認。
以下を参考に0.8.3から最新の0.32.1にバージョンアップして検証。
https://github.com/googleapis/google-api-ruby-client/blob/master/MIGRATING.md
https://github.com/googleapis/google-api-ruby-client/blob/master/generated/google/apis/customsearch_v1/service.rb#L284#!/usr/bin/env ruby require 'google/apis/customsearch_v1' API_KEY = 'XXXXX' CSE_ID = 'xxxxx' custom_search_api = Google::Apis::CustomsearchV1::CustomsearchService.new custom_search_api.key = API_KEY query = { num: 3, start: 1, cr: 25, cx: CSE_ID } json = custom_search_api.list_cses('検索ワード', query).to_json puts jsonこれはjsonが返ってきた。
旧バージョンで動いていたときの出力結果がもはやわからないがツラいところだが、正しく動いてそう。{"context":{"title":" ... json","type":"application/json"}}Google APIのv0.8.3がサポートされなくなった?
- 投稿日:2020-05-21T11:30:26+09:00
【Ruby/Rails】Rubocopでupdate_allのLintを非活性にする
rubocop.ymlRails/SkipsModelValidations: Whitelist: - update_all参考:https://github.com/ManageIQ/manageiq-schema/pull/441/files
- 投稿日:2020-05-21T10:48:47+09:00
RubyでJWTトークンを検証する
AWS Cognitoのウェブトークンの検証を実施したときのメモです。
JSON ウェブトークンの検証 - Amazon Cognito
Cognitoではユーザプールごとに検証用のJWKセットをダウンロードできます
https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/jwks.json
使用するGem
jwt
jwt/ruby-jwt: A ruby implementation of the RFC 7519 OAuth JSON Web Token (JWT) standard.
通常のJWTトークンのデコードに使用
json-jwt
パブリック JSON ウェブキー (JWK) から公開鍵を作成するために使用
実装
# JWKセットをダウンロード uri = "https://cognito-idp.ap-northeast-1.amazonaws.com/example/.well-known/jwks.json" response = Net::HTTP.get_response(URI.parse(uri)) jwks = JSON.parse(response.body) # JWTを検証無しでデコード token = JWT.decode(jwt, nil, false) # JWKセットの中からkidが一致するものを取得 jwk = jwks["keys"].find { |obj| obj["kid"] == token[1]["kid"] } # 公開鍵を作成 public_key = JSON::JWK.new(jwk).to_key # 公開鍵を利用してデコード 検証が不正の場合は例外となる JSON::JWT.decode(jwt, public_key)参考になりましたら LGTM お願いします
- 投稿日:2020-05-21T10:46:21+09:00
Ruby on rails を初心者向けに解説③ ~データベースの作成~
はじめに
今回は、以前の記事の続きになっています。
よろしければ以前の記事も御覧ください。
Ruby on rails を初心者向けに解説② ~リンクの作成~
データベースとは
データベースとは、データを保存しておく場所のことです。
Ruby on Railsにおいては、コントローラーからモデルを作成することによりデータベースを操作することができます。
コントローラーの作成
今回は、ユーザーのIDとパスワードを保存するデータベースを作成することを考えます。
データベースを作成する前に、一度コントローラーとアクションを作成してみましょう。
ターミナルで以下のコードを実行してください。
rails g controller users indexこれでuserコントローラーを作成し、その中にindexアクションを追加することができました。rails g コマンドにおいて、コントローラー名とアクション名の2つを設定することができます。
以下のようにルーティングしてください。
routes.rbget 'users/index' => "users#index"これで、ユーザーから
user/index
というURLが送られてきたときに、userコントローラーのindexアクションを行うことができるようになりました。userコントローラーを確認してみましょう。今回は、最初からアクションが追加されています。
users_controller.rbclass UsersController < ApplicationController def index end end実はviewファイルも自動で生成されています。
以下のようにindex.html.erbファイルを書きましょう。
index.html.erb<h1>Users#index</h1> <p>Find me in app/views/users/index.html.erb</p>以下のURLでこのファイルにアクセスしましょう。
http://localhost:3000/users/index以下の画面がでてきます。
アクションから変数をviewファイルに渡す
コントローラーがviewファイルを探してきて、それをユーザーに返します。
その時、コントローラーの中のアクションに変数を定義することで、その変数をviewファイル内で用いることができます。
以下のように変数を定義しましょう。
users_controller.rbclass UsersController < ApplicationController def index @users = ["maru", "poco"] end end@userのように、変数の前に@を用いることでその変数はインスタンス変数になります。こちらに解説がありました。
このように、コントローラーからviewファイルに変数を渡すときは、ローカル変数ではなくインスタンス変数を用います。
Railsのコントローラでインスタンス変数を使用するのは、以下の場合です。
・メソッド間でのデータの受け渡し(典型的には、before_actionでデータをロードしておくとか)
・ビューへのデータの受け渡しこのように、@変数で作成したインスタンス変数はviewファイル内で利用することができます。
index.html.erb<% @users.each do |user| %> <div> <%= user %> </div> <% end %>@usersは配列が格納されているので、.each do ~ end で取り出すことができます。この部分は全てRubyのコードなので、<%%>ではさみましょう。ブラウザに表示する必要がないので、<%=%> ではなく <%%>ではさむところがポイントです。
<%= user %>
の部分で、ブラウザに表示させます。今回は、コントローラーのアクション内で配列を定義して、それをviewファイルに渡すことで利用しました。
今度は、データベースからデータをアクション内に持ってきて、それをviewファイルに渡すことを考えてみましょう。
モデルの作成
データベースを操作するためには、モデルを作成する必要があります。
モデルとは、
データベースの情報を操作する仕組み
のことです。または、データベースとのやり取りを行うクラス
とも言うことができます。以下のコードでモデルと。マイグレーションファイルを作成します。
rails g model user name:string password:stringUserがモデル名で、id、passwordがカラムになります。カラムとは、データベースの縦のデータ、つまり列のことです。
このコードで作成したデータベースは、以下のような表になっています。
この表全体を
テーブル
と呼び、縦のデータをカラム
、横のデータをレコード
と呼びます。モデルとは、このデータベースに対応するRubyのクラスであり、モデルクラスのインスタンスは一つの行(レコード)を表すオブジェクトであり、テーブルの列(カラム)に対応する属性をもちます。上記のコードを実行すると、データベースを作成するためのmigrationファイルと、モデルが作成されます。
class CreateUsers < ActiveRecord::Migration[5.2] def change create_table :users do |t| t.string :name t.string :password t.timestamps end end enduser.rbclass User < ApplicationRecord end上記の作成したマイグレーションファイル以下のコードで取り込むことで、データベースを作成することができます。
rails db:migrateここまでで、データベースを作成することができました。
それでは、マイグレーションファイルとは何なのかについてまとめていきましょう。
マイグレーションファイルとは
マイグレーションファイルとは、データベースを生成する際の設計図のようなものです。
マイグレーションファイルを実行することで、その内容に基づいたデータテーブルを作成することができます。
railsでは、
rails g model
コマンドを実行すると、マイグレーションファイルとモデルの両方が生成されます。マイグレーションファイルはデータベースの枠組みを作成するための道具で、モデルはデータベースとコントローラーを橋渡しする道具のようなものだと覚えておいてください。
データをデータベースに保存
以下のコードでRailsのコンソールを起動しましょう。
rails consoleコンソールを起動したら、モデルを使ってデータベースにデータを保存してみましょう。
user = User.new(name: "poco", password: "maru") user.saveこれでデータベースにデータを保存することができました。
データベースの確認
それでは作成したデータベースを確認していきましょう。
データベースクライアントの起動
以下のコードでデータベースクライアントを起動できます。
rails dbconsoleテーブルの一覧表示
データベースクライアントを起動した後は、以下のコードでテーブル一覧を表示することができます。
sqlite>.tablear_internal_metadata schema_migrations users
スキーマの表示
以下のコードでスキーマを表示することができます。スキーマとは、構造という意味です。指定したデータベースの構造を確認することができます。
sqlite>.schema usersCREATE TABLE IF NOT EXISTS "users" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "password" varchar, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL);
データベースクライアントの停止
以下のコードでデータベースクライアントを停止することができます。
sqlite>.quitここまでで、データベースを作成することができました。
それでは、実際にデータベースを利用してみましょう。
データベースの利用
データベースには、モデルを用いてアクセスします。
データベースを利用する際は、コントローラーからモデルを用いてアクセスします。
users_controller.rbclass UsersController < ApplicationController def index @user = User.first end endこれで、index.html.erbファイル内でインスタンス変数@userを使用することができるようになりました。
@userには、usersテーブルの一番最初の列のレコードが格納されています。
以下のように、index.html.erbファイル内で使用します。
index.html.erb<p><%= @user.name %></p> <p><%= @user.password %></p>終わりに
今回はここまでになります。
ここまでお付き合い頂きありがとうございました。
- 投稿日:2020-05-21T10:35:51+09:00
userを削除した際に紐づいたtweetを同時に削除する方法
某プログラミングスクールに約3ヶ月通い今回はその時に学習した事を書きます!!
今回はブログアプリを作成した際に、userを削除し紐づいたtweetも同時に削除する方法を書きます。
dependent: :destory
dependent: :destoryとはuserを削除した際に紐づいたtweetも同時に削除してくれる機能で、これのおかげでuserを削除してもtweetだけが残るといった事を回避できます
実装
user.rbClass User < ApplicationRecord has_many :tweets, dependent: :destroy endtweet.rbClass Tweet < ApplicationRecord belongs_to :user end上記の記述でuserを削除した際に紐づいたtweetも削除する様になりました。
注意点
tweetモデル側にdependent: :destroyを記述するとtweetを削除した際に紐づいたuserが削除されてしまいますので注意して下さい!!
最後まで見て頂きありがとうございます!!
この記事が少しでも参考になれば嬉しいです
- 投稿日:2020-05-21T10:12:19+09:00
ログインしていないユーザーをnewやeditページに遷移しない様にする方法
今回のやりたい事は
ログインしていないユーザーは、index,showページのみ遷移できて、newページやeditページに遷移しようとすると強制的にindexページに遷移されるようにします。
方法
以下の処理を行うことで、ユーザーがログインしていない状態でindex,showページ以外に遷移しようとすると、強制的にindexページに遷移されるようになります。
controller.rbclass PracticeController < ApplicationController before_action :move_to_index, except: [:index, :show] ---省略--- private def move_to_index redirect_to action: :index unless user_signed_in? end説明
コントローラー内で繰り返し使用されるコードは、private以下でメソッド化します。
最後まで見て頂きありがとうございます!!
この記事が少しでも参考になれば嬉しいです
- 投稿日:2020-05-21T08:35:29+09:00
RubyMine 2020.1が遅いときはアンチエイリアス設定をGreyscaleしてみよう
困っていたこと:RubyMine 2020.1がめちゃくちゃ遅い
RubyMineのバージョンが2020.1に上がってから文字入力がめちゃくちゃ遅くなりました。
どれくらい遅いのかというと、人間のタイピングスピードにIDEがまったく追いついていない、っていうぐらい遅いです。実際のスピードについては以下のツイートに載せた動画を参考にしてください。
@yusuke RubyMine 2020.1から日本語入力が超遅いです。この記事( https://t.co/JEwYPo19He )を見ながらJBR8を設定しましたが改善されませんでした。全速力でタイピングしてこれぐらいの表示スピードです。実際に1行目の半分ぐらいでタイピングはすべて終わってます。他に何か原因は考えられますか? pic.twitter.com/fGoRHAlR3p
— Junichi Ito (伊藤淳一) (@jnchito) May 10, 2020問題が発生した実行環境
僕の実行環境は以下のとおりです。
- RubyMine 2020.1.1
- macOS 10.15.4
- MacBook Pro (13-inch, 2017)
- Memory 16GB
RubyMineが遅い原因
RubyMineが遅い理由はどうやら4Kディスプレイにあるようです。
僕は普段Mac本体のディスプレイではなく、USB-Cで接続した4Kディスプレイ(EIZO EV2785)を使っているのですが、RubyMineのウインドウを4Kディスプレイで表示したときだけ、この現象が発生しました。
Mac本体のディスプレイに表示したときは、必要十分なスピードで入力できました。同じような現象はIntelliJ IDEAやPhpStorm、PyCharmといった他のJetBrains製IDEでも発生しているようです。
解決策(というか、軽減策)
下記の情報を参考にして、IDEとEditorのアンチエイリアス設定をSubpixelからGreyscaleに変更すると、2019.3とほぼ同等の入力スピードに戻すことができました。
Maybe it will help someone: the integrated terminal was extremely slow, I was able to fix the performance issue by changing the Antialiasing to Greyscale for both the editor and IDE.
https://youtrack.jetbrains.com/issue/JBR-526#focus=streamItem-27-4144635.0-0
アンチエイリアス設定はPreferences > Appearance & Behavior > Appearanceで変更できます。
こちらはGreyscaleモードで入力したときの動画です。
これだと人間のタイピングスピードにもほぼ追従できています。ただし、Greyscaleにすると画面の文字が少し細く(または暗く?)表示されるという副作用があります。
また、アンチエイリアスを完全になくすNo antialiasingというモードもありますが、これだとエディタの文字がガタガタして見栄えが悪いので、僕は選択しませんでした。
できればアンチエイリアス設定を変えずに、デフォルトのSubpixelモードで使いたいところですが、この問題は4Kディスプレイ、OS、JVMの兼ね合いに起因しているらしく、根本的な解決にはもうちょっと時間がかかりそうな気がします。
参考:あまり効果がなかった対策
JavaのRuntimeをJBR11からJBR8に変更する(もしくはJBR8からJBR11に戻す)と改善するかも、という情報がありましたが、これは効果がありませんでした。
ちなみに現在、僕のRubyMine 2020.1ではJBR8(jbsdk8u202b1491_osx_x64.tar.gz)を使用しています。
情報募集!
その他、この問題を解決するためのいい情報をご存じの方がいましたら、コメント欄等で情報をお願いします?
謝辞
本件については株式会社サムライズムのユースケさん(@yusuke)に解決のヒントをいただきました。
ユースケさん、どうもありがとうございました!
- 投稿日:2020-05-21T08:35:29+09:00
RubyMine 2020.1が遅いときはアンチエイリアス設定をGreyscaleにしてみよう
困っていたこと:RubyMine 2020.1がめちゃくちゃ遅い
RubyMineのバージョンが2020.1に上がってから文字入力がめちゃくちゃ遅くなりました。
どれくらい遅いのかというと、人間のタイピングスピードにIDEがまったく追いついていない、っていうぐらい遅いです。実際のスピードについては以下のツイートに載せた動画を参考にしてください。
@yusuke RubyMine 2020.1から日本語入力が超遅いです。この記事( https://t.co/JEwYPo19He )を見ながらJBR8を設定しましたが改善されませんでした。全速力でタイピングしてこれぐらいの表示スピードです。実際に1行目の半分ぐらいでタイピングはすべて終わってます。他に何か原因は考えられますか? pic.twitter.com/fGoRHAlR3p
— Junichi Ito (伊藤淳一) (@jnchito) May 10, 2020問題が発生した実行環境
僕の実行環境は以下のとおりです。
- RubyMine 2020.1.1
- macOS 10.15.4
- MacBook Pro (13-inch, 2017)
- Memory 16GB
RubyMineが遅い原因
RubyMineが遅い理由はどうやら4Kディスプレイにあるようです。
僕は普段Mac本体のディスプレイではなく、USB-Cで接続した4Kディスプレイ(EIZO EV2785)を使っているのですが、RubyMineのウインドウを4Kディスプレイで表示したときだけ、この現象が発生しました。
Mac本体のディスプレイに表示したときは、必要十分なスピードで入力できました。同じような現象はIntelliJ IDEAやPhpStorm、PyCharmといった他のJetBrains製IDEでも発生しているようです。
解決策(というか、軽減策)
下記の情報を参考にして、IDEとEditorのアンチエイリアス設定をSubpixelからGreyscaleに変更すると、2019.3とほぼ同等の入力スピードに戻すことができました。
Maybe it will help someone: the integrated terminal was extremely slow, I was able to fix the performance issue by changing the Antialiasing to Greyscale for both the editor and IDE.
https://youtrack.jetbrains.com/issue/JBR-526#focus=streamItem-27-4144635.0-0
アンチエイリアス設定はPreferences > Appearance & Behavior > Appearanceで変更できます。
こちらはGreyscaleモードで入力したときの動画です。
これだと人間のタイピングスピードにもほぼ追従できています。ただし、Greyscaleにすると画面の文字が少し細く(または暗く?)表示されるという副作用があります。
また、アンチエイリアスを完全になくすNo antialiasingというモードもありますが、これだとエディタの文字がガタガタして見栄えが悪いので、僕は選択しませんでした。
できればアンチエイリアス設定を変えずに、デフォルトのSubpixelモードで使いたいところですが、この問題は4Kディスプレイ、OS、JVMの兼ね合いに起因しているらしく、根本的な解決にはもうちょっと時間がかかりそうな気がします。
参考:あまり効果がなかった対策
JavaのRuntimeをJBR11からJBR8に変更する(もしくはJBR8からJBR11に戻す)と改善するかも、という情報がありましたが、これは効果がありませんでした。
ちなみに現在、僕のRubyMine 2020.1ではJBR8(jbsdk8u202b1491_osx_x64.tar.gz)を使用しています。
情報募集!
その他、この問題を解決するためのいい情報をご存じの方がいましたら、コメント欄等で情報をお願いします?
謝辞
本件については株式会社サムライズムのユースケさん(@yusuke)に解決のヒントをいただきました。
ユースケさん、どうもありがとうございました!
- 投稿日:2020-05-21T01:48:24+09:00
rubyにおける変数の種類
rubyにおける変数の種類
変数の種類が色々あってどう使い分けるかわからなかったので,自分用にメモを残す.
目次
- [ローカル変数]
- [インスタンス変数]
- [クラス変数]
- [グローバル変数]
ローカル変数
- 小文字or_(アンダーバー)で始まる.
- メソッドや,ブロック内のローカルなスコープで参照できる.
local.rbdef local() a = 3 end p a # =>Traceback (most recent call last): local.rb:5:in `<main>': undefined local variable or method `a' for main:Object (NameError)localメソッドで定義されたaは,メソッドの外からは呼び出せない.
インスタンス変数
- @で始まる.
- 同じクラス内であれば,違うメソッドからも参照可能.
- インスタンスごとに値を保持できる.
instance.rbclass Instance def set_val(val) @val = val end def put_val p @val end end test1 = Instance.new test1.set_val("aaa") test1.put_val test2 = Instance.new test2.put_val # => "aaa" nilインスタンスtest1の@valに,set_valメソッドを用いて,"aaa"を入れる.
その後,インスタンスtest2において,put_valを呼び出すが,nilが返ってくる.
ここから,各インスタンスごとに値を保持していることがわかる.instance.rbclass Instance def set_val(val) @val = val end def put_val p @val end end test1 = Instance.new test1.set_val("aaa") test1.put_val test2 = Instance.new test2.set_val("bbb") test2.put_val # => "aaa" "bbb"インスタンスtest2に対してもset_valメソッドを用いる必要がある.
クラス変数
- @@で始まる.
- 同じクラスのすべてのインスタンスで共有される.
class.rbclass Instance def set_val(val) @@val = val end def put_val p @@val end end test1 = Instance.new test1.set_val("aaa") test1.put_val test2 = Instance.new test2.put_val # => "aaa" "aaa"先ほどのインスタンス変数とは違い,値が同じクラスのすべてのインスタンスで共有されている.
class.rbclass Instance def set_val(val) @@val = val end def put_val p @@val end end test1 = Instance.new test1.set_val("aaa") test1.put_val test2 = Instance.new test2.set_val("bbb") test2.put_val test1.put_val # => "aaa" "bbb" "bbb"グローバル変数
- $で始まる.
- プログラムのどこからでも参照できる.
global.rbclass Global def set_val(val) $val = val end end test1 = Global.new test1.set_val("aaa") p $val # => "aaa"
- 投稿日:2020-05-21T01:29:47+09:00
コメントの投稿者名を表示したい
User,Post,Commentの3つのリレーションが、以下の時にコメント一覧でコメントの投稿者名を表示させたい。
user.rbhas_many :posts has_many :commentspost.rbbelongs_to :user fas_many :commentscomment.rbbelongs_to :user belongs_to :postshow.html.erb<p>コメント一覧</p> <% @comments.each do |c| %> <hr> <a href="/users/#{c.user_id}"><%= c.user.name %></a> <%= c.content %> <% end %>c.user.nameのnameがNoMethodErrorとなるので、posts.controllerに以下の1行追加することでcommentに関係したuserの情報を取り入れることができる。
posts.controller.rbdef show @comments = @post.comments.includes(:user).all end
- 投稿日:2020-05-21T00:37:18+09:00
個人アプリ制作2 WEBフォントの導入
今日の実装
① controller users tweet
② model user(devise) tweet
③ haml scssの導入
④ viewの作成 tewwt indexwebフォントの導入 Google Web Fonts
今回はおしゃれフォントをにしするためにGoogle Web Fontsを使用した。
導入方法
今回はscssで導入方法を記述する。
1 使いたいフォントを探す
google fonts から使いたいフォントを探す。
Google Web Fonts
右上にタブのlink href="https://fonts.googleapis.com/css2?family=Anton&display=swap" rel="stylesheetのURLをコピーする。
2 SCSSに読み込ませる
app/assets/stylesheets/application.scss@import url(https://fonts.googleapis.com/css?family=Anton);これでSCSS内でfontfamilyでAntonを使用することができる。
3 SCSSに使う。
app/assets/stylesheets/modules/_tweets.scssfont-family: 'Anton', sans-serif;すると 下のstudy-supportにAntonフォントが適用される。
注意
上のサイトgoogle fontsは日本語が対応していないものがほとんどなので日本語は適用されない場合が多い。
私は、日本語だけ適用されないことに気づかず40分ほど時間を浪費した笑今回はapplication.scssに読み込ませたが他の導入方法をあります。
参考サイト
今日のアイディア
投稿機能に動画を埋め込む
投稿機能(アウトプット)を今日勉強したことの自分のアウトプット動画をいれる
経緯
昨今はyoutubeなどの動画をみて学習したり、Twitter等でアウトプットをすることが動画でアウトプットをしているのが少なく見えた。時代の流れから推測するにSNSは、文字による表現➯文字+写真(インスタグラム)➯動画(youtubeにより個人の発信)となり、時代は動画にあると感じる。今よりももっと個人で発信できることを踏まえ、個人アプリstudy-supportでは、投稿機能に動画によりアウトプットもできるようにしたい。人に何かを伝えることが1番の勉強である。動画という選択肢はアウトプットの幅を広げることだと感じる。