- 投稿日:2020-07-21T23:51:01+09:00
【Rails】renderメソッドの引数のカッコの有無について
- 投稿日:2020-07-21T22:49:31+09:00
A server is already running. Check /[WORKDIR]/tmp/pids/server.pid.の解決方法
- 投稿日:2020-07-21T22:10:53+09:00
マークダウン記法でDB設計【残り55日】
使用したマークダウン記法
[#]
見出しとして使用
数を増やすとfont-sizeが小さくなっていく
HTMLでいうh1~h6タグ[|文字列|]
表の作成として使用
コロンを文字列の左、左右、右につけることで左寄せ、中央揃え、右寄せにできる[-]
箇条書きとして使用
ハイフンの後に半角スペースを入れることテーブル設計
users テーブル
Column Type Option name string null: false string null: false password string null: false Association
- has_many :room_users
- has_many :rooms, through :room_users
- has_many :messages
カラム、アソシエーションが一目瞭然なのでアプリケーション開発には必須の作業。
- 投稿日:2020-07-21T21:18:18+09:00
[Rails]Administrateでメインアプリで使っていたヘルパーメソッドを動作させる方法
困ったこと、やりたいこと
\\\メインアプリのヘルパーメソッドが使えない///
Railsアプリで管理画面を作成するために、Administrateというgemを使用した時のことです。
メインアプリのビューで使うためにhelperファイルに定義したhelperメソッドを、admin以下のビューでも使おうとしたところ、下記のエラーが…
image_present?
は、メインアプリのビューで使用しているヘルパーメソッド(自分でhelpers/shops_helper.rb
に定義したもの)です。
メインアプリではNoMethodErrorにならないのに…どうすればいいの???環境
- Ruby 2.5.1
- Rails 5.0.7.2
- Administrate 0.14.0
結論
1.
config/application.rb
ファイルに、下記の設定を記述する。
2. アプリケーション(サーバー)を再起動する以上。簡単でした笑
config/application.rbmodule Hoge class Application < Rails::Application # 他のconfigが書かれてるかも # ここから config.to_prepare do Administrate::ApplicationController.helper Hoge::Application.helpers end # ここまで end end※
Hoge
はアプリ名です。通常ならば、1行目のmodule
の後ろにrails newした時のアプリ名が記載されているはずです。
Administrate::ApplicationController.helper Hoge::Application.helpers
の
Hoge
の部分を、ご自身のアプリ名に置き換えてください。しっかりGitHubのIssuesに挙げられていて、解決済みだった
Best way to include main app helper modules in administrate? #334
余談
参考記事に挙げたGitHubのIssuesを見ていると、他の方法もあるよう。
こちらの方法は、
1.helpers
ディレクトリの下にadministrate
ディレクトリを作成
2. そこにapplication_helper.rb
ファイルを作成
3. そこにヘルパーメソッドを再度定義する
という方法のようです。試しにやってみた
helpers/administrate/application_helper.rbmodule Administrate::ApplicationHelper def image_present?(shop) if shop.shop_images.present? image_tag "#{shop.shop_images[0].shop_image}", class: 'top-cover-img shop-img' else image_tag asset_path('no-image.png'), class: 'top-cover-img shop-img' end end endポイントは、
module
の宣言の際に、クラスの継承?(Administrate::ApplicationHelper
)を記述することだそうです。
これがないとRouting Errorになります。
実現できるが、DRY原則に反する
一応上記の方法でも実現できましたが、同じヘルパーメソッドを2回定義することになるので、DRY原則に反するなと思いました。
無駄なファイルも作成しなくていいので、冒頭の方法をおすすめします。
- 投稿日:2020-07-21T20:58:49+09:00
【ポートフォリオを作成する方へ】ミスを減らして、読みやすいコードへ -Rubocop Airbnb-
Rubocop Airbnbとは
書かれたコードをコーディング規約に沿っているかチェックしてくれるライブラリです。構文解析ツールとしてRubocopが有名ですが、色々な設定があるので、今回は開発現場用にカスタマイズされたrubocop-airbnbを導入していきます。
導入
gemをインストール
Gemfilegroup :development, :test do gem 'rubocop-airbnb' end$ bundle installファイル作成
Gemfileと同じディレクトリに.rubocop.yml と .rubocop_airbnb.ymlを新規作成します。
.rubocop.ymlinherit_from: - .rubocop_airbnb.yml AllCops: Exclude: - 'bin/*' - 'config/**/*' - 'db/**/*' - 'spec/spec_helper.rb'.rubocop_airbnb.ymlrequire: - rubocop-airbnb呼び出した際にエラーが出る時はここのファイルの"."や"_"のつけ忘れや入力ミスの可能性があるので気をつけてください。
rubocopの実行
$ rubocop --require rubocop-airbnb自動修正方法
$ rubocop --require rubocop-airbnb -aまとめ
修正は後になるほど大変になるので、ぜひコードを書き始める前に導入してみてください。
参考
- 投稿日:2020-07-21T20:25:22+09:00
【Ruby on Rails】Fat Controllerの解消〜まずはロジックをモデルへ〜
はじめに
今回初投稿となります。
スクールでRuby on Railsを学習し、リファクタリングのカリキュラムもあったのですが、その時点では完成させることに必死で、ロクにリファクタリングもしていなかったので今回ControllerのロジックをModelへ移し、コントローラーをすっきりさせる方法を書いていきます。そもそもFat Controllerとは?
コントローラー自体の行数が多く、処理の流れを追いにくくなってしまっているControllerの状態を指します(簡単に言えば見通しが悪い)。
スクールでは全く意識せずにControllerに全てのロジックを記述していたが、「実務レベルのコードに近づけたい!」という思いから現在も個人アプリのFat Controllerと闘っています(笑)切り分ける手順
まずは膨大に膨れ上がったControllerのロジックを全てModelへ移してしまうくらいの気持ちでいきましょう。
Controllerに記述するpublicメソッドはアクションだけで十分です。そしてロジックを移す先は基本的にModelで問題ないと思います。
例:ユーザーの持つアイテムのみを引っ張ってきたい場合
切り分け前↓
users.controller.rbdef show @useritems = Item.includes(:images).where(user_id:(current_user.id)).order(id: "DESC") if user_signed_in? enddeviseを使用して認証機能を実装しているため、「current_user.id」で現在ログイン中のユーザーのidが取得できます。つまり現在ログイン中のユーザーのマイページ(showアクション)にユーザーのアイテムの情報を引っ張ってきたいわけです。
しかしこのデータの取得、実は「items.controller.rb」のindexアクションでも使用しています。ということでModelにメソッドを定義し、ユーザーのアイテムを取得する記述をまとめたいと思います。まずはController
users.controller.rbdef show @useritems = Item.user_items_get(current_user.id) if user_signed_in? endModel側で「current_user」は使用できないので引数で渡します。
続いてModel
Item.rbdef self.user_items_get(user_bigint) Item.includes(:images).where(user_id:(user_bigint)).order(id: "DESC") endこの様にする事でItemControllerのindexアクションでも
items.cotroller.rbdef index @useritems = Item.user_items_get(current_user.id).limit(10) if user_signed_in? endこの様に使用することができます。
Modelにメソッドを書いてControllerで呼び出すとなると、初学者は大層なことに感じてしまいがちですが、Controllerをすっきりさせる上では重要なので是非活用してみて下さい。(しまったこの例行数減ってないや、、、笑)
- 投稿日:2020-07-21T20:08:18+09:00
Rubyのパターンマッチを使って簡単なプログラミング問題を解いてみた
業務で必要になった簡単な文字列処理をRuby 2.7で導入されたパターンマッチを使って解いてみました。
今回のお題はこちら
"1, 5, 10-12, 15, 18-20"
という文字列から
[1, 5, 10, 11, 12, 15, 18, 19, 20]
という配列を作りたい。どう書く?
僕の解答例
こんな感じで解いてみました。
Minitestによるテストも一緒に書いてます。require 'minitest/autorun' def parse_as_array(str) str .scan(/\d+(?:-\d+)?/) .flat_map{|s| case s.split('-').map(&:to_i) in [n] then n in [n, m] then [*n..m] end } end class ParseAsArrayTest < Minitest::Test def test_parse_as_array str = "1, 5, 10-12, 15, 18-20" expected = [1, 5, 10, 11, 12, 15, 18, 19, 20] assert_equal expected, parse_as_array(str) end endざっくり解説
上の
parse_as_array
メソッドのロジックを上から順に分解しながら説明してみます。まず、正規表現を使って文字列から数字とハイフンだけを配列として抜き出します。
str = "1, 5, 10-12, 15, 18-20" str.scan(/\d+(?:-\d+)?/) #=> ["1", "5", "10-12", "15", "18-20"]正規表現の読み方がわからない!という人はこちらの記事を読めばわかるはずです。
- 初心者歓迎!手と目で覚える正規表現入門・その1「さまざまな形式の電話番号を検索しよう」 - Qiita
- 初心者歓迎!手と目で覚える正規表現入門・その2「微妙な違いを許容しつつ置換しよう」 - Qiita
さらに、その配列をそれぞれハイフンでsplitします。
arr = ["1", "5", "10-12", "15", "18-20"] arr.map{|s| s.split('-')} #=> [["1"], ["5"], ["10", "12"], ["15"], ["18", "20"]]ただし、そのままだと文字列になってしまうので、
to_i
メソッドで整数に変換します。arr = ["1", "5", "10-12", "15", "18-20"] arr.map{|s| s.split('-').map(&:to_i)} #=> [[1], [5], [10, 12], [15], [18, 20]]そうすると、"-"が含まれる文字列は要素が2個に、それ以外は要素が1個になります。
この「1個か、2個か」をパターンマッチで条件分岐して、なおかつ変数に代入します。arr = [[1], [5], [10, 12], [15], [18, 20]] arr.each {|a| case a in [n] # 要素が1個の場合の処理 pp n in [n, m] # 要素が2個の場合の処理 pp [n, m] end } #=> 1 # 5 # [10, 12] # 15 # [18, 20]Ruby 2.7のパターンマッチ構文の使い方についてはこちらの記事をご覧ください。
さらに、"10-12"のような文字列は
[10, 11, 12]
のような配列に変換する必要があります。
これは範囲(Range)を使って実現します。n = 10 m = 12 [*n..m] #=> [10, 11, 12]ハイフンを含まない数字(1や5)はそのまま数字として使えばOKです。
ここまでのアイデアを組み合わせてメソッドチェーンにすると、次のようなコードが書けます。(パターンマッチ構文は
then
を使ってin
を1行にまとめています)str = "1, 5, 10-12, 15, 18-20" str .scan(/\d+(?:-\d+)?/) .map{|s| case s.split('-').map(&:to_i) in [n] then n in [n, m] then [*n..m] end } #=> [1, 5, [10, 11, 12], 15, [18, 19, 20]]ただし、上の結果を見るとわかるように、"10-12"や"18-20"の変換結果はネストした配列になってしまっています。
そこで、map
の代わりにflat_map
を使ってフラットな配列が返るようにします。str = "1, 5, 10-12, 15, 18-20" str .scan(/\d+(?:-\d+)?/) .flat_map{|s| case s.split('-').map(&:to_i) in [n] then n in [n, m] then [*n..m] end } #=> [1, 5, 10, 11, 12, 15, 18, 19, 20]これをメソッド化すれば完成です!
def parse_as_array(str) str .scan(/\d+(?:-\d+)?/) .flat_map{|s| case s.split('-').map(&:to_i) in [n] then n in [n, m] then [*n..m] end } end str = "1, 5, 10-12, 15, 18-20" parse_as_array(str) #=> [1, 5, 10, 11, 12, 15, 18, 19, 20]パターンマッチを使わない場合
ほぼ同じ考え方でパターンマッチを使わない書き方もできます。
def parse_as_array(str) str .scan(/\d+(?:-\d+)?/) .flat_map{|s| n, m = s.split('-').map(&:to_i) m ? [*n..m] : n } endあれ、こっちの方がシンプルかも・・・???
その他の解答例
弊社内で出てきたその他の解答例です。
# evalを使うパターン def parse_as_array(str) str .gsub('-', '..') .split(',') .flat_map {|x| Array(eval(x)) } end# evalを使うパターンその2 def parse_as_array(str) str .gsub(/(\d+)-(\d+)/, '*\1..\2') .then{|s| eval("[#{s}]")} endいろいろな解き方があって面白いですね!
- 投稿日:2020-07-21T19:13:13+09:00
いいね機能(Ajax)の実装
自分用にまとめます。
実装
コントローラー・モデル作成済み
routes.erbRails.application.routes.draw do resources :posts do resources :comments, only: [:create, :destroy] resource :likes, only: [:create, :destroy] end endlikesはIDの付与不必要のためresourceになる
post.rbdef liked_by?(user) likes.where(user_id: user.id).exists? endいいねしたかどうかを確認できる
likes_controller.rbclass LikesController < ApplicationController def create @post = Post.find_by(id: params[:post_id]) # 連続クリック防止のための条件 unless @post.liked_by?(current_user) @like = current_user.likes.new(post_id: @post.id) @like.save end end def destroy @post = Post.find_by(id: params[:post_id]) @like = current_user.likes.find_by(post_id: @post.id) @like.destroy end endcreate,destroyそれぞれリダイレクトは不要になるので、記載している場合は削除
posts/show.html.slim#Ajax化するために必要になるのでidを付与する div id='like_#{ @post.id }' # いいねアイコンをパーシャル化 = render 'like', post: @postposts/_like.html.slim# いいね削除 - if post.liked_by?(current_user) = link_to post_likes_path(post), method: :delete, remote: true do i.fas.fa-heart style='color: red;' = post.likes.count # いいね - else = link_to post_likes_path(post), method: :post, remote: true do i.far.fa-heart = post.likes.countremote: trueをつけることでJavaScriptファイルを呼び出す
likes/create.js.erb$("#like_<%= @post.id %>").html("<%= j(render 'posts/like', post: @post ) %>");likes/destroy.js.erb$("#like_<%= @post.id %>").html("<%= j(render 'posts/like', post: @post ) %>");完成!
- 投稿日:2020-07-21T19:05:17+09:00
Rails環境構築 Rails5.2.1 ruby2.5.1 Catalina
久しぶりの投稿です。
2019年の9月からテックキャンプに通い、2020年の7月からRails自社開発企業で働き始めました!
時間は掛かってしまいましたが、念願のエンジニアデビュー初日、支給されたMacBookの環境構築で苦労したので記録しておきます。開発環境
Rails 5.2.1
Ruby 2.5.1
MacOS Catalina10.15.6Dockerは使ってないので完全に初期状態のPCにエディタからRubyから詰め込んで行きました。
これだけで1日終わりました。苦労したこと
- command line toolsの導入
- Rubyのバージョン設定
- MacOSの互換性(個人ではmojaveを使用)
- rbenvの理解
学習の基礎段階ではテックキャンプのカリキュラムで環境を構築していたので、0から自力で環境構築するのに結構時間がかかってしまいました。かなり復習になりました。
command line tools
command line toolとは「キーボードだけで操作するプログラム」です。
要はターミナルから打ち込むコマンドですね。Xcodeの「command line tools」をインストールします。
ターミナル$ xcode-select --installXcode本体を入れなくても良いという記事がありますが、私の環境ではXcode自体もインストールが必要でした。
こちらのコマンドでバージョン確認が取れればインストール成功
ターミナル$ xcodebuild -version遭遇したエラー
xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instanceこちらがXcode本体をインストールする前に遭遇したエラー
Xcode本体をインストール後に↓のコマンドで解決しました。
ターミナルsudo xcode-select -s /Applications/Xcode.app/Contents/DeveloperXcodeのcommand line toolsに切り替えるコマンドみたいです。
Rubyのバージョン設定
学習時はあまり意識していませんでしたが、Rubyのバージョン管理はrbenvで行います。
複数のRubyのバージョンを管理するツールです。homebrewでインストールします。
※homebrewも初期状態ではインストールされていないので導入が必要です。
homebrewとはMac OSのパッケージマネジャです。ターミナル# rbenvインストール $ brew install rbenv ruby-build次にbashで使えるようにするのですがMacOS Catalinaではデフォルトのログインシェルが zsh です。
mojaveでは bash でした。まだ資料もbashのほうが多いのでここでbashにログインシェルを切り替えました。
ログインシェルとはログイン直後に設定されているシェルのことです。
切替コマンド
ターミナル# 使用できるシェルを確認 $ cat /etc/shells # 切替 $ chsh # vimが開くのでファイルを修正します。Catalinaではターミナルが %表記 になっています。
mojaveでは $表記 です。地味に焦りました。
いままでbashしか使ったことがなく、bashの方が日本語の資料が豊富なのでzshをbashに切り替えた訳ですが、zshはbashの上位互換という記事を目にしました。
ターミナルでも警告が出た気がします。早くzshにして慣れた方が良さそうな気がします。
続いてbashでコマンドを使えるようにパスを通します。
ターミナル$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc $ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile $ source ~/.bash_profileこれでrbenvが使えるようになります。
その後いよいよRubyやRails,DBをインストールしていくのですが、特に詰まるポイントもなかったので割愛します。
こちらの記事を参考にさせて頂きました。以上です。
お付き合い頂きありがとうございました!
- 投稿日:2020-07-21T18:35:58+09:00
Railsで日時を日本語表記に変更
はじめに
テーブルのカラム
created_at
を使えば、データを作成した日時を取り出せます。
ところが、そのままの表記では使いづらいです。今回は、
2020/7/21 9:05:50
の様な表記で取り出せるようにしたいと思います。作成日時を表示する
まず
posts
テーブルのデータ@post
のcreated_at
をそのまま取り出してみましょう。posts/show.html.erb<p>イベント: <%= @post.event %></p> <p>場所: <%= @post.place %></p> <p>作成日時: <%= @post.created_at %></p>
place event created_at 東京 花火大会 2020-07-21 00:05:50 UTC 目標としている
2020/7/21 9:05:50
の表記と大いに違うことが分かると思います。具体的には以下の3点が異なります。
UTC
(世界標準時) になっている/
のところが-
になっている7
の表記が07
になっている順番に修正していきたいと思います。
1.世界標準時から日本時間に変更する
プログラミングは世界中で使われている為、そのままだと
世界標準時
で出力されてしまいます。
その為、日本時間
に変更しましょう。config/application.rbclass Application < Rails::Application # ***** 次の1行を追加 ***** config.time_zone = "Asia/Tokyo" endこの1行を入れることで以下のように、
世界標準時
を日本時間
に変更することができました。
place event created_at 東京 花火大会 2020-07-21 09:05:50 +0900
+0900
がついていますが、これは、日本時間と世界標準時との時差が+9時間であることを表しています。2.フォーマットを変更する
日本時間にはなりましたが、フォーマットが
2020-07-21 09:05:50 +0900
では分かりにくいです。変更していきましょう。まず、多言語に対応する為の gem をインストールし、日本語に設定します。
Gemfile# Rails6 の場合 gem 'rails-i18n', '~> 6.0' # Rails5 の場合 gem 'rails-i18n', '~> 5.1'ターミナルbundle install
config/application.rbclass Application < Rails::Application # 略 config.time_zone = "Asia/Tokyo" # ***** 次の1行を追加 ***** config.i18n.default_locale = :ja end次に、
rails-i18n
に用意されているl
メソッドを使用します。posts/show.html.erb<p>イベント: <%= @post.event %></p> <p>場所: <%= @post.place %></p> <!-- ***** l を追加 ***** --> <p>作成日時: <%= l @post.created_at %></p>さらに、config/locales/ja.ymlというファイルを作成し、フォーマットを設定しましょう。
config/locales/ja.ymlja: time: formats: default: "%Y/%m/%d %H:%M:%S"これにより、表記が以下のように変わり、+0900も消えます。
place event created_at 東京 花火大会 2020/07/21 09:05:50 フォーマットは自由に変更することができ、例えば、
秒
が不要なら:%S
を省くことで対応出来ます。config/locales/ja.ymldefault: "%Y/%m/%d %H:%M"
place event created_at 東京 花火大会 2020/07/21 09:05
記号 意味 %Y 年(YEAR) %m 月(MONTH) %d 日(DAY) %H 時(HOUR) %M 分(MINUTE) %S 秒(SECOND) [参考ページ] Ruby 2.7.0 リファレンスマニュアル(strftime)
3.ゼロ(0)埋めをなくす
例えば、
7月
が07
と表記されるのは不自然なので0
を削りましょう。config/locales/ja.ymlja: time: formats: # ***** %の後ろに-を追加 ***** default: "%Y/%-m/%-d %-H:%M:%S"
place event created_at 東京 花火大会 2020/7/21 9:05:50
-
を入れることで以上の様に、0埋め
をなくすことが出来ました。
- 投稿日:2020-07-21T18:05:33+09:00
標準入力・まとめ/python,ruby
自分用メモとしてpaizaのスキルチェックやAtCoderなどでよく使いそうな標準入力をまとめました。
基本
文字
input.pys = input()input.rbs = gets.chomp数値
pythonn = int(input())rubyn = gets.chomp.to_iスペースで区切る
スペースで区切られた値を個別の変数に数値として入力
input1 2 3pythona,b,c = map(int,input().split()) #int カンマ input ドット split に注意rubya,b,c = gets.chomp.split.map(&:to_i)スペースで区切られた値を個別の変数に文字として入力
inputred blue yellowpythona,b,c = input().split()rubya,b,c = gets.chomp.splitスペース区切りの値をリストに入力(文字・数値)
inputspring summer autumn winter 101 102 103 104pythonx = input().split() y = list( map(int,input().split()) )rubyx = gets.chomp.split y = gets.chomp.split.map(&:to_i)output#x ["spring","summer","autumn","winter"] #y [101,102,103,104]複数行
入力:n(行数)
i1
.
.
inn行の値をリストに入力 [i1,i2,i3,.....,in]
pythonn = int(input()) I = [ input() for i in range(n) ]rubyn = gets.chomp.to_i array = [] n.times do i = gets.chomp array.push(i) end
- 投稿日:2020-07-21T14:19:23+09:00
動画の再生時間(HH:MM:SS)を秒数にしたいし、その逆もしたい
- 投稿日:2020-07-21T13:49:25+09:00
【AWS SQS】SQSを構築し、EC2からメッセージをポーリングする
目標
AWS SQSを構築しメッセージをキューに投入(AWSコンソール上から投入する)、その後投入したメッセージをAWS SDKを利用してEC2から取得(ポーリング)する。
SQSとは
アプリケーション間でやりとりされるメッセージを送受信するためのAWSが提供するキューサービスのこと。
受信側がメッセージをSQSに問い合わせてメッセージを取得するPull型のサービスです。SQSに関する基本情報は以下記事がわかりやすくまとめられていると思いました。
Amazon SQS前提
・AWS SDK(AWS SDK for Rubyを本記事では利用)を使用可能なEC2インスタンスが構築済みであること(※)。
※AWS SDK for Rubyを構築した際の参考手順
【AWS SDK】EC2自動構築用スクリプト(1.AWS SDK for Rubyのセットアップ)作業の流れ
項番 タイトル 1 SQSの構築 2 SQSにメッセージを送信 3 EC2からメッセージをポーリングする 手順
1.SQSの構築
①SQSコンソールを開く
②
キューを作成
をクリック③作成するキューの設定
今回はスタンダードキューを利用します(※1)
キューの名前は任意のものを記載します。※1 SQSには以下2つのタイプのキューが存在します。特徴を簡単にまとめます。
・スタンダードキュー
⇒最低1回のメッセージ配信を保証するが、リクエストのタイミングによっては同一メッセージが複数回配信される可能性がある。
⇒メッセージ配信の順序はベストエフォート型(メッセージ送信と配信の順序が異なる可能性がある。)・FIFOキュー
⇒同一メッセージが複数回配信されることはない。
⇒メッセージ配信の順序は先入れ先出し型(メッセージ送信と配信の順序が同一となる。)
⇒高性能なため、スタンダードキューよりも少し料金が高い。キューの詳細設定(※2)をします。
今回はメッセージ受信待機時間
のみ20秒に設定し、それ以外はデフォルトのままとしています。※2 以下簡単にキューの詳細設定の内容を記載致します。
・可視性タイムアウト
メッセージを受信した後に一定時間、該当のメッセージを他システムから見えなくさせる機能のこと。
可視性タイムアウトとして指定した時間内にメッセージ処理を完了させ、メッセージ削除することで、
同一メッセージに対する複数回処理を防ぐことが可能となります。・配信遅延(遅延キュー)
キューにメッセージを送信した後、指定した時間が経過した後にメッセージを表示させるようにする機能・メッセージ受信待機時間
ロングポーリングorショートポーリングの設定を行うことが出来ます。
デフォルトはショートポーリング(メッセージ受信待機時間が0秒)となっており、キューが空の場合でもすぐ再リクエストを行います。
SQSはメッセージのリクエスト回数によって料金が判断されるため、空メッセージのリクエストを繰り返すと料金がかさんでしまいます。
その対策として有効なのが、ロングポーリング(メッセージ受信待機時間が0秒より上)となります。
ロングポーリングを設定すると空メッセージを受け取った場合、指定した秒数分待機する(キュー接続を持続する)ため、
SQSのリクエスト回数を減らし料金を節約することが可能となります。
要件にもよりますが、基本的にはロングポーリングを使用するのがAWSの推奨となっているようです。キューへのアクセス設定はデフォルトのままとします。
最後に暗号化、デッドレターキュー(※3)、タグの設定もありますが今回は設定なしとします。
キューの作成
をクリック※3 デッドレターキュー
処理結果がエラーとなったメッセージを何回かリトライ後、自動的に別のキューに移動する機能
問題のあるメッセージが別キューに集中するため識別しやすくなり、当該メッセージが正規のキューに残存することを防ぎます。2.SQSにメッセージを送信
作成したSQSキューにAWSコンソール上からメッセージを送信してみます。
①作成したSQSキューの詳細画面から
メッセージの送受信
をクリック
②
メッセージ本文
を記載後メッセージ送信
をクリック
この手順を何回か繰り返します。
③送信したメッセージの内容確認
メッセージ送信欄の下段にあるメッセージ受信欄からメッセージをポーリング
をクリック
メッセージが表示されればOKです
3.EC2からメッセージをポーリングする
①AWS SDK for Rubyが利用可能なEC2インスタンスにポーリング実行用スクリプトを配備
# ********************************************************************************** # <機能概要> # 指定したSQSキューのメッセージをポーリングする # # <機能詳細> # 常駐プロセスとして稼働し、指定したSQSキューのメッセージをポーリングし取得時刻及びメッセージ本文を標準出力する。 # 取得したメッセージは出力後削除する。 # メッセージが空の場合は指定した時間(wait_time_seconds)分待機した後、キューが空であることを伝えるメッセージを出力する。 # # <スクリプト用法> # ruby <スクリプトパス> # ********************************************************************************** require 'aws-sdk' # キュー名 queue_name = "MyTestQueue" # SQS操作用インスタンス作成 sqs = Aws::SQS::Client.new # キューURLの取得 begin queue_url = sqs.get_queue_url(queue_name: queue_name).queue_url rescue Aws::SQS::Errors::NonExistentQueue puts "A queue named '#{queue_name}' does not exist." exit(false) end loop do # キューからメッセージを取得 receive_message_result = sqs.receive_message({ queue_url: queue_url, message_attribute_names: ["All"], # 全属性のメッセージを取得 max_number_of_messages: 5, # 最大でも5メッセージの取得 wait_time_seconds: 20 # メッセージが空の場合は20秒待機 }) # メッセージを取得した時刻を取得 timestamp = Time.new # メッセージが空のときはemptyメッセージ出力 if receive_message_result.messages.nil? puts "#{timestamp.strftime("%Y-%m-%d %H:%M:%S")}: Message is empty." end receive_message_result.messages.each do |message| # 取得したメッセージ本文を表示 puts "#{timestamp.strftime("%Y-%m-%d %H:%M:%S")}: #{message.body}" # メッセージをキューから削除 sqs.delete_message({ queue_url: queue_url, receipt_handle: message.receipt_handle }) end end②スクリプト実行し、メッセージをポーリングする。
AWSコンソールから事前投入した3つメッセージは即座に処理され、メッセージが空の場合は指定した時間分待機することを確認できました。
またメッセージ待機中に新規メッセージをキューにプットした場合、そのメッセージは即座に処理されることも確認できました。[ec2-user@basehost ~]$ ruby queue.rb 2020-07-21 04:13:32: test2 # AWSコンソールから事前投入したメッセージその1 2020-07-21 04:13:33: test3 # AWSコンソールから事前投入したメッセージその2 2020-07-21 04:13:33: test1 # AWSコンソールから事前投入したメッセージその3 2020-07-21 04:13:53: Message is empty. # wait_time_secondsで指定した時間分(20秒)待機後、emptyメッセージ出力 2020-07-21 04:14:01: This message is the message sent during the waiting time. # メッセージ待機時間中にキューにプットしたメッセージ、プット後即座に処理された。 2020-07-21 04:14:21: Message is empty. 2020-07-21 04:14:41: Message is empty. 2020-07-21 04:15:01: Message is empty.
- 投稿日:2020-07-21T12:13:08+09:00
rubocopに追加された Style/HashLikeCase Consider replacing case-when with a hash lookup
rubocopに追加された Style/HashLikeCase
case文で記述しなくても良い場合は配列で定義してしまいましょうというルール。
rubocop
0.88.0
で追加、非常に良いですね。悪い例type = 'test' case type when 'interview' 'インタビュー' when 'test' 'テスト' when 'standard' '通常' end良い例type = 'test' lists = { 'interview' => 'インタビュー', 'test' => 'テスト', 'standard' => '通常', } lists[type]公式リポジトリの情報
issueと経緯
https://github.com/rubocop-hq/rubocop/issues/8247
PRと実装
- 投稿日:2020-07-21T10:26:22+09:00
redirect_toでflashメッセージが表示されない
事象
下記のように記述してもflashメッセージが表示されず、msgがクエリパラメータに含まれてしまう。
redirect_to action: :new, alert: 'msg'解決策
下記のように記述する。
redirect_to({:action => :new} , {:alert => 'msg'})原因
redirect_toは下記のように使用する。
redirect_to(options = {}, response_options = {})冒頭のように記述すると、flashメッセージも第一引数として扱われてしまう。
redirect_to action: :new, alert: 'msg' ↓ redirect_to({:action => :new, :alert => 'msg'}, { })
- 投稿日:2020-07-21T10:19:16+09:00
redirect_toとrenderの使い分け
概要
Railsで
scaffold
を使ったらcreateアクションは以下のようになる。
保存に成功した時はredirect_to
でページ遷移するのに失敗したときはrender
を使っている。
この違いを解説する。user_cocntroller.rbdef create @user = User.new(user_params) respond_to do |format| if @user.save format.html { redirect_to @user, notice: 'User was successfully created.' } format.json { render :show, status: :created, location: @user } else format.html { render :new } format.json { render json: @user.errors, status: :unprocessable_entity } end end end結論
redirect_toはHTTPリクエストが走る。
renderはviewをただ表示するだけ(=URLは変化しない)redirect_toを使用したい時
データの更新が成功したときは、HTTPリクエストを走らせて別のページに遷移する。
そうすることで、リロードで同じデータが登録されないようにする。renderを使用したい時
保存に失敗したときは、エラーメッセージを添えてviewを表示してやるだけでOK。
無駄にリクエストを増やさないようにする。
データの登録は行われていないので、リロードされても問題ない。