- 投稿日:2020-10-17T23:44:27+09:00
本日の学習まとめ ユーザー管理機能実装にて
はじめに
今回は完全に自分用で覚えておきたいことを雑多に書き連ねている。
正規表現
PASSWORD_REGEX = /\A(?=.*?[A-z])(?=.*?[\d])[A-z\d]+\z/i.freeze # 半角英数混合1字以上 ZENKAKU_REGEX = /\A[ぁ-んァ-ン一-龥]+\z/.freeze # 全角ひらカタ漢字 KANA_REGEX = /\A[ァ-ヶー-]+\z/.freeze # 全角カナ
freeze
は変数が変わらないようにするため。バリデーションのオプションをまとめる
with_options presence: true do validates #オプションをつける endエラーメッセージを表示させる
foem_withの中でrenderメソッドでファイルを呼び出す。そのとき、devise配下のファイルであるように記述をする。
<%= form_with model: @user, url: user_registration_path', local: true do |f| %> <%= render 'devise/shared/error_messages', model: f.object %>_error_messages.html.erb<% if model.errors.any? %> <div id="error_explanation"> <h2> <%= I18n.t("errors.messages.not_saved", count: model.errors.count, resource: model.class.model_name.human.downcase) %> </h2> <ul> <%= model.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </div> <% end %> modelを呼び出すように記述する。
- 投稿日:2020-10-17T22:06:56+09:00
Rails ブラウザ上で、ルートを確認する
はじめに
今回は、ブラウザ上でルートの確認の仕方について学習します。
普段は、ターミナルにrails routesをたたき、確認していました。
$ rails routes Prefix Verb URI Pattern Controller#Action sessions_new GET /sessions/new(.:format) sessions#new root GET / static_pages#home help GET /help(.:format) static_pages#help about GET /about(.:format) static_pages#about contact GET /contact(.:format) static_pages#contact signup GET /signup(.:format) users#new POST /signup(.:format) users#create login GET /login(.:format) sessions#new POST /login(.:format) sessions#create logout DELETE /logout(.:format) sessions#destroy users GET /users(.:format) users#index POST /users(.:format) users#create new_user GET /users/new(.:format) users#new edit_user GET /users/:id/edit(.:format) users#edit user GET /users/:id(.:format) users#show PATCH /users/:id(.:format) users#update PUT /users/:id(.:format) users#update DELETE /users/:id(.:format) users#destroyブラウザ上で確認する方法
(http://localhost:3000/rails/info/routes)
こちらにアクセスするだけです!
左の列から
-Helper
-HTTP Verb
-Path
-Controller#Actionとなっていて、構成はターミナルと変わりません。
こちらの方が見やすいですね!
- 投稿日:2020-10-17T21:31:24+09:00
EC2にRAILSをデプロイ
- 投稿日:2020-10-17T19:04:48+09:00
Rails if文とunlessの混合条件式の作成
最終課題に向けて調整を行いました。
その際に、条件式をifとunlessの両方を使用するという特殊なパターンに
チャレンジしてみました。備忘録として投稿させて頂きます。今回はhamlにて記述しています。
sample.rb#viewファイルにて .item-show-page__link-btn -if @item.buyers.present? %p SOLD OUT -else - unless user_signed_in? && @item.user_id == current_user.id = link_to purchase_item_path(@item.id), class: "item-show-page__link" do 購入画面へ - else %p 出品者は購入できませんメソッドの中身
@item 出品情報が入っています。
buyers 購入した履歴のメソッドになります。解説
if〜else
もし購入した履歴のIDが存在したらSOLD OUTを表示unless~else
if文のelseの中に入れ子として格納
しています。そこからunlessの条件式を入れています。
もし出品した商品とユーザーIDが一致しない場合は購入画面に遷移するリンクを出現。
そうでない場合は「出品者は購入できません」と出現させる。以上となります。
- 投稿日:2020-10-17T17:54:52+09:00
Javascriptで日付を扱う(moment.js)
はじめに
Qiita初投稿です。
間違っていることがありましたら、ご指摘いただけると幸いです。開発環境
ruby 2.6.5
Rails 6.0.3.3概要
moment.jsとはjavascriptで日付を扱うときに便利なライブラリです。
パッケージ管理面での欠点があるとも言われていますが、まだ主流な技術なので使用してみました。使用方法
作業中のディレクトリでmoment.jsをインストールします
npm install moment使用したいjsファイルでmomentを読み込みます
〇〇.jsvar moment = require(“moment”);↓このような書き方で生成できます
〇〇.jsconst dt = new moment();しかし、これだけだとrails sで引っかかります。
↓おそらく、yarnの再インストールが必要になります。error Lockfile does not contain pattern: "moment@^2.29.1" error Found 1 errors. ======================================== Your Yarn packages are out of date! Please run `yarn install --check-files` to update. ======================================== To disable this check, please change `check_yarn_integrity` to `false` in your webpacker config file (config/webpacker.yml).check_yarn_integrityはデフォルトでFalseとなっているので
yarn install --check-filesだけを実行してみますyarn install --check-files問題なく使うことができました
最後に
moment.jsはレガシーな技術で今後はあまり使われなくなるかも知れません。
day.jsの方が軽量で管理面でも上位互換だとも言われていますが,
現役で活躍していることもあるので試験的に使用してみました。移行する際は、この方の記事が参考になります。(勝手に掲載してすいません)
https://qiita.com/oika/items/2d15aea7809ab358ba25
- 投稿日:2020-10-17T16:58:22+09:00
Spree::Productのカラムを解説
solidus使っていると初心者にとっては「。。。ん?」みたいな状態ですよね。
この記事を読まれていると言うことは少し全体像が掴めて、「Spree::Productにはどう言ったカラムが存在するんだ?」と言うところなのかなと思います。
そこで今回は「Spree::Product」内のカラムについて簡潔に紹介と説明をしていきます。Solidusのバージョン
solidus 2.0.9
カラムの紹介と説明
Spree::Productのid=1をのぞいてみましょう。
それではここにあるカラムについて説明します。id
idです。笑
name
商品名。
description(description:説明する)
商品紹介文。
available_on(available:利用可能な)
ストアで買うことができるようになる日付。
未設定の場合、表示されない。deleted_at(delete:削除)
available_onの逆で、ストアで買えなくなる日付。
slug(IT用語:位置を示すコード)
「位置を示すコード」等の意味がある(IT用語)。URL(パーマリンク)の末尾の部分を任意の文字列に指定できる機能があり、SEOにも関係がある。
meta_description(meta:高次〜)
SEO用で、サーチエンジン向けの説明。
meta_keywords
SEO用で、サーチエンジン向けのキーワード。
tax_category_id
商品の税区分
shipping_category_id(shipping:運送)
配送料の指定。
created_at
商品が作られた日時。
updated_at
商品が更新された日時。
promotionable
Promotionルールに基づく金額を生成する。
meta_title
HTMLのtitleタグ用。空欄の場合はnameが代用される。
駆け出しsolidus開発者にとってSpree::Productモデルを理解する糧になれば幸いです!
もし間違っていたらご指摘をお願いします。。
- 投稿日:2020-10-17T16:47:32+09:00
Ruby on Rails で特定のViewにCSS を適用する
Ruby on Rails で作ったWebアプリケーションのあるページで、Tableタグで作った表中の文字が上揃えになっていました。
このままでは見た目が悪いので、上下中央揃えとなるよう、CSSを適用する方法を調べましたので自分用メモとして残します。1.何を修正すれば良いのか?
/marketpurser/app/assets/stylesheets 内のファイルです。
デフォルトで存在するapplication.scss に追記すると、すべてのViewに適用されます。
また、Viewの名前に対応した.scssファイルに追記すると、特定のViewのみに適用されます。2.どう記述すれば良いのか?
CSSと同じ文法で良いようです。
今回はtableクラスを持ったtableタグ内の、tdタグに適用したいので、以下のように記述しました。/marketpurser/app/assets/stylesheetssample.scsstable.table td { vertical-align:middle; }sample.html.erb<table class="table"> <thead> <tr> <th>#</th> <th>Info</th> </tr> </thead> <tbody id="myTable"> <tr> <td>1</td> <td>data1</td> </td> </tbody> </table>解決しました。
なお、単にブラウザを再読み込みするのではなく、もう一度修正したViewのページにアクセスしないとCSSが反映されませんでした。(初歩的なミス)以上、個人的なメモでした。
- 投稿日:2020-10-17T16:00:13+09:00
certbot停止からの再インストール
はじめに
certbotが死にました。。
というよりかは本番環境で運用していたhttps通信の証明証がいきなり破棄されて、戻すのに大変だったので備忘録。開発環境
ruby 2.5.7
Rails 5.2.3
AWS ec2
nginx
puma手順
cd ~ rm -r -f certbot git clone https://github.com/certbot/certbot.git cd certbot/ chmod a+x certbot-auto sudo ./certbot-auto --nginx --debug ※あとはyesに答えるだけエラー集
エラー①
エラーコード
Traceback (most recent call last): File "<stdin>", line 27, in <module> File "<stdin>", line 19, in create_venv File "/usr/lib64/python2.7/subprocess.py", line 185, in check_call retcode = call(*popenargs, **kwargs) File "/usr/lib64/python2.7/subprocess.py", line 172, in call return Popen(*popenargs, **kwargs).wait() File "/usr/lib64/python2.7/subprocess.py", line 394, in __init__ errread, errwrite) File "/usr/lib64/python2.7/subprocess.py", line 1047, in _execute_child raise child_exception OSError: [Errno 2] No such file or directory原因
- pythonのバージョンの不一致
改善コード
alternatives --set python /usr/bin/python2.7エラー②
エラーコード
pkg_resources.DistributionNotFound: The 'virtualenv==15.1.0' distribution was not found and is required by the application原因
- virtualenvのバージョンの不一致
改善コード
sudo pip uninstall virtualenv pip install virtualenv==15.1.0エラー③
エラーコード
pkg_resources.DistributionNotFound: The 'pip==9.0.3' distribution was not found and is required by the application原因
- pipのバージョンの不一致
改善コード
sudo easy_install pip == 9.0.3参考サイト
https://yoshinorin.net/2018/09/10/letsencrypt-cannot-update/
- 投稿日:2020-10-17T15:47:27+09:00
"~"で任意の文字を囲む方法
【概要】
1.結論
2.どのようにコーディングするか
3.開発環境
1.結論
gets.chomp、lengthメソッドを使用する!!
2.どのようにコーディングするか
str = gets.chomp #---❶ str_length = str.length puts('~' * (str_length + 2)) #---❷ puts('~'+str+'~') #---❸ puts('~' * (str_length + 2)) #---❷❶:.chompを入れないと下記のようになります。改行をして2行目の最後の"~"をくっつけています。
❷:lengthメソッドで入力したの文字の長さに +2しています。+2する理由は左上の"~"と右上の"~"の角っこを加えています。
❸:入力した文字の両端に"~”を加えています。3.開発環境
Mac catalina 10.15.4
Vscode
Ruby 2.6.5
Rails 6.0.3.3
- 投稿日:2020-10-17T13:07:08+09:00
curl: (77) error setting certificate verify locations: CAfile: ~/anaconda3/ssl/cacert.pem CApath: none の対処法
- 投稿日:2020-10-17T12:58:17+09:00
[rails] devise導入中のエラー
devise導入中に下記のエラーが出ました。
gemをbundle installしたのち、rails g devise:installを実行。
その後、rails g devise userを実行したのち、rake db:migrateを実行した時に発現したエラーです。エラー
Mysql2::Error: Table 'development.users' doesn't exist /Users/projects/db/migrate/20201016082907_add_devise_to_users.rb:7:in `block in up' /Users/projects/db/migrate/20201016082907_add_devise_to_users.rb:5:in `up' /Users/projects/bin/rails:9:in `<top (required)>' /Users/projects/bin/spring:15:in `<top (required)>' bin/rails:3:in `load' bin/rails:3:in `<main>'Caused by: ActiveRecord::StatementInvalid: Mysql2::Error: Table 'development.users' doesn't exist /Users/projects/db/migrate/20201016082907_add_devise_to_users.rb:7:in `block in up' /Users/projects/db/migrate/20201016082907_add_devise_to_users.rb:5:in `up' /Users/projects/bin/rails:9:in `<top (required)>' /Users/projects/bin/spring:15:in `<top (required)>' bin/rails:3:in `load' bin/rails:3:in `<main>'Caused by: Mysql2::Error: Table 'development.users' doesn't exist /Users/projects/db/migrate/20201016082907_add_devise_to_users.rb:7:in `block in up' /Users/projects/db/migrate/20201016082907_add_devise_to_users.rb:5:in `up' /Users/projects/bin/rails:9:in `<top (required)>' /Users/projects/bin/spring:15:in `<top (required)>' bin/rails:3:in `load' bin/rails:3:in `<main>' Tasks: TOP => db:migrate (See full trace by running task with --trace) =================================解決方法
初学者でまず何が起こっているのかわからなかったので、
現状のテーブルがどれが動いているのか確認しました。rails db:migrate status結果
〇〇-no-MacBook% rake db:migrate:status database: development Status Migration ID Migration Name -------------------------------------------------- up 20201013135213 Create items up 20201014013111 Create users down 20201016082907 Add devise to usersここでdeviseをbundle installする前に、
試しに作っていた、userテーブルができてしまっていることに気がつきました。必要ないかもしれないですが一度テーブルを元に戻すために下記を実行
rails db:rollback全てdownの状態にしました。
その後、不必要な、20201014013111 Create usersを削除rm -rf db/migrate/20201014013111_create_users.rbテーブルを削除した後、
〇〇-no-MacBook% rake db:migrate:status database: NF_development Status Migration ID Migration Name -------------------------------------------------- down 20201013135213 Create items down 20201016082907 Add devise to usersそして
〇〇-no-MacBook% rails db:migrate == 20201013135213 CreateItems: migrating ====================================== -- create_table(:items) -> 0.0173s == 20201013135213 CreateItems: migrated (0.0174s) ============================= == 20201016082907 AddDeviseToUsers: migrating ================================= -- change_table(:users) rails aborted! StandardError: An error has occurred, all later migrations canceled:さらにエラーが出てしまいました。
原因は、deviseをinstallした際に本来、createでできるものがchangeになっておりエラーが発生
下記に修正しました。class CreateItems < ActiveRecord::Migration[6.0] def change→create change→create_table :items do |t| t.string :name t.string :text t.text :image t.integer :category_id t.integer :item_id t.timestamps end end endその後、deviseをアンインストールするために削除
〇〇-no-MacBook% rails d devise user Running via Spring preloader in process 73770 Deprecation warning: Expected boolean default value for '--orm'; got :active_record (string). This will be rejected in the future unless you explicitly pass the options `check_default_type: false` or call `allow_incompatible_default_type!` in your code You can silence deprecations warning by setting the environment variable THOR_SILENCE_DEPRECATION. invoke active_record remove db/migrate/20201016082907_add_devise_to_users.rb remove app/models/user.rb invoke test_unit remove test/models/user_test.rb remove test/fixtures/users.yml route devise_for :usersそして最後に、再度deviseをinstallし正常に動くようになりました。
〇〇-no-MacBook%rails g devise user Running via Spring preloader in process 73899 Deprecation warning: Expected boolean default value for '--orm'; got :active_record (string). This will be rejected in the future unless you explicitly pass the options `check_default_type: false` or call `allow_incompatible_default_type!` in your code You can silence deprecations warning by setting the environment variable THOR_SILENCE_DEPRECATION. invoke active_record create db/migrate/20201016152820_devise_create_users.rb create app/models/user.rb invoke test_unit create test/models/user_test.rb create test/fixtures/users.yml insert app/models/user.rb route devise_for :users初学者なので2,3時間かかってしまいました。
誰かのお役に立てれば嬉しいです。参考
Qitta:【Rails】マイグレーションファイルの削除
https://qiita.com/ISSO33/items/33a935cb3255c269bef2Qitta:Rails 本番環境 ActiveRecord::StatementInvalid (Mysql2::Error: Table 'テーブル名' doesn't exist):
https://qiita.com/ashketcham/items/a0d0a2ac788779895fb4Qiita:Mysql2::Error::ConnectionError: Access denied for user
'root'@'localhost' (using password: YES)の解決法
https://qiita.com/naota7118/items/b62d71484e21d6739d68Qiita:deviseのアンインストール
https://qiita.com/NT90957869/items/8c5285775a67a51f03e1teratall:[rails] devise導入中のエラー
https://teratail.com/questions/214948
- 投稿日:2020-10-17T12:32:45+09:00
Rails zshを使った環境変数 設定の仕方と記述方法
Google Map API を使用中自分で取得したAPIをそのまま記述してGit Hubのpushしてしまいました。
するとGit Hubからこんなメールが…
GitGuardian has detected the following Google Key exposed within your GitHub account.
GitGuardian は、あなたの GitHub アカウント内で公開されている以下の Google キーを検出しました。
素晴らしい!GitHubはこんなことまでしてくれるのだと感動しました。
感動している場合ではないのですぐ環境変数に入れて記述を変えようといろいろ調べたので共有させてください環境変数とは何か
見せたくないものを隠す変数…といったイメージで良いと思います
そして環境変数を設定できるものはたくさんあるのでご自身で良いものを探してみてください!
私の場合はzshを使って環境変数をし設定していきますzshは自称「最強」のシェルらしいです
Zshのインストール方法
初心者向け:Zshの導入
こちらの記事がとてもわかりやすかったです!
こちらの記事からZshをインストールしてきてくださいZshを使った環境変数の設定の仕方
% vim ~/.zshrcで.zsherを開きます
すると
こんな画面になっていると思います
自分はすでにいろいろ設定しているので記述されている内容が多いですが無視してください
この画面が開いたらとりあえず「i」を入力してください
左下に-- INSERT--と出ていると思いますこれをインサートモードと言います
入力ができるようになるのでexport 使いたい変数名='隠したい値' # イコールにはスペースを入れないように気をつけてください例
export GOOGLE_MAP_API='hoge'このように記述すれば設定完了です
インサートモードを抜けるコマンドはescキー抜けれます抜けた後
設定を保存する際は「:wq」
保存しないときは「:q!」
で終了してくださいその後
.zshrcを再読み込みし、定義した環境変数を有効にしますsource ~/.zshrcで環境変数の設定は終わりです。
設定した環境変数の使い方
基本的には
ENV['設定した環境変数']と使います
APIを使用したりしてAPI KEYをviewに記述するときは<%= ENV['設置した環境変数'] %>と記述します
以上になります!
- 投稿日:2020-10-17T10:57:18+09:00
Rails Tutorial 拡張機能の返信機能を作ってみた(その1)
Rails Tutorialの第14章にある拡張機能について
Rails Tutorialをの第14章には、Tutorialを完了した人向けに、自分で機能を拡張するお題がいくつかあります。
最初のお題である、返信機能に挑戦しています。まだ作成途中ですが、できたところまで投稿します。作る要件を確認し、仕様を作る
要件は以下のように書かれています。
Twitterには、マイクロポスト入力中に@記号に続けてユーザーのログイン名を入力するとそのユーザーに返信できる機能があります。このポストは、宛先のユーザーのフィードと、自分をフォローしているユーザーにのみ表示されます。この返信機能の簡単なバージョンを実装してみましょう。具体的には、@replyは受信者のフィードと送信者のフィードにのみ表示されるようにします。
仕様のヒントも書かれています。
これを実装するには、micropostsテーブルのin_reply_toカラムと、追加のincluding_repliesスコープをMicropostモデルに追加する必要があると思います。
要件を具体的にブレークダウンします。
・@replyが表示されるのは、以下の3者
replyの受信者
replyの送信者(自分)
replyの送信者のフォロワー上記以外のユーザーには表示されない
・マイクロポストの先頭に「@reply ユーザーのログイン名」を入力したときに、このポストをreplyと判定
仕様を深堀する、例示されているtwitterを参考にするため調べる
Tutorialの「6.2.5 メールアドレスの一意性」を読み返したところ、大文字と小文字の区分けをするか書いてありました。
ユーザー名に大文字と小文字で区分けをすべきなのか、TaroとTAROを違うものとするかどうかです。
twitterはどうなのかネットで調べます。内部では同じだが、入力時に区分けはするという記事が多かったです。ズバリ書いている記事が見つからなかったです。
メアドと同じ仕様で作ることにします。この大文字小文字の機能は、最初からではなく後で追加することにしました。後から追加するのが簡単そうに見えたためです。
どういう機能を作るか、以前に追加した機能に似ているので読み返す
以前に追加した機能に似ているので、どの機能と似ているか読み返します。
13章のマイクロポストの機能に似ている
6.7章のユーザー登録の機能に似ている
6.2.5 一意性を検証する
メールアドレスの一意性その結果をもとに、以下のような機能を考えました。
・replyで表示する/しないの判定ができる機能をmodelに追加
このpostはreplyかどうか
・@replyの入力を判別する機能をviewまたはcontrollerに追加
・ユーザー名がユニークになるように、modelとviewに追加最後の「ユーザー名がユニーク」の機能は、最初からではなく後で追加することにしました。まずはユニークなテストデータだけで動くものを作ってみて、後からユニークにする制約の機能を付け加えればよいと考えたためです。
機能を詳しく設計する モデル
14章の14.1.1を再度読みます。id間のrelatoinのことでした。
micropostsテーブルのin_reply_toカラムと、追加のincluding_repliesスコープをMicropostモデルに追加する必要があると思います。
をヒントに、modelをどう変更するか考えます。
microposts
列名 属性 id integer content text user_id integer in_reply_to integer created_at datetime updated_at datetime in_reply_to の列を追加するとして、型は何になるか?どのユーザーか特定するのだから、idと同じでintegerと考えました。
機能を詳しく設計する メソッド
micropostのメソッドを追加するか、既存のメソッドを変更するか。
表13.1を参考にします。
user.micrposts Userのマイクロポストの集合をかえす 既存の変更
user.microposts.build(arg) userに紐付いた新しいMicropostオブジェクトを返す 既存の変更
user.microposts.find_by(id: 1) userに紐付いていて、idが1であるマイクロポストを検索する 既存の変更replyのメソッドを追加するか、考えます。
user.microposts.create(arg,reply:user2) user2へのreplyのマイクロポストを作成する
既存のcreateメソッドを変更することにします。機能を詳しく設計する ビュー
画面は主に2つ修正、replyを入力するところと、replyを表示するところです。
入力項目は増やす必要がない、なぜなら、contentの先頭に@replyと記入するからと考えました。
出力でreply専用の画面が必要か?
Twitterを調べます。replyは元Tweetをクリックすると別画面に移ってreplyの一覧を表示しています。replyの親子のTweetを一覧で表示しています。ちょっと複雑なので今回はそこまではやらず、元Tweetと同じ画面に表示することにします。
画面のイメージは、モックを作るのは面倒なのでテキストだけです。
comment box : @reply michael Cum aspermatur ..Feedの表示イメージ
@reply michael Cum aspermatur ..機能を詳しく設計する ビューの入力エラーチェック
user_idが見つからないときは、親切な設計なら入力時にエラーを表示します。createするときにチェックするはずなのでエラーを表示することにします。
postをした後で、user_idが削除されたケースはどうするか?
このmicropostを削除するべきか。もういない人にreplyしたmicropostだけが残っているほうがよいと考え、micropostは削除しないと考えます。所要時間
9/27から10/1までの3.0時間です。
- 投稿日:2020-10-17T04:21:42+09:00
【CircleCI】CircleCIの自動テストでハマった(rails + mysql)【メモ】
はじめに
CircleCIを使ってRailsアプリの自動テストをやろうとしてハマったのでメモ。
特にmysqlコンテナとの接続が上手くいかず、ロクに考えずconfigをいじりまくっていたらCircleCIの無料枠を食いつぶすことになりました。
各種設定ファイルの内容や、エラーへの対策を備忘録として残すことに。環境
CircleCI 2.1 Bundler 2.1.4 Rails 6.0.3.4 ruby 2.6.5 MySQL 5.7開発環境はDocker-composeで構築。
サービス名とコンテナ名の関係は以下のよう。
サービス名 コンテナ名 web webapp_web_1 db webapp_db_1 app webapp_app_1 設定ファイル
アプリ名はwebappとする。
database.ymlとdb.env
データベースの設定ファイル。
この設定がCircleCI側で上手く使えなかったので、今回は以下の記事を参考にCircleCI用のデータベース設定ファイルを作成することにしました。
よって、ここの設定はCircleCIとは関係ないです。
CircleCI 2.0の設定メモconfig/database.ymldefault: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: <%= ENV.fetch('MYSQL_USER') { 'root' } %> password: <%= ENV.fetch('MYSQL_PASSWORD') { 'rootpass' } %> port: 3306 host: db development: <<: *default database: webapp_development test: <<: *default database: webapp_testenvironments/db.envMYSQL_ROOT_USER=root MYSQL_ROOT_PASSWORD=rootpass MYSQL_USER=kagamiya MYSQL_PASSWORD=kagamiyaポートの設定は要らないかも。
host: dbはDocker-composeのサービス名です。
ENV.fetchの{ 'root' }とかも要らないと思います。database.yml.ci
CI用のデータベース設定ファイル。
CirclCIでの自動テストではこちらを使います。config/database.yml.citest: adapter: mysql2 encoding: utf8 pool: 5 username: 'root' port: 3306 host: '127.0.0.1' database: webapp_testconfig.yml
肝心のCircleCIの設定ファイル。
参考はこちら。
CircleCIでテストを自動化circleci/config.ymlversion: 2.1 # バージョン指定 executors: default: working_directory: ~/webapp docker: - image: circleci/ruby:2.6.5-node environment: BUNDLER_VERSION: 2.1.4 RAILS_ENV: test DB_HOST: 127.0.0.1 DB_USERNAME: 'root' DB_PASSWORD: '' - image: circleci/mysql:5.7 environment: MYSQL_ROOT_HOST: '%' MYSQL_ALLOW_EMPTY_PASSWORD: 'true' commands: setup: steps: - checkout - run: name: Update bundler # bundlerのバージョン2へのアップデート command: gem update bundler - run: name: Which bundler? # バージョン確認 command: bundle -v - restore_cache: # キャッシュを読み込む keys: - gem-cache-v1-{{ checksum "Gemfile.lock" }} - gem-cache-v1- - run: name: Bundle Install command: bundle check --path vendor/bundle || bundle install --deployment - save_cache: # キャッシュを保存する key: gem-cache-v1-{{ checksum "Gemfile.lock" }} paths: - vendor/bundle # 以下はRails6でWebpackerを使う場合は必須 - restore_cache: keys: - yarn-cache-v1-{{ checksum "yarn.lock" }} - yarn-cache-v1- - run: name: Yarn Install command: yarn install --cache-folder ~/.cache/yarn - save_cache: key: yarn-cache-v1-{{ checksum "yarn.lock" }} paths: - ~/.cache/yarn jobs: test: executor: default environment: RAILS_ENV: test steps: - checkout - setup - run: name: Wait for DB command: dockerize -wait tcp://127.0.0.1:3306 -timeout 90s - run: name: Use specific database.yml # CircleCI用のデータベース設定を使う command: mv config/database.yml.ci config/database.yml - run: name: Database setup command: | bin/rails db:create bin/rails db:schema:load --trace - run: # 普通のテストとシステムテストを実行する name: Rails Test command: | bin/rails test bin/rails test:system workflows: build_and_test: jobs: - test(MySQLの8系を使う場合は記述の追加が必要なようで、5.7を使うことにしました。
また、rubyのイメージはnodeがついていないとyarnコマンドが使えませんでした。)特にデータベース周りの設定でハマりました。
というのも、私がMySQLの仕様をあまり理解できていなかった(というか今も理解できていない)からで…
当初は参考記事にならって、DB_USER: 'kagamiya' DB_PASSWORD: 'kagamiya' MYSQL_USER: 'kagamiya' MYSQL_PASSWORD: 'kagamiya'としていました。
しかし、そもそもkagamiyaなんていうユーザーはCircleCIのMySQLイメージには登録されていません。(開発環境のdbコンテナにはもちろんありますが)
そこで必然的にrootを使うことになるので、以下のようにしました。DB_USER: 'root' DB_PASSWORD: 'rootpass' MYSQL_USER: 'root' MYSQL_PASSWORD: 'rootpass'しかし、上手くいきませんでした。
というのは、rootユーザーのデフォルトのパスワードは設定されていないからです(多分)。
そういうわけで、パスワードを空にしても上手くいきません。DB_USER: 'root' DB_PASSWORD: '' MYSQL_USER: 'root' MYSQL_PASSWORD: ''というわけで、ユーザーはroot、パスワードはMYSQL_ALLOW_EMPTY_PASSWORD: 'true'として(空を許可?)で接続しなければならないようです。
- image: circleci/ruby:2.6.5-node environment: BUNDLER_VERSION: 2.1.4 RAILS_ENV: test DB_HOST: 127.0.0.1 DB_USERNAME: 'root' DB_PASSWORD: '' - image: circleci/mysql:5.7 environment: MYSQL_ALLOW_EMPTY_PASSWORD: 'true'ここでまたまたエラーを吐きました。
Access denied for user 'root'@'127.0.0.1'ここの理解に苦しんだのですが、どうやら'root'@'127.0.0.1'というユーザーはいないということのようです。
mysqlのユーザー一覧を見てみると、'root'@'%'やら'root'@'localhost'はいますが、'root'@'127.0.0.1'はいません。
mysqlのホスト名(DB_HOST)にlocalhostを使うか127.0.0.1を使うかは、また別の問題として色々あるようです。
しかしながら、今は接続することが最優先なので、rootのホストとして%を指定してやります。
(%は「全てのホスト」という意味だそうですが、よく分かりません)MYSQL_ROOT_HOST: '%' MYSQL_ALLOW_EMPTY_PASSWORD: 'true'理由はどうあれ、これでやっと接続できました。
次に、CircleCIのイメージでは独自のデータベース設定を使うため、database.ymlをdatabase.yml.ciで上書きします。
データベースのセットアップ前に処理を追加します。- run: name: Use specific database.yml # CircleCI用のデータベース設定を使う command: mv config/database.yml.ci config/database.yml私の環境では、指定したデータベース(webapp_test)が無いと怒られたので、データベースの作成を行いました。
- run: name: Database setup command: | bin/rails db:create bin/rails db:schema:load --trace(ここは次回以降の実行でエラーの原因になるかも…?)
まとめ
MySQLの仕様とconfigの内容は理解しきれていません。
configのサンプルは多くの方がアップしておられますが、詳細まで解説されているものが少ない印象です。
よって、自分が理解できていない部分でエラーとなればまたハマる可能性が大ですね…
- 投稿日:2020-10-17T03:01:48+09:00
javascriptを使用して、音声や音楽を流す方法
前置き
私は独学でプログラミング学習を始めて3か月の初学者です。
何度も壁にぶつかりながら、学習を進めていく中で、先駆者の方々の記事に助けられてきました。
私も悩んでいる方の助けになればと思い、記事を投稿することにしました。この記事はWebアプリの制作過程で、Javascript(以後JSと略称を使用します)のイベント時や特定の処理を実施した際に、音声を再生したいという思いから調べた内容がもとになっています。
もともとHTMLにはaudio要素があり、audio要素のsrc属性にファイルの場所を指定して利用することで音声を再生できます。
しかし、Railsの環境下だとファイル場所の指定がうまくいかず、つまずいた結果、『audiojs-rails』というGemを使用することにしました。目的
この記事では、『再生プレイヤーを非表示にして、HTMLのInputボタンを押した際に音声を再生する』ということを目的として記載していきます。アレンジを行えば、特定の処理が終わった後に再生をするということが可能になります。
使用環境
OS:Win10
Rails 5.2.4.4
Ruby 2.6.6
現在はローカル環境で開発中目次
◆Gemのインストールと使用方法
◆特定のイベントによって再生ができるようにアレンジ
◆再生プレイヤーを非表示に!◆使用するGemのインストールと使用方法
1.Gemfileに下記の内容を追加してbundle installを行います。
※rails serverを起動している場合は再起動してください。
gem 'audiojs-rails'2.audiojsの初期化と再生プレイヤー設置
音声データを再生したいViewに下記の内容を記載します。
audiojs.createAll()によって再生プレイヤーが作成されます。
※再生プレイヤーはいらないよ!って方でも、再生できるか確かめるために下記の内容をViewへ記載することをお勧めします
※sample.mp3は、ご自分が用意した音源ファイルの名前に変更してください。<!-- 再生プレイヤー --> <%= audio_tag 'sample.mp3' %> <!-- audiojsの初期化 --> <script> const audioPlayer = audiojs.createAll(); </script>3.assetsパスの追加
上記で設置した再生プレイヤーで読み込んでいる『sample.mp3』は音声ファイルの名前です。
お好きなファイルを用意していただければよいのですが、保存場所には注意が必要です。
必ず、app/assets/audios/に配置するようにしましょう。(私はaudiosのフォルダがなかったので作成しましたが正常に動作しました。)しかし、保存しただけでは使用できませんので、アセットパイプラインで配信するために、assetsパスを追加します。
config/initializers/assets.rb に下記を追加します。config/initializers/assets.rbRails.application.config.assets.paths << Rails.root.join("app", "assets", "audios")4.assetsパスが追加されたか確認する。
皆さんが使用しているコマンドラインで、Rails consoleを起動して下記の内容を打ち込んでください。
Rails.application.config.assets.paths結果として、末尾にaudiosと書かれたフォルダパスが読み込まれていれば問題なさそうです。
※下記のフォルダパスは一例なので、皆さんがWebアプリを保存している場所によって変わります。"C:/Users/sample/ruby/webapp/app/assets/audios"パスが追加されたことを確認したら、再生できるか試してみましょう。
再生ができたら、準備満タンです。◆特定のイベントによって再生ができるようにアレンジをする。
1、ViewにInputタグを追加してIDを設定し、それをScriptで読み込む。
今回は、operationというIDを振って変数に代入しています。
<input type="submit" id="operation"> <script> const operation = document.getElementById("operation"); const audioPlayer = audiojs.createAll(); </script>2.再生プレイヤーの情報をaudio変数に代入して、inputをクリックしたときに、音声の再生を行う。
※必ず、audioPlayerのインデックス番号 [0] を入れた変数を用意してください。
audioPlayer.play();と入力しても動作しません。<input type="submit" id="operation"> <script> const operation = document.getElementById("operation"); const audioPlayer = audiojs.createAll(); # ここから追加した内容 const audio = audioPlayer[0]; operation.addEventListener("click", () => { audio.play(); }); # ここまで </script>なぜ audio に対して audioPlayer[0] を入れなければいけないのかは厳密には理解できていませんが、
audioPlayerの中身をConsole.logで覗いてみると下記のようになっていることがわかりました。
再生プレイヤーを生成したときの情報がaudioPlayerに入っています。
故にインデックス番号0の中身に音声ファイルの情報や、再生や停止といった操作にかかわる情報が入っているため、それを指定しないと動作しないのではないかと推測しています。◆再生プレイヤーを非表示に!
あとは簡単、Audio_tagをDivタグで囲ってあげて、CSSのDisplayをnoneにしてあげるだけです。
<div class="none"> <%= audio_tag 'decision48.mp3' %> </div>最後に
今回いろんな記事の情報を自分なりに操作した内容をまとめてみました。
何かお気づきな点ございましたら、お教えていただけると助かります。
参考にさせていただいた記事もまとめておきますので、ご興味のある方は是非!・【Rails】audiojs-railsの導入からオーディオファイル再生までの手順
↑再生プレイヤーのオプションもまとめられています。再生プレイヤーをいじりたい人は是非。
・MP3を再生するjavascript(audio.js)のメモ
↑jQueryを使用して、再生ボタンや停止ボタンを作っています。応用すればJSだけでも同じことができるかもしれません。
- 投稿日:2020-10-17T00:55:56+09:00
どうやら本番サーバー上でsidekiqをサービスで動かすと環境変数が別物のようだ
概要
AWSのEC2上でsidekiqをsystemdでサービス化して起動していたところ、通したはずのPythonコマンド用の環境変数のPATHが効かない現象が起きたので調査した。
調査
コード中のいろんな箇所にwhoamiや環境変数を確かめるコマンドを差し込んだりした結果、
sidekiqのジョブとPOSTリクエストを受けているcontrollerで実行しているユーザが違うことからsidekiqをサービス起動する設定が怪しいことに気がついた。ちなみにRspecやローカル環境は実行ユーザーに環境変数が効いていたからなのかsidekiqで失敗するジョブもオールグリーンだった。
ところでSystemdってなに?
ってぐぐってみたらこの記事が参考になった。これからSystemd入門する
https://qiita.com/bluesDD/items/eaf14408d635ffd55a18対処法
systemdのsidekiq.serviceファイルの設定を書き換えてはサービスやOSの再起動を繰り返して微調整し、OS起動直後やサービス再起動しても差し込んだコードに環境変数が効く状態になった。
systemdのsidekiq.serviceファイル
環境変数を読みこむシェルスクリプトを実行するようにExecStartPreを追記。
/etc/systemd/system/sidekiq.service[Unit] Description=sidekiq After=syslog.target network.target [Service] WorkingDirectory=/var/www/hoge-app ExecStartPre=/bin/sh /var/www/hoge-app/aws/service/sidekiq_exec_start.sh ExecStart=/root/.rbenv/bin/rbenv exec bundle exec sidekiq -e production ・・・(中略)・・・ [Install] WantedBy=multi-user.targetExecStartPreで実行するシェルスクリプト
sourceで.bash_profile読んだり、exportでなど何らかの形で環境変数を設定(※)した後、systemctlのset-environmentでsystemdでも同じ環境変数を使えるようにする。
※環境によってはどちらか一方かもしくは無くても動くかもしれない。/var/www/hoge-app/aws/service/sidekiq_exec_start.shsource /home/ec2-user/.bash_profile export PYENV_ROOT="$HOME/.pyenv" export PATH="$PYENV_ROOT/bin:$PATH" # systemdにも環境変数を適用 /bin/systemctl set-environment PYENV_ROOT="$PYENV_ROOT" /bin/systemctl set-environment PATH="$PATH" # Python関連の設定処理 pyenv global 3.8.3 eval "$(pyenv init -)" # この時点で設定されている環境変数を任意のログファイルに書き出す。(デバッグ用) LOGFILE=/var/www/hoge-app/log/production.log echo "Sidekiq Service Exec Start Pre --------" >> $LOGFILE echo "$PYENV_ROOT" >> $LOGFILE echo "$PATH" >> $LOGFILE python -V >> $LOGFILE whoami >> $LOGFILE echo "-------------------------------------" >> $LOGFILEサービス再起動
systemctl daemon-reload systemctl restart sidekiq.serviceサービスのステータスがactiveかつ、ProcessのExecStartPreの記載が設定と一致していれば設定は成功。
後は実際にアプリケーションを動作させて確認。[root@ip-*-*-*-* hoge-app]# systemctl status sidekiq.service ● sidekiq.service - sidekiq Loaded: loaded (/etc/systemd/system/sidekiq.service; enabled; vendor preset: disabled) Active: active (running) since Sat 2020-10-31 18:28:39 JST; 3s ago Process: 7130 ExecStartPre=/bin/sh /var/www/hoge-app/aws/service/sidekiq_exec_start.sh (code=exited, status=0/SUCCESS) Main PID: 7731 (bundle) CGroup: /system.slice/sidekiq.service └─7731 sidekiq 6.1.1 hoge-app [0 of 1 busy]
- 投稿日:2020-10-17T00:09:27+09:00
RailsにBootstrapを導入する方法
RubyにBootstrapを導入する方法
手順
- Bootstrapのインストール
- SCSSファイルの作成
- JSファイルの修正
- Rails(Puma)の再起動 ## Bootstrapをgemでインストール
Gemfilegem 'bootstrap', '~> 4.3.1' gem 'jquery-rails'ターミナルbundle installSCSSファイルを作成
ターミナルmv app/assets/stylesheets/application.css app/assets/stylesheets/application.scssapp/assets/stylesheets/application.scss/* * This is a manifest file that'll be compiled into application.css, which will include all the files * listed below. * * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's * vendor/assets/stylesheets directory can be referenced here using a relative path. * * You're free to add application-wide styles to this file and they'll appear at the bottom of the * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS * files in this directory. Styles in this file should be added after the last require_* statement. * It is generally better to create a new file per style scope. * *= require_tree . <(削除) *= require_self <(削除) */ @import "bootstrap"; <(追加)JSファイルを修正
app/assets/javascripts/application.js# 以下の3つを追記 //= require jquery3 //= require popper //= require bootstrap # 元々のコード //= require rails-ujs //= require activestorage //= require turbolinksRails(Puma)を再起動
Dockerfile# Railsに必要なパッケージをインストール RUN apt-get update -qq && apt-get install -y nodejs RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \ && apt-get install -y nodejs # 以下の公式サイトの記述では、node.jsのバージョンが低くてbootstrapが使えない # RUN apt-get update -qq && apt-get install -y nodejsBootstrapの使い方(テンプレート)
app/views/layouts/application.html.erb<!DOCTYPE html> <html> <head> <title>App</title> <%= csrf_meta_tags %> <%= csp_meta_tag %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> </head> <body> <div class="d-flex flex-column flex-md-row align-items-center p-3 px-md-4 mb-3 bg-white border-bottom shadow-sm"> <h5 class="my-0 mr-md-auto font-weight-normal">Company name</h5> <nav class="my-2 my-md-0 mr-md-3"> <a class="p-2 text-dark" href="#">Features</a> <a class="p-2 text-dark" href="#">Enterprise</a> <a class="p-2 text-dark" href="#">Support</a> <a class="p-2 text-dark" href="#">Pricing</a> </nav> <a class="btn btn-outline-primary" href="#">Sign up</a> </div> <p class="notice"><%= notice %></p> <p class="alert"><%= alert %></p> <%= yield %> </body> </html>こうなる!
現場からは以上です!