20210501のRailsに関する記事は30件です。

アセットパイプラインの仕組み(概要)

アセットパイプライ(以下の仕組み) 開発(時) Ruby on Railsのアプリケーション内で使用したいJavaScriptやCSS、画像ファイルを「開発作業がしやすいようにファイルを分割してコーディング WEB表示(時) 最終的にWEBページ表示の際にCSS,JavaScript,Imageファイルなどを「連結・圧縮する」仕組みです。 ・WebブラウザがWebページを表示するために必要なHTMLファイルの元ファイル(.erb)をapp/viewsディレクトリ内に配置します。 ・一方、そのHTMLを装飾するためのCSSファイルや画像ファイル、JavaScriptファイルは、app/assetsディレクトリ内に配置します。 ・stylesheetsディレクトリ内には、CSSファイル。imagesディレクトリには、Imageファイル。javascriptsディレクトリには、JavaScriptファイルを配置します。 記載する内容の種類ごとにディレクリやファイルを分けています。 それは、「開発者にとって、何がどこに記載されているかをわかりやすく認識させるため」です。 Webブラウザには、ひとつのWebページを表示するために複数のファイルを結合する機能は備わっていません。そのため、開発者が作業をしやすいようにファイルをたくさんのディレクトリに分けてしまうと、それらのディレクトリをそのままひとつのWebページとして扱うことができなくなってしまいます。 そこで、このアセットパイプラインの仕組みが考え出されました。 アセットパイプラインは、複数のディレクトリやファイルに分かれたassetsディレクトリ内のファイルをひとつに連結・圧縮する機能です。 Ruby開発・事例サイト 提供:Ruby開発に強いトランスネット https://www.transnet.ne.jp/2016/02/28/rails%E5%88%9D%E5%AD%A6%E8%80%85%E3%81%8C%E3%81%A4%E3%81%BE%E3%81%9A%E3%81%8Dcolnr%E3%80%8C%E3%82%A2%E3%82%BB%E3%83%83%E3%83%88%E3%83%91%E3%82%A4%E3%83%97%E3%83%A9%E3%82%A4%E3%83%B3/
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Herokuへのデプロイ方法

Herokuへのデプロイ方法を備忘録も兼ねて記述します。 なおこれはRails 6.0.0で作成したアプリをHeroku-18デプロイする方法になります。 まず Heroku CLIをインストール ターミナル % brew tap heroku/brew && brew install heroku 次に下記のコマンドを入力 バージョンが出れば成功 ターミナル % heroku --version heroku/7.40.0 darwin-x64 node-v12.16.2 Herokuにログイン ターミナル # Herokuへログインするためのコマンド % heroku login --interactive => Enter your Heroku credentials. # メールアドレスを入力し、エンターキーを押す => Email: # パスワードを入力して、エンターキーを押す => Password: 緑色でメールアドレスが表示されれば成功です。 Heroku上にアプリケーションを作成 ターミナル % cd ~/アプリのあるディレクトリ % pwd #カレントディレクトリを確認 % heroku create アプリケーション名 下記のコマンドを入力し設定が正しくできたか確認 ターミナル % git config --list | grep heroku ClearDBアドオンを追加 ClearDBアドオンとは、MySQLを使うためのツールでHerokuでMySQLを使用できるようになります ターミナル % heroku addons:add cleardb データベースの変更をする Ruby on Railsを使う場合は、MySQLに対応するGemについて考慮する必要があり、そちらの設定を変更する必要があるとのことです ターミナル % heroku_cleardb=`heroku config:get CLEARDB_DATABASE_URL` ターミナル % heroku config:set DATABASE_URL=mysql2${heroku_cleardb:5} # 以下、コマンドの実行結果 Setting DATABASE_URL and restarting ⬢ ○○○○○... done, v◯◯ DATABASE_URL: mysql2://000000000000:0aa0000@us-cdbr-east-02.cleardb.com/heroku_aaa00000000?reconnect=true 次にHeroku上で非公開の値(サーバーのアクセスキーやAPIキーなど)を管理するために暗号化をする必要があります。 credentials.yml.encファイルという外部に漏らしたくない情報を扱う際に用いるファイルがあり、master.keyファイルでその暗号文を復元します。 まずcredentials.yml.encの中身を確認 ターミナル % EDITOR="vi" bin/rails credentials:edit 確認後は、「escキー」→「:」→「q」と入力し、「enterキー」を押して閉じる Heroku上にmaster.keyを設置する Heroku上で環境変数を設定 ターミナル % heroku config:set RAILS_MASTER_KEY=`cat config/master.key` 環境変数を確認 RAILS_MASTER_KEYという変数名で値が設定されていれば成功 ターミナル % heroku config Herokuで利用するStackを指定 Stackとは、Herokuにおけるアプリケーションの動作環境のことでStackはデプロイされたアプリケーションを読み取り正常に稼働させるために用意されています。 下記のコマンドを実行。 ターミナル % heroku stack:set heroku-18 -a アプリケーション名 git push heroku masterを実行 ターミナル % git push heroku master Heroku上でマイグレーションを実行 ターミナル % heroku run rails db:migrate heroku apps:infoで公開を確認 ターミナル % heroku apps:info ===○○○○○○ Addons: cleardb:ignite Auto Cert Mgmt: false Dynos: web: 1 Git URL: https://git.heroku.com/○○○○○○.git Owner: sample@sample.com Region: us Repo Size: ○○○ KB Slug Size: ○○○ MB Stack: heroku-18 Web URL: https:/○○○○○○.herokuapp.com/ あとはURLヘアクスして表示されれば成功
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初心者のためのRuby on Rails環境構築

Ruby on Rails 環境構築 この記事の対象者 ローカル環境でRailsで環境構築を初めてする人 mac 使っている人 Railsチュートリアルや入門レベルで環境構築したことがある人 環境 mac Big Sur Version 11.3 Ruby 2.5.1 Rails 5.2.5 ターミナル bash zshになっている場合は(%で始まる)ターミナル設定からbash($で始まる)に切り替えてください ここからターミナルで行う作業は最初のほうはホームディレクトリで進めてください。 参考書籍 現場で使える Ruby on Rails5 速習実践ガイド(5.2対応) Command Line Tools for Xcodeをインストール $ xcode-select --install - これはHomebrewを使うためにインストールします。かなり重たいのでストレージを気にしてください。 インストールできたら $ xcodebuild -version で確認。 ここで僕はエラーが起きたのですが どうやらXcodeのインストールが必要だったみたいなのでお忘れなく。 Homebrewのインストール Homebrewとは ではHomebrewをインストールしていきます https://brew.sh/index_ja のページに行って/bin/bash....という文字が並んでいるところがあるのでこれをコピペしてターミナルで実行してください。 $ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" インストールできたら $ brew doctor でインストールが正常にできているか確認。 Your system is ready to brew.みたいなことがレスポンスとして返ってきたら問題なしです。 rbenvをインストール $ brew install rbenv rbenvコマンドを利用できるようにする パス設定と初期化処理を.bash_profileに追加。 $ echo 'export PATH="$HOME/.rbenv/bin:$PATH"'>> ~/.bash_profile $ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile これをやる理由 https://qiita.com/1000ch/items/a61e65fe82d8bdea840e Rubyのインストール $ rbenv install 2.5.1 インストールが終わったら、システム全体で使用するRubyのバージョンをrbenvに変更する。 $ rbenv global 2.5.1 最後に正しくrbenvでインストールしたバージョンのRubyが利用できるか確認する。 $ ruby -v $ which ruby ここでうまく行かなかったので、以下の記事を参考にしたら解決できました! Rubyのパッケージ管理ツール「RubyGems」をアップデート Ruby本体だけでも動作するが、公開されているライブラリを使うことでより、生産的にプログラムを書いていくことができる。 最新版のシステムにアップデートしておきます $ gem update --system Bundlerのインストール Bundlerとはgem(ライブラリ)を束ねてどのgemのどのバージョンが必要なのか明示してくれる仕組み。 $ gem install bundler Railsのインストール $ gem install rails -v 5.2.5 Node.jsのインストール WebアプリケーションのフロントエンドにJavaScriptを使う場合、効率よく配信するためにJavaScriptを圧縮するのが一般的。 Railsにもその機能は備わっているが、JavaScriptランタイムが必要なのでNode.jsをインストールする。 $ brew install node データベースのインストールとセットアップ postgresqlのインストール $ brew install postgresql 正しくインストールされているか確認 $ postgres -V(Vは大文字なので注意!) PostgreSQLを起動する $ brew services start postgresql PostgreSQLサーバを立ち上げたらコンソールに入って動作確認 $ psql postgres control + Dで脱出できます PostgreSQLを停止する $ brew services stop postgresql Gemfile編集 https://bamboo-note.tokyo/Ruby/rails-new-error-messages/ この記事をみてGemfileを編集してください アプリケーションを新規作成 rails newでアプリの雛形を作成。データベースをpostgresqlに指定 $ rails new アプリ名 -d postgresql これでアプリフォルダが自動生成されるので、アプリフォルダに移動 $ cd アプリ名 データベース作成 PostgreSQLを起動した状態でデータベース作成コマンドを実行 $ bin/rails db:create railsコマンドではなく、bin/railsにしている理由は、アプリのルートディレクトリ直下のbinディレクトリにある railsというスクリプトを呼び出している。このスクリプトを使うと「bundle exec rails」として実行した時と同様に Gemfile通りのgemを使える環境上でコマンドを実行できるようになります。 サーバ立ち上げ $ bin/rails s ここからアプリの開発を進めてください! おつかれさまでした!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

webサービスを個人で開発・運営するときに知ってほしい6つのこと【個人開発】

初めに 自分が今まで個人開発をしてきて学んだこと、考えたことをまとめます。 筆者について webアプリを作るのが好きでここ一年間、公開したものだけで15個はあります 最近作ったもの(宣伝も兼ねて) AmmotというSNSで、コンセプトは「制限の少ない自由な投稿を」です。 「ツイッターは文字数制限がきつい、ただfacebookは実名制だしデザインがごちゃごちゃでいや」 という声を聴いたので作ってみました。 文字数制限が6000字まで、画像・動画・音声は同時に10個まで投稿可能です。 詳しくはこちらも見てください 1.アイデアを出す方法 一番いいのは自分が困った経験を思い出すことです。 「○○あったらいいのになぁ」「○○がなくなればいいのになぁ」など 特に「このサービス使いにくいなぁ」とか結構いいかもしれません。 そのサービスを使ってる人はある程度自分が作ったサービスに興味を持つだろうし、使う人(ペルソナ)が絞られているので。 ただし急にそんなことを思い出そうとしてもなかなか出ないので、日ごろからメモをしたり 付箋に適当なことを書きまくってそれをグループ分けして要らないものをそぎ落とし、残ったものを順序よく並べて整理するという方法もあります。(KJ法と言われています。) ↓自分の日ごろのメモ まともなアイディアがありませんね。はい アイディア出しの注意 めちゃ個人的意見ですが 基本的には悩みを解決するタイプ以外のwebアプリは使われにくいです。 理由は二つ。 1.検索されないから。 「なんかおもろいwebサービスないかなぁ」で検索されることはほぼないです。 ユーザーがwebサービスを探す理由は基本的に困ったことがあるからです。 2.実際に使ってくれる人が少ない 緊急でもないので 「面白そうだな」とは思ってもそこから実際に使ってくれる人は非常に少ないと思います。 そう考えるとBoketeってすごい 2.開発する前のアイディアの確認 開発する前に確認するべきことは大体こんな感じ 自分はそのサービスを使うか。 なぜそのサービスを作りたいのか。 悩みをどうやって解決することができるサービスでしょうか。 最初は日本語だけで運営可能か 個人で管理できるか ほぼコンテンツがいらない or 自分で初期コンテンツが作れる 1~2年は運用できそうか 差別化はできそうか ユーザーにどんな体験を与えるか 一番重要なのは「自分はそのサービスを使うか」です。 自分が使うサービスは成功しやすいです。 開発してる時もユーザーの気持ちなどをいちいち考えず「自分がどうしたら使いやすいか」という主観的な目線で作れるからです。 ただ注意してほしいのは「これは自分も使う!」と思って開発したが結局自分は使わなかったというパターンです。 これを防ぐのは結構難しいですが、いったん休憩をしてみて落ち着いた状態でもう一回そのアイディアを見つめなおすと良いかもしれません。 3.開発中 意識してるのは2つ デザインを重視する これは結構意見が分かれがちですが僕はデザインはかなり重要だと思ってます。 最初はデザインなんて適当でいいやと思っていましたが トップページのデザインは、ユーザーがどのくらい登録してくれるかに大きく左右します。 動作速度を見る railsは素の状態で使うと結構遅いので工夫が必要です。 僕がやってるは countメソッドを使わない キャッシュを使う scriptにはasync属性を付ける turbolinksは絶対に外さない render collectionを使う くらいですかね。 それでもAmmotはそこそこ遅いので困ってます。 4.リリースしたら qiita service-safari zenn note つくログ twitter 最低でもこのくらいは宣伝したほうがいいです。 無料で宣伝できるところがあったらなんでもやるくらいの心がけで挑みましょう。 名言: 宣伝はやりすぎるくらいがちょうどいい 5.少し過疎ってきたら... 内容を変えて再度、qiitaやnoteに宣伝してみる。 ログインをしないとコンテンツが見えないようにする 投稿時刻などを見せない など ツイッターやQiitaではスパム報告をされない程度に全力でやりましょう。 過疎ったということは一度は人を寄せ付けたということですから。 6.諦めるタイミング 何度も宣伝したが無理... 完璧に過疎った...PV数0 某掲示板製作者のひ○ゆきという方が言っていました 「口コミで広がらないサービスは伸びない」 宣伝をしたら最低でも100人くらいの人が作ったwebアプリを見てくれると思います。それを何度かやって無理なら、あきらめましょう。 期間でいえば大体1月くらい公開・宣伝して全く無反応だったらやめましょう。 愛着があるサービス程、閉鎖は悲しいと思いますがあなたの中でその失敗の原因を探して今後に生かせば失敗しても「作ってよかった」といえる日がくるはずです。 まとめ 一番重要なのは 自分が使うサービスを作ろう ただそれでも失敗することはあるので webアプリを当てるのは結構難しいのでへこまず前へ進もう。 数を作ろう(そのためにスピードを上げよう) 最後に僕の作ったAmmotもぜひ使ってみてください! AmmotのURL https://ammot.net/ 僕のAmmotのアカウント https://ammot.net/user/yamada(%E9%96%8B%E7%99%BA%E8%80%85) 僕のツイッターアカウント https://twitter.com/yamada1531
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】実務未経験の介護士が共同開発に参加して学んだこと

0. はじめに はじめまして! この記事では、「実務未経験の介護士の私が Rails 共同開発に挑戦し、そこで学んだことや躓いたこと、反省した点」などについてまとめています。 チームでの開発現場経験を積むことで、「コミュニケーションの適切な取り方」や「わからない部分の質問の仕方」、「コンフリクトの解消の仕方」など、一人での学習では決して学ぶことのできない貴重な経験を積ませていただくことができました。 今回はそのような共同開発の現場で実際に学んだことをまとめて、今後の自分の成長につなげることができたらなと考えております! 1. 自己紹介 まずは簡単な自己紹介からさせて頂きます! スペック 27歳 介護士 → エンジニアを目指している駆け出しエンジニア 学習中の言語:Ruby, Ruby on Rails 今後学習予定の言語や知識:Javascrict, AWS 趣味 カラオケ(高音域が出ないことが悩みなので、いつかボイストレーニングを習いたい) 野球(球速は遅いが、コントロールには安定感がある) 筋トレ・運動全般(毎日頑張っています?) メンタリストDaiGoさんの動画を視聴しながら、実用的な技術を生活に取り入れる 性格 介護士として忍耐強く働いてきたということもあり、衝動的な性格から理性的に行動するように。 比較的、温厚な性格だと思う。 2. 今回の共同開発に参加しようと思った動機 まず、「なぜ今回の共同開発に参加しようと思ったのか?」の根本的な動機の部分を述べさせて頂きます。端的に言うと、以下のものを「得たい!」と思ったので、共同開発に参加させて頂きました。 コミュニケーションスキルの向上 チームでの開発経験 問題にぶち当たった時に自分で原因を特定し、解決を図るための「自走力」 試行錯誤した上でどうしてもわからない場合、素直に質問できる柔軟性 これらのものを「共同開発」に参加することを通して獲得したいなと思いました。 結果的に、特に「コミュニケーション」の部分に関してはスキルの向上ができたのと、以前よりもより自信を持つことができた気がします。 ここについての具体的なやり取りに関しては後述させて頂きます! 3. Rails 共同開発で取り組んだ内容 共同開発で取り組んだ内容を簡単にご説明していきます! 成果物 今回の共同開発では「ECサイト」の購入者視点の画面の実装に取り組みました。 概要 開発期間:3/1 ~ 4/30(2ヶ月間) 週1回のチームミーティングを行い、進捗状況の確認を行う 週2~3回の作業会を行い、それぞれわからないところを質問し合う 構成メンバー 講師・TA:現役エンジニア2名 共同開発メンバー:現役インフラエンジニア1名、未経験2名 使用した言語・技術 バックエンド Ruby(バージョン:2.7.1) Ruby on Rails(バージョン:6.0.3.5) フロントエンド HTML5 CSS3 Bootstrap(5.0.0.beta2) インフラ Docker docker-compose データベース MySQL2(0.5.3) 使用したツール・環境 Slack:レビュー依頼、進捗状況の確認、日報の共有などをしました。 GitHub:タスク管理・確認、プルリクエストを出す、コードレビューを受ける、受けた指摘に対応し、コミットを出すなどをしました。 Googleドライブ:モックアップ、基本設計(ER図/画面遷移図)、画面定義書などのファイルを管理・共有のために使用しました。 Git / Sourcetree:コミットやプッシュなどの git 操作をするために利用しました。 Sequel Pro:DB を視覚的に管理できるツール Boost Note:「1タスク1メモ」といった感じで、学んで点や躓いた点を随時メモしました。 DeepL:英語対策のための翻訳アプリ 使用したエディター:Visual Studio Code 使用したPC:Mac ER図 実装した機能 新規ユーザ登録機能 ログイン / ログアウト処理 商品検索 商品詳細へ カートへ カートを開く 購入確定 Top画面に戻る 履歴を開く 注文検索 注文キャンセル ユーザ情報を開く ユーザ情報修正 / 退会処理 修正確定 GitHub https://github.com/quest-academia/qa-rails-ec-training-violet 4. Rails 共同開発で私が担当した箇所 ①ユーザー登録ページ 「お客様情報登録」にお客様(ユーザー)が登録に必要な情報を入力するためのページを作成しました。 ②商品詳細画面 ■ 商品が存在する場合 ■ 商品が存在しない場合 「商品詳細画面」を商品が存在する場合と存在しない場合の二つに分けて、それぞれの画面が表示されるようなページを作成しました。 ③商品検索画面 ■ 検索結果にヒットする商品が存在する場合 ■ 検索結果にヒットする商品が存在しない場合 「商品検索画面」に検索フォームや商品の一覧、ページネーション機能などを入れて、お客様(ユーザー)が商品を検索できるようなページを作成しました。 5. 【必ず身に付けておきたい】 講師に学んだプルリクエストの出し方 共同開発では、開発業務以外にも Git や GitHub の操作方法がとても学びになりましたが、その中でも特に「 Pull Request(プルリクエスト )の出し方」が個人的には参考になりました! 今後の開発を進めていく上での基礎として、必ず身に付けておきたいと思いました。 ▼ プルリクエストを出す際の雛形となるテンプレート 以下は講師が提供してくださったテンプレートを元に僕が作成したプルリクエストの一例です。 プルリクエスト出す際は、以下のようなフォーマットをもとに作成しました。 プルリクエストの最終的な確認項目 このプルリクエストで実行したこと(概要) 対象 issue 重点的に見て欲しいところ(不安なところ) 実装できなくて後回しにしたところ チェックリスト(動作確認・ rubocop の実行など) その他の参考情報(参考にした記事のリンクなど) このようなフォーマットを元に書くことによって、レビュアーの方にとってわかりやすいプルリクエストの作成に繋がると感じました。 特に「重点的に見て欲しいところ(不安なところ)」の項目では、「問題に躓いた時にうまく人に頼れるスキル」も大事になって来ると思うので、不安だったことについては小さなことであっても、必ず書くようにしました。 また、予想完了時間や実質完了時間、作業内容、納期などもタスクに取り組む前に予測・設定しました。実務では「担当するタスクを細かい作業項目に分解して、一つずつ取り組んでいくスキル」が必要になってくると思うので、思いつく限りのことはなるべく言語化して書くようにしました。 作業内容は、最初は全ての作業項目を洗い出すことはできず、取り組みながら後から修正を加えたりしました。 ただ、プルリクエストを出してマージされるまでにかかった時間が、予想完了時間を大幅に超えてしまっていたり、納期が遅れてしまったりしたことは反省点です? はじめから無理な目標を設定しすぎない方が良いと思いました。 ▼ 1指摘1コミット また、コードレビューを受ける際は「1指摘1コミット」でやり取りをするようにしました。つまり、複数の指摘を同時に受けたとしても、対応する際は一つずつコミットを出して個別に対応していくということ。 これは講師の方から「意外と知らない人が多いけど、大事なこと」として教わりました。 以下のような感じです↓ 基本的なことかもしれませんが、こう言った基礎的なことが個人的にはとても大事になってくると思うので、今後も実践を通して身に付けていきたいです。 6. Rails 共同開発で躓いた点・大変だったこと 共同開発において躓いたことや大変だったこと、またそれに対する僕の対応です! 主に、以下の2点でつまずきました。 ① コンフリクトの発生 ② if文を用いた View ファイルの条件分岐 ① コンフリクトの発生 コンフリクト発生に関しては、共同開発が始まった初っ端から躓いてしまい、かなり焦りました? まだ始まったばかりなのにいきなり難しい問題に出くわして「自分にはやっぱり向いてないんじゃないかな・・・」と勘違いしてしまった記憶があります? その時はなんとか解決したいと思い、検索を繰り返し問題への対処に当たりました。 とりあえず問題の理解と解決策がなんとなく理解できたので、それを実行しようと思う意思とそれが今後の開発にあたり問題のない対処法かどうかを確認をしたかったので、講師の方に質問してみました。 以下が僕が講師の方に質問させていただいた際のやり取りの記録になります。 僕からの講師への質問 (Slack より引用)文字が小さくてすいません? この質問への講師からの回答は1往復で済み、なんとか「コンフリクトの解消」にまで至りました! とても嬉しかったですし、次回以降同じような問題に出くわしたとしても、以前のように無駄に焦ったりはしなくなりました。 ② if文を用いた View ファイルの条件分岐 「if文を用いた商品に関しての条件分岐」については、 html.erb 内で if 文を使って「商品が存在するページ」と「商品が存在しないページ」に分岐することができるようにするタスクだったのですが、メソッドの書き方が間違っており、苦戦しました。 苦戦したコードの内容:商品テーブルから指定されたIDの商品の詳細を取得する 本来はコントローラー内で以下のように記載しなければなりませんでした。 def show @product = Product.find_by(id: params[:id]) end しかし僕は、以下の二つの間違いをずっと繰り返していました。 def show @product = Product.find(params[:id]) # ← find_by を使ってない end def show @product = Product.find_by(params[:id]) # ← find_by の引数にカラム指定をしていない end 最終的には講師の方に記述ミスを指摘してもらい、解決に至りましたが、「find_by メソッドを使う時はカラムを指定する」というところがすっかり抜けていました。 このようにコードの記述ミス然り、アルファベットの記述ミスやファイル名の命名違い、全角スペースでのインデントなど、細かいミスがまだまだ目立つなと思いました。 今後はこのようなミスをできるだけ少なくできるよう、必ず独自の「メモ」を取るようにして、同じ間違いを繰り返さない工夫をしたいと思います。 7. Rails 共同開発に参加して良かったこと 2021年3月頃までは僕は主に一人でプログラミング学習に取り組んでいました。 しかし、将来的にもしエンジニアになることができたら、一人での開発ではなくチーム単位での開発となり、お互いの進捗状況を確認しあったり、わからないことを相談しあったりするなどと言った「協調性」が必ず必要になってくると思いました。 そのため、早めにそのスキルを身につけておくことによって、「技術面でのサポート」はどうしても頂かなければならない時が多々あるかと思いますが、そのような技術的なサポートをして頂く際の「質問力」であったり、互いにスムーズで円滑なやりとりを行うための「コミュニケーション能力」の面においては、なるべく一緒に仕事をさせていただく方々の負担にならないようにしたいなと思いました。 また、個人的に「チーム単位での活動」や「誰かと協力すること」、「コミュニケーション能力」にいささかの不安があったため、実際の現場に近い環境で現役のエンジニアさんやチーム開発参加者たちと共に「テキストベース」や「 ZOOM などでお互いに顔を合わせた状態でのコミュニケーション」に積極的に参加して場数を踏むことによって、苦手分野を克服したいなと思いました。 たとえここで失敗したとしても、苦手分野の克服に挑戦したことによって自分なりの改善策や解決策などのデータが得られると思ったので、積極的に挑戦して行くべきだと判断しました。 ありがたいことに今回の共同開発では、みなさん向上心があり親切な方々ばかりだったので支えて頂いたことの方が多かった印象があるのですが? 、それでも僕なりに役に立ちそうな情報は共有するようにしたり、読み手に負担をかけないわかりやすい文章を作成することにとても神経を使いました。 この経験によって、コミュニケーションのスキルが今までよりも段違いに向上したのではないかと思います。 8. さいごに【まとめ】 今回この「共同開発」というものに参加させてもらうことによって、 コンフリクトの解消 GitHub の見方・操作・やりとりの仕方 Git の操作やプルリクエストの出し方 開発するものに対する意思の疎通や進捗状況の確認 タスクへの取り組み方や管理の仕方 などの個人での開発・学習では決して学ぶことのできない多くのことを学び、経験させていただきました。 また、現役のRailsエンジニアの方からは「技術力は正直まだまだ足りてないですが、コミュニケーションの取り方はハイレベルですね」といった評価をして頂けたのはとても嬉しかったです! 今後はこれらのことをよりスムーズにできるようにブラッシュアップさせて、実務に入った時に周りの方々に「この人との仕事は余計なストレスがないし、スムーズでやりやすいな」と思ってもらえるように、備えて行きたいと思います。 拙い文章でしたが、最後までご覧頂き、ありがとうございました! Twitter :@kunikuni2992
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ActionController::RoutingError - uninitialized constant GraphiQL::Rails::EditorsController エラーの解決方法

困ったこと Rails 6 環境でGraphQLを実装するためこちらのサイトを参考に各種セットアップをしていたところでした。 rails generate graphql:install コマンドを実行後、 http://localhost:3000/graphiql を開いたところ、以下エラーが発生した... ActionController::RoutingError at / uninitialized constant GraphiQL::Rails::EditorsController 前提 以下の Gem を利用している環境とする rails (6.1.3.1) graphql (1.12.8) graphiql-rails (1.7.0) 解決方法 答えは Gem 本家のIssueに投稿されていたコメントでした。以下を追記後、Railsサーバーを再起動したら GraphiQLの画面が表示できました config/initializers/zeitwerk.rb Rails.autoloaders.each do |autoloader| autoloader.inflector = Zeitwerk::Inflector.new + autoloader.inflector.inflect( + 'graphiql' => 'GraphiQL' + ) end 関連 uninitialized constant GraphiQL::Rails::EditorsController · Issue #43 · rmosolgo/graphiql-rails Rails + GraphQLでAPI作成 fxn/zeitwerk: Efficient and thread-safe code loader for Ruby
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Rails] Rspecでテストコードの実装①

はじめに 本日より何回かに分けて、テストコードに関しての知識をこちらでアウトプットできればと思います テストの必要性 絶対に壊れない機械がないように、絶対に不具合のないシステムはありません。しかし、サービスの一時停止や不具合は、サービスへの信頼度を著しく下げ、ユーザ離れを引き起こします。(もっといろいろな問題はありますが) こうした問題を起こさないように、ちょっとでも防ぐためにテストを行います。例えば、何か新しい機能を追加した時に他の機能との競合を確認しないままリリースしてしまえば、メイン機能が止まる可能性もあるわけです。とはいえ、毎回機能実装のたびに手動で確認するのは非効率でミスが起こりやすいです。そこで活躍するのが、テストコードです。 テストコードとは。 テストコードとは、動作を確認するためのコードを書くことで、自動で挙動確認するという方法です。こうしたコードをテストコードと言います。Railsにおいては、今回、テストコードの実装にはRspecを使います。 基本的に、境界値分析など様々なテストケースの考え方があります。この記事では、特にわかりやすい正常系と異常系のテスト行います。 正常系 「ユーザーが開発者の意図する操作を行った時の挙動」をテストするもの 異常系 「ユーザーが開発者の意図しない操作を行った時の挙動」をテストするもの テストの種類 テストは大きく分けて単体テストと結合テストの2つがあります。 単体テスト モデルやコントローラーといった機能ごとのテスト。例えば、バリデーションが本当に機能しているかなどを調べます 結合テスト ユーザーがブラウザで操作する一連の流れを再現して、問題がないか確かめます。例えば、「ユーザはログイン情報を入力し、送信ボタンを押したら、成功した旨が表示されマイページにと遷移するかどうか」を確認したりします。 テストコード実装準備① テストコードの実装には、Rspecというgemを使用します。早速インストールしましょう。 Gemfileに以下を記載しましょう group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] gem 'rspec-rails', '~> 4.0.0' end ターミナルでbundle installを忘れないように!!!! 次に、Rspecの設定をします。 以下のように、コマンドを打ってください。 rails g rspec:install このコマンドで生成されたファイルのうち.rspecファイルを開き、以下のように記述します。 テストコードの結果をターミナル上に可視化するための記述です。 --require spec_helper --format documentation テストコード実装準備 ここからはUserモデルのテストコードを書く準備を行います。 rails g rspec:model user これを行うと、以下のファイルが生成されます。 spec/models/user_spec.rb require 'rails_helper' RSpec.describe User, type: :model do pending "add some examples to (or delete) #{__FILE__}" end これからはこのファイルにテストコードを記述していくこととなります。 ちなみに、一行目のrails_helperはRspecを用いてRailsの機能をテストするときに、共通の設定を書いておくファイルです。各テスト用ファイルでspec/rails_helper.rbを読み込むことで、共通の設定やメソッドを適用します。 rails gコマンドでテストファイルを生成すると、rails_helperを読み込む記述が、自動的追加されます。 おわりに 今回は一旦概念の理解と準備までを完了しました! 次回は実際にテストコードを実装していきましょう!!!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【個人開発】挫折しない目標達成アプリ「tumiki」を作りました。

はじめに webエンジニアとして働き始めてはや1年たちました。 土日にちまちま作ったwebアプリが完成したので、紹介します。 Youtubeに動画も載せていますので、文字読むのめんどいよ...!ってかたはこちらでも。 サービスの概要 https://www.tumiki.work ほとんどの人が挫折する、目標達成を手助けるアプリです。 自分も含め、目標達成ができなくて悩んでいる人が多いと感じ、 その課題を解決できるような工夫を詰め込みました。 使い方 1.目標を登録する 達成したい目標 達成に必要な行動 その目標を達成したいとおもった理由(価値観) 目標のカテゴリ を入力します。 2.積み上げ記録をつける 目標を達成するために必要な行動(先程登録したもの)をしたら、 記録をつけます。 3.ランクを上げて目標達成 積み上げ記録を付けるとランクが上がります。 ランクがlv.10まで上がると、目標達成できます。 他の目標達成アプリにない強み 1.海外大学の目標達成フレームワークを使用 目標達成率が上がると証明されている、目標達成フレームワークMACの法則を使用しました。 Measurable(メジャラブル:測定可能性) Actionable(アクショナブル:行動可能性) Competent(コンピテント:適格性) 以上の3つのポイントを目標作成画面に取り入れて、ユーザーが目標を立てる段階で、 目標達成率を上げられるように工夫しました。 2.モチベーションが上がるランクUP機能 積み上げ記録が増えるとランクが上がるようになっています。 普段目標に向けてなにかしても、目標が叶うまでは、達成感を味わえないため、 途中で挫折してしまう人が多いかと思います。 そこで、ランクUP機能をつけることで、目標に向けて進んでいる感をユーザーがもてるように工夫しました。 3.みんなの目標が見れる tumikiでは登録している方の目標、行動記録が見えるようになっています。 目標の途中で 次何をしたらいいかわからない そもそもどんな目標を立てたらいいのかわからない。 そんな人は他の方の目標をみて参考にできますし、 一緒に頑張る仲間を見つけることもできます。 使用技術 使用言語 Ruby on Rails HTML CSS (bootstrap) 開発環境 Docker デプロイ AWSのEC2 完成までにかかった道のり 土日にちまちま作って、約4ヶ月かかりました。 1月 アプリの設計作業とDockerで開発環境を整える 冬休みからアプリの作成を開始しました。 どうせ作るなら、誰かに使ってもらえるサービスにしたい...!と思い設計作業にかなり時間がかかってしまった。。。 いろんなツールを使ったのですが、個人サービスのようなものだったら、 紙にモックを作るだけで良かったかも。 とはいえ、 絶対につけたい機能とそうでない機能の洗い出し モデルの設計 は、早く完成させるためにも、ちゃんとやっておいてよかったなぁと思いました。 下記に私がやった設計作業について書いてあるので、きになる方はぜひ。 Dockerは初めて使ったのですが、便利ですが、Docker特有の部分で結構躓くところが多かった。 本当に初心者のかたは、ローカルではじめに開発したほうがいいのかなと思いました! 2月、3月 開発作業 最初にバックエンドの機能を大体終わらせて、それからフロントを整えるという形にしました。 バックエンドは特に難しいこともせず、フロントもbootstrapを使っていたので、 とくに詰まることなくスムーズにいきました。 2月 開発し始めはバックエンドから 3月 フロントやり始めた 4月 デプロイ 4月は1ヶ月ぐらいデプロイの作業をしていました。 これが本当にしんどかったです。笑 いままでは、ローカル環境にHerokuでデプロイすることしかしてませんでしたが、 Dockerを環境構築に使う NGINXをサーバーで使う AWSでデプロイする という3つの初めての挑戦にかなり苦戦しました。 ここで学んだことは、わかったふりしてすすめると最後に痛い目にあうということです笑 Dockerや、AWSはコピペでやればなんとかなるかーと思っていましたが、 詰まったとき、なんで動かないんだろう?がわからず、デバッグとかもできないので、 なんの知識もないと終わってしまいます。 実際私もこれが起き、基礎からDockerや、AWSについてYoutubeや本で学びなおしました。 そして、なんとかデプロイすることができました...!!! 最後に 大変なこともありましたが、何よりも個人開発を通してプログラミングが好きになりました。 tumikiについては、自分も使うし、今後も改善したり、新たな機能をつけていきたいと思いますので、 ぜひ楽しみにしていてください!! 制作過程を載せた Youtube note Twitter もよろしければ見ていただけると幸いです。 読んでいただきありがとうございました!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Rails & PostgreSQL]rails db:createをするとPG::InsufficientPrivilege: ERROR: permission denied to create databaseが発生

Postgres初心者です。エラーを解決した備忘録として残しておきます。 環境 Amazon Linux2 Rails 6.0.3 Posgres 11.5 起きていること 本番環境でrails db:createを入力したところ以下のようなエラーが発生した $ rails db:create RAILS_ENV=production PG::InsufficientPrivilege: ERROR: permission denied to create database Couldn't create 'travelour_production' database. Please check your configuration. rails aborted! ActiveRecord::StatementInvalid: PG::InsufficientPrivilege: ERROR: permission denied to create database bin/rails:4:in `<main>' Caused by: PG::InsufficientPrivilege: ERROR: permission denied to create database bin/rails:4:in `<main>' Tasks: TOP => db:create (See full trace by running task with --trace) 解決方法 どうやらデータベースの作成権限がないらしい。そこでpostgresにログインして、権限を付与していく #ログイン $ psql -U postgres ALTER ROLEコマンドでデータベース作成権限を与える postgres=# ALTER ROLE {ユーザ名} WITH CREATEDB; ALTER ROLE その後serviseコマンドで再起動 sudo service postgresql restart これでrails db:createコマンドができるようになります。 rails db:create RAILS_ENV=production Created database `travelour_production`
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

RSpec導入手順

最近RSpecを使い始めたので、導入手順をメモ 環境 Rails 6.0.3.6 MySQL Docker --skip-testを指定して new Gem Gemfile . group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] gem 'capybara' gem 'rspec-rails' gem 'factory_bot_rails' end . webmock等は一旦入れない予定で。 RSpecをインストール bin/rails g rspec:install Running via Spring preloader in process 167 create .rspec create spec create spec/spec_helper.rb create spec/rails_helper.rb 上のように4つ作成される。 .rspec : RSpec用の設定ファイル spec : スペックファイルを格納するディレクトリ spec/spec_helper.rb, spec/rails_helper.rb : RSpecでカスタマイズするヘルパーファイル テスト用のDB準備 bin/rails db:migrate RAILS_ENV=test RSpecの書式変更 --format documentation を追加することで、RSpecの出力を読みやすいドキュメント形式に変更することができる --require spec_helper --format documentation FactoryBot設定追加 以下の様に設定することで、FactoryBotのメソッドの呼び出しが楽になる。 spec/rails_helper.rb RSpec.configure do |config| config.include FactoryBot::Syntax::Methods end (例) # 設定前 user = FactoryBot.create(:user) # 設定後 user = create(:user) rails_helper.rbに設定追加 Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f }がコメントアウトされているので、それを外す。 そうすることで、spec/support/配下のファイル を読み込むことができる。 spec/rails_helper.rb require 'spec_helper' . . Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f } . RSpec.configure do |config| . . RSpecを起動してみる ここまで設定したら、動作確認してみましょう bundle exec rspec No examples found. Finished in 0.00231 seconds (files took 0.17073 seconds to load) 0 examples, 0 failures テストファイルは書いていませんが、RSpecが動作していることは確認できました 後日、capybaraの設定等を追加します 参考記事 RailsアプリへのRspecとFactory_botの導入手順 【Ruby on Rails】RSpec導入まで
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CRUDについてのまとめ

CRUD アプリケーションのデータ取り扱いに関して、基本的な処理の頭文字を並べたものです。 アプリケーションの機能は、この4つの処理を組み合わせながら実装します。 C(Create) R(Read) U(Update) D(Delete) 生成 読み取り 更新 削除 Railsでは、CRUDを7つのアクションに分割して、処理を実現します。 7つのアクション CRUDを実現するためには、それぞれの処理を記述する必要があります。 Ruby on Railsには、それらのアクションの設定が慣習的に決められており、下記の表のようなアクションが存在します。 アクション名 内容 index 一覧表示 show 詳細表示 new 生成 create 保存 edit 編集 update 更新 destroy 削除 これを本カリキュラムでは、「7つのアクション」と呼んでいます。 これらの7つのアクションのルーティングは、resourcesメソッドを使用することで一度に設定が可能です。 resourcesメソッド resourcesは、7つのアクションへのルーティングを自動生成するメソッドです。 resourcesの引数に、:tweets というシンボルを指定すると/tweetsのパスに対応するルーティングが生成されます。 例】resourcesメソッドの使用例 Rails.application.routes.draw do resources :tweets end 上記のように記載すると、以下のような7つのアクションすべてのルーティングを設定したことになります。 例】resourcesメソッドで自動生成されるルーティング GET /tweets(.:format) tweets#index POST /tweets(.:format) tweets#create GET /tweets/new(.:format) tweets#new GET /tweets/:id/edit(.:format) tweets#edit GET /tweets/:id(.:format) tweets#show PATCH /tweets/:id(.:format) tweets#update PUT /tweets/:id(.:format) tweets#update DELETE /tweets/:id(.:format) tweets#destroy
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Ruby on Rails】途中でカラムを追加・削除する

概要 アプリ作成途中に「追加でこの情報もテーブルに保存したい!」「このカラムはいらん!」と思う時は多々ありますよね、、、 そんな時のために「カラムを追加・削除する方法」を記載しておきます!! (環境構築とモデルの作成はできている状態です) 環境 ruby 2.6.5 Rails 6.0.3.5 【カラムを追加する】 追加するカラム Usersテーブルにnameカラムを追加する ①追加するカラムのマイグレーションを生成 % rails g migration Add[カラム名]To[テーブル名][カラム名:型]  (見本) % rails g migration AddNameToUsers name:string (実行するコマンド) 以下のマイグレーションファイルが自動で作成されます。 db>migrate>〇〇〇〇〇〇_add_name_to_users.b class AddNameToUsers < ActiveRecord::Migration def change add_column :users, :name, :string end end ②追加したマイグレーションファイルをテーブルに反映 % rails db:migrate これでテーブルに新しくカラムが追加されます。 【カラムを削除する】 削除するカラム Usersテーブルのnameカラムを削除する ①削除するカラムのマイグレーションを生成 % rails g migration Remove[カラム名]To[テーブル名][カラム名:型]  (見本) % rails g migration RemoveNameToUsers name:string (実行するコマンド) 以下のマイグレーションファイルが自動で作成されます。 db>migrate>〇〇〇〇〇〇_remove_name_to_users.b class RemoveNameToUsers < ActiveRecord::Migration def change remove_column :users, :name, :string end end ②作成されたマイグレーションファイルをテーブルに反映 % rails db:migrate これでUsersテーブルのnameカラムが削除されます。 参考リンク Railsのデータベースでカラムを追加する方法 -Qiita Ruby on Rails カラムの追加と削除 -Qiita
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ActionView::Template::Error (ActiveStorage::InvariableError)の対処法

エラー概要 記事投稿画面から、画像を選択し投稿した際に起こったエラー。データベースには登録されていたが、ブラウザにはエラー画面が出ていた。 原因 拡張子がHEIC形式のものを投稿した際に、エラーが出ていた。jpgやpngの場合は投稿できた。 解決方法 rais db:migrate:resetをして、データベースにあるものをリセットすると、エラー画面はなくなる。HEIC形式以外の画像を添付すると、エラーは解決された。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【メモ】RSpecの準備・セットアップ

はじめに RSpecの導入手順を記しとこうと思います。 ここではRSpec, FactoryBotの導入部分を書いていきます。 Gemfileの編集 次の様にGemfileを編集する。 Gemfile group :development, :test do #すでにあるブロックに下3行を追加 gem "rspec-rails" gem 'spring-commands-rspec' gem "factory_bot_rails" end 自分用(Rubyのバージョンを変えたらエラーが出たため) Rubyのバージョンが 3.0.0 以上の場合、Gemfileに以下を記入 これを記入しないとrspecコマンドを実行してもエラーが出る。 Gemfile gem 'rexml', '~> 3.1', '>= 3.1.9' そしてbundle installする。 RSpecのインストール コマンドラインで次のコマンドを実行。 rails g rspec:install 次のコードを.rspecファイルに追加。 .rspec --format documentation Config/Application.rbの編集 次のコードを追加。 config/application.rb class Application < Rails::Application config.generators do |g| g.test_framework :rspec, controller_specs: true, fixtures: true, helper_specs: true, model_specs: true, request_spec: false, routing_specs: false, view_specs: false end end これでRSpecの導入は終了。 以下、RSpecコマンド ・モデルスペック rails g rspec:model user ・システムスペック rails g rspec:system projects FactoryBotの設定 rails_helperを編集。 *必須ではない rails_helper.rb RSpec.configure do |config| #元からあるこのブロックに以下の1行を追加 config.include FactoryBot::Syntax::Methods end これがあることで次の様に簡潔にコードか書ける。 # 通常の呼び出し方 user = FactoryBot.create(:user) # 上のコードを書いたことにより省略形が使える様になる。 user = create(:user) おわりに 以上で導入完了です。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

未経験者が頑張ってWebアプリを作ってみた

初心者が頑張ってそこそこモダンな技術を使ってポートフォリオアプリケーションを作ってみました。 使用技術 Docker Docker-compose Ruby 2.6.5 Rails 6.0.0 AWS(EC2,S3,VPC) になります。 もう本番環境に上げています なのでこちらのリンクを踏めばすぐに飛ぶことができます。 http://13.208.108.131:3000/ どういったアプリなのか 僕はよくブロガー兼Youtuberの人を見るときがあります。 そうでなくてもツイッターとYoutubeで活動している方を見ることがあるのですが、その時に思うのは、 プラットフォームの移動がめんどくさい って言うことなんですよね。 TwitterいってからYoutubeに行ってコンテンツを楽しむ しかもその上にブログ記事を書いている人にはブログ記事もチェックしないといけない いつも思っていました。 俺が見たいのはブログなどのコンテンツであって読み込み画面や別のタブを開いて検索をかけてとかがしたいわけではない なので、それらをすべて一つのアプリケーションにまとめることができれば楽だなと思ったので、まだまだサービスとしては至らない点は多いですがそういった思想のもと作ってみました。 このアプリの紹介というか思い出話 このアプリでは3つの分類にページが分かれています。 ・ブログ ・つぶやき ・動画 した2つにはバリデーションをかけています。なので、動画以外を動画投稿のページで投稿してしまうと、バリデーションによって弾かれてしまいます。 その機能を作ろうとした時に、どうやってもバグになってしまうんですよね。 普通にやろうとすると、動画投稿のページで普通に動画を投稿しようとすると動画を投稿しているのにバリデーションで弾かれてしまうんですよね。 なので、ActiveStorageに対してバリデーションをかけられるGemを追加していくことで対応しましたね。 あと印象に残っているのは、 No Method Errorになてしまった時に、チェックするのは基本的にはコントローラーなのですが、底があっているときにはどこを見たらいいかというと、マイグレーションファイルとモデルを見ていくと解決の糸口になるということがわかったときはすごい良かったとお思いました。 それにその頃からエラーが起きてしまってもどこを見ていったらいいかを構造的に考えていくといったことができるようになったので、良かったなと 初学者にありがちなのが、 コピペに頼るあまり構造がわかっていない。 だからエラーになったとしても対処ができない、仕組みや構造がわかっていないから。 それを解消できるきっかけはやっぱりこのアプリをつくったときですね。 エラーになっても、構造から逆算して考えるようになったので、成長が早くなったというかスタートラインに立つことができたなと感じました。 あと頑張ったことといえばActionTextを導入したことですね。 Rails6からの機能で、Railsでかんたんにブログが投稿できるようになるっていうものですね。 なので、追加してみたのですが、初心者には難しかったですね。 何より情報がすくねぇっていう問題があったので、、 本当にググっても情報がまじで出てこねぇっていうことが頻発したので、めちゃくちゃ大変だったんですよね。 ユーザーとの関連付けも大変だったのですよはい。 ・ActionTextに関するマイグレーションファイル ・Blogに関するマイグレーションファイル ・ActiveStorageに関するマイグレーションの3つが生成されるのですが、その時に俺間違えてActionTextに関するマイグレーションファイルの方にユーザー情報を関連付ける記述をしてしまったので、投稿する時に ユーザー情報なんてねぇよって怒られてましたw まぁソレはBlogのマイグレーションファイルに記述すればよかったのでいいんですけどね。 あとはオブジェクトについてまなんだりしました それと非同期いいね機能も学んだので、すげぇ良かったです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

devise機能にカラムを追加する方法

diviseにカラムを追加する方法 deviseの実装後にnicknameカラムを追加したくなったので今回は追加の手順をメモする。まずはDBにあるdeviseのマイグレーションファイルにnicknameカラムを追加する。今回はnicknameなのでstring型で追加する データベースを変更するためにターミナル上でロールバックを行う まずは編集したいdbが何番目にあるか確認する! % rails db:migrate:status database: アプリ名_development Status Migration ID Migration Name -------------------------------------------------- up 20210428012237 Devise create users 今回はまだdeviseのマイグレーションファイルしか存在しないので1つのみUPになっている。❗️ちなみに下から何番目か数える❗️ 次にロールバックのコマンドを記入する % rails db:rollback STEP=○ 今回は1番目なのでSTEP以降の記述はいらない。 その後にもう一度マイグレーションファイルの現状を確認するために先ほどと同様に以下のコマンドを入力 % rails db:migrate:status database: アプリ名_development Status Migration ID Migration Name -------------------------------------------------- down 20210428012237 Devise create users 上記のようにdownになっていれば変更可能の状態になっている。 今回はdeviseのマイグレーションにnicknameカラムを追加したいので以下のコードを記載する # frozen_string_literal: true class DeviseCreateUsers < ActiveRecord::Migration[6.0] def change create_table :users do |t| ## Database authenticatable ここから追加 t.string :nickname, null: false     ここまで追加 t.string :email, null: false, default: "" t.string :encrypted_password, null: false, default: "" 変更が終了できたら、ターミナルでdbをマイグレートする % rails db:migrate これで問題なければ反映されている? 最後に確認でDBのschema.rbに追加したカラムのコードがあれば成功! 感想 4月は学校の新生活やコロナウイルスの騒動であまりプログラミングをできていなかったがGWから時間を確保できるので再開していこうと思う? 今回は初心に帰ってdbの変更方法をQiitaに書いてみた? dbの変更の手順はいつになっても使うことなのでこの記事の手順は絶対に忘れないようにしよう!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

rails -sでサーバの起動ができない

rails -sでサーバを起動しようとするも、 boot.rbファイルがないためエラーが発生 ターミナルには下記のようなエラーが表示されている。 wrong number of arguments (given 2, expected 1) (ArgumentError)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails LINEbot 入門

Rails×LINEbotの実装方法と一連の処理の流れを説明しています。 ※Railsに関しては一通り学習を終えていることが前提 まず一連の処理の流れ ※WEBサーバは何でも問題ないですが、以下の例ではHerokuを使用している想定です。 ①LINEアプリで自分が作成したチャネルを友達登録し、メッセージを送信します。 ②LINEのサーバではそのメッセージを受信し、チャネルに設定したWebhook URLにリクエストを送信します。 ③リクエストを受信したRailsサーバは受信した内容を参照し、色々と処理をした結果、最終的にレスポンスとなるメッセージを作成します。 ④レスポンスメッセージをLINEサーバに返します。 ⑤LINEサーバがレスポンスメッセージをLINEアプリに返します。 一つずつ解説 ①LINEアプリで自分が作成したチャネルを友達登録し、メッセージを送信します。 まずLINEbotを作るにはLINE Developersに登録する必要があります。 こちらから登録しましょう。 LINEアカウントがあればすぐに登録できます。 登録が終わったらまずしなければいけないことは プロバイダーの作成 チャネルの作成 になります。 プロバイダーとは今回の場合、開発者(=自分)のことを指します。 チャネルは要するにメッセージを受け取るための公式アカウントです。 こちらのドキュメントにプロバイダーの作成、チャネルの作成の説明がありますので、確認しながら作成してください。 ※作成するチャネルの種類は「Messaging API」になります。 ②LINEのサーバではそのメッセージを受信し、チャネルに設定したWebhook URLにリクエストを送信します。 さてチャネルを作成したので、LINEアプリから友達登録をしてみましょう。 LINE Developersコンソールから トップ > プロバイダー名 > チャネル名 > Messaging API設定 > ボット情報 を表示すると ボットのベーシックID というのがあり、このIDをLINEアプリで検索することで友達追加することが可能です。 応答メッセージの無効化 現時点でメッセージを送信すると このようなメッセージが返ってくると思います。 今回のLINEbot作成では不要な機能なので、設定を変更します。 LINE Developersコンソールから トップ > プロバイダー名 > チャネル名 > Messaging API設定 > LINE公式アカウント機能 応答メッセージを無効にします。 Webhook設定 LINEサーバから自分が開発したWEBアプリにリクエストを送信するための設定をします。 LINE Developersコンソールから トップ > プロバイダー名 > チャネル名 > Messaging API設定 > Webhook設定 Webhook URLの設定とWebhookの利用をONにします。 ※「www.example.com」は自分が作成したアプリのURLを設定してください。 ※この例ではcallbackアクションがLINEbotのリクエストの受付先となります。 ③リクエストを受信したRailsサーバは受信した内容を参照し、色々と処理をした結果、最終的にレスポンスとなるメッセージを作成します。 次にRails側の実装をしていきたいところですが、先にLINEサーバに接続するためのアクセストークンを発行しましょう。 LINE Developersコンソールから トップ > プロバイダー名 > チャネル名 > チャネル基本設定 > チャネルシークレット チャネルシークレットを発行します。 LINE Developersコンソールから トップ > プロバイダー名 > チャネル名 > Messaging API設定 > チャネルアクセストークン チャネルアクセストークンを発行します。 上記の チャネルシークレット チャネルアクセストークン がLINEサーバに接続するために必要な情報になります。 こちらが漏洩すると自分が作成したチャネルを悪用されてしまうので、注意しましょう。 今度こそRailsの実装をしていきたいと思います。 公式の説明はこちらです。 まず、Gemfileに gem 'line-bot-api' を追加してbundle installをしましょう。 最初にルーティングの設定をします。 Rails.application.routes.draw do post '/callback', to: 'linebot#callback' end そしてコントローラを作成します。 class LinebotController < ApplicationController # LINEbotを使用するための設定を読み込み require 'line/bot' # CSRFトークン認証を無効 protect_from_forgery :except => [:callback] def client # LINE APIクライアントのインスタンスをアクセストークンなどを使用して生成 @client ||= Line::Bot::Client.new { |config| # アクセストークンは環境変数に設定 # トップ > プロバイダー名 > チャネル名 > チャネル基本設定 > チャネルシークレット config.channel_secret = ENV["LINE_CHANNEL_SECRET"] # トップ > プロバイダー名 > チャネル名 > Messaging API設定 > チャネルアクセストークン config.channel_token = ENV["LINE_CHANNEL_TOKEN"] } end def callback body = request.body.read signature = request.env['HTTP_X_LINE_SIGNATURE'] # 開発環境でやると認証が通らないことがあったため、本番環境でのみ署名の認証を行う # (LINEアプリからの送信ということを示すための署名) if Rails.env.production? unless client.validate_signature(body, signature) head :bad_request return end end # LINEサーバから送信されてきたメッセージ、各種情報を取得 events = client.parse_events_from(body) events.each { |event| case event when Line::Bot::Event::Message case event.type when Line::Bot::Event::MessageType::Text # 送信されてきたメッセージを取得 received_msg = event.message['text'] # 今回はオウム返し message = [ { type: "text", text: received_msg } ] # ④レスポンスメッセージをLINEサーバに返します。 client.reply_message(event['replyToken'], message) end end } head :ok end end あとはデプロイをして動作確認をしましょう。 ※環境変数の設定を忘れずに! ⑤LINEサーバがレスポンスメッセージをLINEアプリに返します。 ここまでできたらアプリの完成です。 うまくできたでしょうか。 今回はただのオウム返しアプリになりますが、受信したメッセージの内容によって処理を分岐すれば色々なことができると思います。 私の場合は、毎日出社したときにあるものを提出しなければならず、非常に面倒だったので、LINEbotから送信して提出できるようにしました。 LINEであれば毎日開くのでついでにルーチンワークができるようになれば楽ですよね。 テキストメッセージ以外の受信 前述のコントローラでは case event when Line::Bot::Event::Message case event.type when Line::Bot::Event::MessageType::Text このように受信した情報がどいうものなのかを判断しています。 公式情報の例を覗いてみると events.each do |event| case event when Line::Bot::Event::Message handle_message(event) when Line::Bot::Event::Follow reply_text(event, "[FOLLOW]\nThank you for following") when Line::Bot::Event::Unfollow logger.info "[UNFOLLOW]\n#{body}" when Line::Bot::Event::Join reply_text(event, "[JOIN]\n#{event['source']['type']}") when Line::Bot::Event::Leave logger.info "[LEAVE]\n#{body}" when Line::Bot::Event::Postback message = "[POSTBACK]\n#{event['postback']['data']} (#{JSON.generate(event['postback']['params'])})" reply_text(event, message) when Line::Bot::Event::Beacon reply_text(event, "[BEACON]\n#{JSON.generate(event['beacon'])}") when Line::Bot::Event::Things reply_text(event, "[THINGS]\n#{JSON.generate(event['things'])}") when Line::Bot::Event::VideoPlayComplete reply_text(event, "[VIDEOPLAYCOMPLETE]\n#{JSON.generate(event['videoPlayComplete'])}") when Line::Bot::Event::Unsend handle_unsend(event) else reply_text(event, "Unknown event type: #{event}") end 色々あるようですね。 友達追加したとき ブロックしたとき グループに追加したとき グループから削除したとき ファイルが送信されたとき etc... 友達追加のタイミングでユーザー登録処理などを実装することも可能です。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MVCその1.ルーティングについて

“初学者向け基礎知識”MVCにおけるルーティングについて ここではルーティングの意味と、MVC各機能の詳細について触れます。 大まかな概要部分については、下記の記事でまとめました。 https://qiita.com/TechOtome/items/bb7886fa9fcb7e0a5c18 MVCの処理の流れ 図1.リクエストからレスポンスまでの処理の流れ 説明の前に ここでは、Ruby on Railsを用いたMVCの記述を紹介しています。 ・Ruby: プログラミング言語の一つ。記述がシンプルで分かりやすいことから人気。大きなWEBアプリーケーションにも小さなプログラムにも対応できる。 ・Ruby on Rails: Rubyで作られた”フレームワーク”のこと。 ・フレームワーク:WEBアプリを作成する上で必要なツールを準備する必要があるが、 フレームワークは既に”必要となる作業やリソース”を用意している。簡潔に言えば、フレームワークを使って開発した方が作業が減って楽。 ルーティングについて 一言で書くと ”クライアントからのリクエストの処理を振り分ける。” 仮にユーザーが”A.com”というURLをクリックしたら、”A”というページを表示する(レスポンスとして返す)ように処理を振り分けます。 Twitterであれば「新しいツイートをする」「プロフィール画面を表示する」「フォロワー一覧を見る」「フォロワーのツイート一覧を見る」などなど。さまざまな処理がありますが、これらは全て一度ルーティングにリクエストが送られて、どのような処理をするのか振り分けてから、コントローラーからレスポンスが送られてユーザーが受け取ることができます。 実例)ルーティングでトップページを見るには? リクエストと言っても、具体的な中身がイメージしにくいと思います。 例えば”Tweet”というアプリがあって、そのトップページを見たいというリクエストがあった場合のルーティングは下記の記述になります。 get ’/tweets’, to: ’tweets#index’ 上記の記述は3つに分けることができます。 またそれぞれの意味も一緒に記述します。 ・get →HTTPメソッドの”GET” ・/tweets →URIパターン(URIとURLは別のものですが、WEBページのアドレスではURIもURLも同じ意味を指します。) (※URI解説参照: https://webtan.impress.co.jp/e/2010/03/09/7539) ・tweets#index →リクエストの行き先=tweetsというコントローラ名のindexアクション ルーティングでは、リクエストで”HTTPメソッド”と”URI”パターンを受け取りリクエストの行き先を記述します。 HTTPメソッド ‘URIパターン’, to ‘コントローラー名#アクション名’ HTTPメソッドとアクションとは? ここで、MVCの記述における重要な2つの用語を簡潔にまとめます。 1.HTTPメソッド HTTPメソッド:HTTP通信の中で行いたい処理の種類のこと。HTTPリクエストメソッドとも言う。8つ存在する。 HTTP通信:WEBアプリはインターネットを通じて利用することができる。その時のデータの送受信の通信方法をHTTP通信と呼ぶ。 図2.代表的なHTTPメソッド4つ 2.アクション アクション:MVCにおけるコントローラー内の処理の種類のことを言う。コントローラーではルーティングから受け取ったリクエストに対応する処理をする。 図3.MVCのコントローラーアクション 終わりに MVCのメリットの一つに「処理の記述が整理されている」点がありますが、このようにアクション名でどんな処理をするのかが理解できます。 MVCを使ったアプリ開発では、HTTPメソッドとアクション名を理解することがとても重要です。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

「remote: ! Could not detect rake tasks...」というエラーが表示された場合の対処法

bundlerのバージョンを変更しよう git push heroku master 実行時に「remote: ! Could not detect rake tasks」「remote: ! ensure you can run $ bundle exec rake -P against your app」とエラーが表示される場合は、bundlerのバージョンがエラーの原因である可能性が高いです。 そのため、以下の手順に従って、bundlerのバージョンを変更しましょう。 bundlerのバージョンを変更しましょう ① 現在入っているbundlerを削除します
以下のコマンドを実行しましょう。 ターミナル # 何度か確認を求められますが、「y」を入力してエンターを押しましょう % gem uninstall bundler ② bundlerのバージョン2.1.4を指定してインストールします
以下のコマンドを実行しましょう。 ターミナル % gem install bundler -v '2.1.4' ③ Gemfile.lockを削除します
テキストエディタでAjaxAppを開きます。
「Gemfile.lock」を右クリックし、「削除」を選択しましょう。  ④ Gemfile.lockを作り直します
以下のコマンドを実行しましょう。 ターミナル % bundle install ⑤ 変更をGitHubへ反映させます
GitHubDesktopより、commit と pushを行いましょう。 ⑥ Herokuにアプリケーションの情報を追加します
以下のコマンドを実行しましょう。 ターミナル % git push heroku master 下記のようにエラーが出ていなければ、デプロイ完了です。
今後、開発環境のAjaxAppに追加機能を実装し、その変更をHeroku上のAjaxAppにも反映したい場合は、同じ様にmasterブランチにコミットし、Herokuにプッシュする必要があります。 
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Heroku上にアプリケーションを作成しよう

Herokuにアプリケーションを作成し heroku createコマンド Heroku上に公開するアプリケーションを作成します。*すでに登録されているアプリケーション名は使用できません。 ターミナル % cd ~/projects/ajax_app % pwd #「ajax-app」にいることを確認する % heroku create ajax-app ClearDBアドオン ClearDBアドオンとは、MySQLを使うためのツールです。ClearDBというデータベースサービスが提供しているアドオンで、これを追加することにより、HerokuでMySQLを使用可能となります。 ターミナル % heroku addons:add cleardb Creating cleardb on ⬢ ajax-app... free Created cleardb-vertical-00000 as CLEARDB_DATABASE_URL Use heroku addons:docs cleardb to view documentation これでデータベースをMySQLに設定できました。Ruby on Railsを使う場合は、MySQLに対応するGem設定を変更します。 ターミナル % heroku_cleardb=`heroku config:get CLEARDB_DATABASE_URL` これでClearDBデータベースのURLを変数heroku_cleardbに格納できました。 ターミナル % heroku config:set DATABASE_URL=mysql2${heroku_cleardb:5} 以下、コマンドの実行結果 Setting DATABASE_URL and restarting ⬢ ajax-app... done, v◯◯ DATABASE_URL: mysql2://000000000000:0aa0000@us-cdbr-east-02.cleardb.com/heroku_aaa00000000?reconnect=true Heroku上で非公開の値を管理する仕組み アプリケーションを開発する際、サーバーのアクセスキーやAPIキーなど、外部に漏らしたくない情報を扱う場面があります。デプロイをする際、それらの情報はセキュリティの観点から暗号化する必要があります。暗号化された情報は、開発環境および本番環境であらかじめ用意した鍵を用いて復号(暗号化された情報を使えるように)します。 Railsのバージョン5.2以降では、credentials.yml.encを利用して、それらの情報を暗号化します。 credentials.yml.encファイル Railsにて、外部に漏らしたくない情報を扱う際に用いるファイルです。通常時は、英数字の文字列で構成された暗号文が表示され、ファイル内に何が書かれているのか分からないようになっています。しかし、このcredentials.yml.encと対になるmaster.keyが存在する場合、credentials.yml.encの暗号文を復号し、ファイル内の記述を確認できます。 master.keyファイル credentials.yml.encの暗号文を復号する、鍵の役割を持ったファイルです。特定のcredentials.yml.encと対になっているため、その他のcredentials.yml.encへは、効果を発揮しません。 また、master.keyは非常に重要なファイルなので、リモートリポジトリに反映されることは好ましくありません。そのため、デフォルトで.gitignoreに記述されており、Gitで管理されない仕組みになっています。 credentials.yml.encの中身を確認しましょう まずは、ターミナルのAjaxAppディレクトリにて、下記のコマンドを入力しましょう。 下記のコマンドは、credentials.yml.encをmaster.keyによって復号し、中身を確認するためのコマンドです。 ターミナル % EDITOR="vi" bin/rails credentials:edit 以下のような画面が確認できれば、credentials.yml.encをmaster.keyによって復号し、中身を確認できた状態と言えます。 次に、他のファイルと同様の方法で、credentials.yml.encの中身を確認してみましょう。 テキストエディタにてAjaxAppディレクトリを開き、config/credentials.yml.encを開きましょう。 先ほど確認した内容と異なり、以下の様な暗号文のみが確認できます。 credentials.yml.encは、master.keyを用いない場合には暗号文として表示されること credentials.yml.encは、master.keyとセットで扱うことで中身が解読可能になること このように、credentials.yml.encはmaster.keyとセットで扱います。 しかし、先にお伝えしたように、セキュリティの面から、master.keyはデフォルトでGitに管理されない仕組みとなっています。 この後、HerokuへAjaxAppのコードをデプロイしますが、その際にデプロイされるコードというのは、Gitで管理されているコードになります。つまり、master.keyはこのままだとHeroku上へデプロイできず、credentials.yml.encもHeroku上で扱えないということになります。 そこで、Heroku上に別途master.keyを設置し、Heroku上でもcredentials.yml.encを扱えるようにしましょう。 Heroku上にmaster.keyを設置しよう Heroku上には、環境変数としてmaster.keyの値を設置します。Herokuへ環境変数を設定するためには、 heroku configというコマンドを使用します。 環境変数 OSが提供するデータ共有機能の1つで、「どのディレクトリ・ファイルからでも参照できる変数」を設けることができます。一般的な用途の1つとして、「外部に漏らしたくない情報を環境変数にセットする」というものがあります。 環境変数のイメージとしては、特定の値を格納する箱を思い浮かべましょう。今回は、RAILS_MASTER_KEYという環境変数(箱)を用意し、その中にmaster.keyの値を入れるという使い方をします。この様に設定をすると、外部にmaster.keyの値を漏らすことなく、使用できます。 その環境変数を設定するためには、heroku configというコマンドを使用します。 heroku configコマンド Heroku上で環境変数の参照・追加・削除等をする場合に用います。環境変数の追加であればheroku config:set 環境変数名="値"と実行します。そうすることによって、Heroku上で環境変数を追加できます。 Heroku上で環境変数を設定しましょう Heroku上に環境変数を設定します。 ターミナル % heroku config:set RAILS_MASTER_KEY=`cat config/master.key` Heroku上で環境変数を確認しましょう 設定が正しくできているか、Herokuの環境変数一覧を表示してみましょう。下記のコマンドを入力してください。 ターミナル % heroku config 以下のように、RAILS_MASTER_KEYという変数名で値が設定されていれば成功です。 動作環境を変更しよう デプロイをする前に、Herokuで利用する環境を指定しましょう。Herokuには、Stack(スタック)という環境が用意されています。 Stack Stackとは、Herokuにおけるアプリケーションの動作環境のことです。Stackはデプロイされたアプリケーションを読み取り正常に稼働させるために用意されています。デフォルトのStackは「Heroku-20」です。一方で、別のStackを選択することもできます。 みなさんが開発に使用してきたRubyのバージョンは、Heroku-20では使用できません。 そのため、Rubyのバージョン2.6.5が動作するStackを指定しましょう。 Herokuで利用するStackを指定しましょう ターミナル % heroku stack:set heroku-18 -a ajax-app 既にHerokuへpush済みの方へ。2021年1月に、HerokuのStackがHeroku-18からHeroku-20へと更新されました。そのため、以前にデプロイをされた方でも、デプロイの際に「The Ruby version you are trying to install does not exist on this stack.」とエラーが出てしまう場合は、上記のコマンドを実行しましょう。 Herokuへアプリケーションを追加しよう. Herokuにデプロイする際には、Gitの仕組みを使用するのでした。Gitで管理しているリポジトリをHerokuへ反映することで、Heroku上で該当するアプリケーションの操作が可能になります。Gitで管理しているリポジトリをHerokuに反映するためにはgit push heroku masterというコマンドを用います。 git push heroku masterを実行しましょう 下記のコマンドを入力し、HerokuへAjaxAppの情報を追加しましょう。 ターミナル % git push heroku master git push heroku master 実行時に「remote: ! Could not detect rake tasks」「remote: ! ensure you can run $ bundle exec rake -P against your app」とエラーが表示される場合は、こちらをご確認ください。 https://qiita.com/takuo_maeda/items/267d38f7dfc23bc4e41f 今後、開発環境のAjaxAppに追加機能を実装し、その変更をHeroku上のAjaxAppにも反映したい場合は、同じ様にmasterブランチにコミットし、Herokuにプッシュする必要があります。 Heroku上でマイグレーションファイルを実行しよう Herokuにアプリケーションの情報を反映することができました。しかし、データベースにはマイグレーションの情報が反映されていません。rails db:migrateを実行したいところですが、そのままコマンドを入力しても実行できません。Heroku上で実行したいコマンドの頭には、heroku runをつけましょう。 heroku runコマンド Heroku上で実行したいコマンドに用います。rails db:migrateであればheroku run rails db:migrateと実行します。そうすることによって、Heroku上でコマンドが実行できます。 ターミナル % heroku run rails db:migrate Running rails db:migrate on ⬢ ajax-app-123456... up, run.8920 (Free) D, [2020-05-08T08:22:50.410454 #4] DEBUG -- : (2.9ms) SET NAMES utf8mb4, @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'), @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483 D, [2020-05-08T08:22:50.467023 #4] DEBUG -- : (2.6ms) SELECT @@innodb_file_per_table = 1 AND @@innodb_file_format = 'Barracuda' D, [2020-05-08T08:22:50.479166 #4] DEBUG -- : (11.6ms) CREATE TABLE `schema_migrations` (`version` varchar(255) NOT NULL PRIMARY KEY) D, [2020-05-08T08:22:50.499390 #4] DEBUG -- : (12.0ms) CREATE TABLE `ar_internal_metadata` (`key` varchar(255) NOT NULL PRIMARY KEY, `value` varchar(255), `created_at` datetime NOT NULL, `updated_at` datetime NOT NULL) D, [2020-05-08T08:22:50.504699 #4] DEBUG -- : (2.4ms) SELECT GET_LOCK('410119075843185555', 0) D, [2020-05-08T08:22:50.525145 #4] DEBUG -- : (2.8ms) SELECT `schema_migrations`.`version` FROM `schema_migrations` ORDER BY `schema_migrations`.`version` ASC I, [2020-05-08T08:22:50.527632 #4] INFO -- : Migrating to CreatePosts (20200407082548) == 20200407082548 CreatePosts: migrating ====================================== -- create_table(:posts) D, [2020-05-08T08:22:50.545176 #4] DEBUG -- : (11.5ms) CREATE TABLE `posts` (`id` bigint NOT NULL AUTO_INCREMENT PRIMARY KEY, `content` text, `created_at` datetime NOT NULL, `updated_at` datetime NOT NULL) -> 0.0126s == 20200407082548 CreatePosts: migrated (0.0128s) ============================= D, [2020-05-08T08:22:50.559351 #4] DEBUG -- : (2.4ms) BEGIN D, [2020-05-08T08:22:50.562044 #4] DEBUG -- : primary::SchemaMigration Create (2.5ms) INSERT INTO `schema_migrations` (`version`) VALUES ('20200407082548') D, [2020-05-08T08:22:50.573840 #4] DEBUG -- : (11.5ms) COMMIT D, [2020-05-08T08:22:50.584601 #4] DEBUG -- : ActiveRecord::InternalMetadata Load (3.2ms) SELECT `ar_internal_metadata`.* FROM `ar_internal_metadata` WHERE `ar_internal_metadata`.`key` = 'environment' LIMIT 1 D, [2020-05-08T08:22:50.595802 #4] DEBUG -- : (2.5ms) BEGIN D, [2020-05-08T08:22:50.598379 #4] DEBUG -- : ActiveRecord::InternalMetadata Create (2.4ms) INSERT INTO `ar_internal_metadata` (`key`, `value`, `created_at`, `updated_at`) VALUES ('environment', 'production', '2020-05-08 08:22:50', '2020-05-08 08:22:50') D, [2020-05-08T08:22:50.607963 #4] DEBUG -- : (9.4ms) COMMIT D, [2020-05-08T08:22:50.610566 #4] DEBUG -- : (2.4ms) SELECT RELEASE_LOCK('410119075843185555')
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

whereの使い方

whereの使い方 ■whereの基本形 モデル名.where(カラム名: 値)」 User.where(age: 20) 「Userテーブルの中でageカラムが20のレコードを検索」という意味になります。 ※複数ヒットすれば複数のレコードを返します。なお、ヒットするidのレコードが見つからない場合は、ActiveRecord_Relationクラスの空配列を返します。 条件の指定(最初のヒットデータ) モデル名.where(カラム名: 値).first」 User.where(age: 20).first 条件の指定(最後のヒットデータ) モデル名.where(カラム名: 値).last」 User.where(age: 20).last 条件の指定(選んで取り出す2) モデル名.where(カラム名: 値).offset 整数」 User.where(age: 20).offset 5 20才のデータを1から5番目までは飛ばして6番目から取り出す 条件の指定(選んで取り出す) モデル名.where(カラム名: 値).limit 整数」 User.where(age: 20).limit 5 20才のデータを5つ取り出す 条件の指定(並び順) モデル名.where(カラム名: 値).order(asc/desc)」 User.where(age: 20).order(asc) asc 小さいものから順に並べる desc 大きいものから順に並べる 条件の複数指定(AND検索) #whereの引数には、複数の条件を指定することができます。 User.where(age: 20, sex: 'male', payment: true) 上記は「Userテーブルの中でageが20かつsexがmaleかつpaymentがtrueのレコードを検索」という意味になります。 and 論理積と呼ばれ、両方がtrueならtrueを返す falsならor 論理和と呼ばれ、両方ともfalseならfalseあとは成り立てばtrueを返す xor 排他的論理和。両方が異なる値ならtrue、異なるならfalseを返す not これはこれまでのものと違いnotの後に値を指定するだけ。trueならfalseを示す LIKEであいまい検索 #Stringのカラムを指定する場合、指定した文字列を含むレコードを検索することができます。 User.where('email like ?', '%@gmail.com%') 上記は「Userテーブルの中でemailに@gmail.comが含まれるレコードを検索」という意味になります。 % 任意の0文字以上の文字列 _ 任意の1文字 ORでいずれかを含む検索 #whereの後に.orをつけることで、条件1または条件2に該当のような検索ができます。※Rails5からの機能です User.where(family_name: '山田').or(User.where(first_name: '太郎')) 「Userテーブルの中でfamily_nameが山田またはfirst_nameが太郎のレコードを検索」という意味になります。 NOTで否定検索 whereの後に.notをつけることで、条件に当てはまらないレコードを返すようになります。 User.where.not(status: 'reject') 「Userテーブルの中でstatusがreject以外のレコードを検索」という意味になります。 whereの使い方まとめ 基本の条件指定 【モデル.where(カラム名: 値)】 AND検索 【モデル.where(カラム名1: 値1, カラム名2: 値2)】 あいまい検索 【モデル.where('カラム名 like ?', %値%)】 否定検索 【モデル.where.not(カラム名: 値)】
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

rbenv で欲しいバージョンがない

rbenvでインストール可能なrubyバージョン確認 % rbenv install -l 2.6.7 2.7.3 3.0.1 ver2.7.1が欲しいのだが、ない。 rbenv をアップデートしてみる https://qiita.com/_am_/items/c1dbeb11f40bbbac8fd9 ↑こちらの記事を参考。 欲しいバージョンがないときはアップデートするように書いてある。 下記実行 $ brew update $ brew upgrade rbenv ruby-build 結果: 変わらず。 % rbenv install -l 2.6.7 2.7.3 3.0.1 インストールしてみる 下記実行 % rbenv install 2.7.1 結果: インストール出来た。 結論 rbenv install -lに直接書いてなくても、最新のものより前のバージョンなら、DLできるっぽい。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【修正版】csvファイルを開いてハッシュとして取り込むメソッド

私が未熟なためコードが動きません。 @scivolaさまのこの記事の下のコメントを元に修正させていただきました。 丁寧に見ていただけて感謝です。 addresses = [] File.open("address_book.csv").each_line do |info| #---① a = info.split "," #---② addresses << AddressInfo.new(*a) #---③ end.close#---④ @scivolaさま提案 require "csv" addresses = [] CSV.foreach("address_book.csv") do |row| #---② addresses << AddressInfo.new(*row) #---③ end #---④ ①File.open("ファイル名")(「*ファイルは必ずCSVファイルで)」は読み込みモードで指定したファイルを開き、Fileクラスのオブジェクトを返します。ここでは返されたオブジェクトはeach_lineメソッドforeach(を使って1行ずつ展開してメモリを節約します。)に利用されています。each_lineメソッドではファイルを行単位で読み込み読み込んだ行をブロック引数に格納します。 ②splitメソッドはinfoブロックに格納された行単位の文をしてしたカンマごとに文字列に分割します。 ③newクラスでオブジェクトを生成します。ここではアドレスに書かれたzip.code,prefecture,ward,cityなどカンマごとに分解されたものを<<で配列にして格納します。 ④closeメソッドで開いたファイルを閉じます。処理を終えます。(開放) (注)「<<」の記号を使うことで配列末尾に配列要素を追加できます。 各パラメータの種類 Rubyのメソッド定義で使えるパラメータを以下の8つに分類しています。 種別 例 必須 a オプション b = 2 配列分解 (c, *d) splat *args post-required f キーワード g:, h: 7 ダブルsplat **kwargs ブロック &blk 必須・・・必須パラメータは、呼び出し側で引数を与えないとエラーになるパラメータです。つまりこの「必須」は「呼び出し側で引数を省略できない」という意味になります。 def foo(a) # aが必須パラメータ(普通のパラメータ) puts "a: #{a}" end foo #=> エラー オプション・・・パラメータにデフォルト値を与えたものはオプションのパラメータになります。オプションなので、引数を渡さない場合はデフォルト値が使われ、エラーになりません。 def foo(a = 1) # a = 1がオプションパラメータ(デフォルト値を持つ) puts "a: #{a}" end foo #=> a: 1 配列分解・・・配列分解は、入れ子になった配列をリテラルで(=変数に入れずに)渡された場合に配列を部分に切り分けて受け取る、特殊な動作です。分解のパターンは、パラメータ側のsplat(後述)の配置や丸かっこ( )によって複雑に変化します。引数に[1, 2], 3を与えた場合の例を以下に示します。 (*a) # a = [1, 2], 3 # a = [1, 2], b = 3 (a, *b) # a = [1, 2], b = 3 # a = [1, 2], b = 3, c = # a = 1, b = 2, c = 3 ((a, *b), c) # a = 1, b = [2], c = 3 かなり複雑ですね。パズルみたいで楽しそうですが、パラメータの数が増えると、入れ子の配列リテラルの分解を正確に理解して引数で渡すのは至難の業です。引数に配列リテラルをうかつに書くと落とし穴にハマりそうです。 def method1(*a) puts "a: #{a}" end; def method2(a, b) puts "a: #{a}" puts "b: #{b}" end; def method3(a, *b) puts "a: #{a}" puts "b: #{b}" end; def method4(a, b, *c) puts "a: #{a}" puts "b: #{b}" puts "c: #{c}" end; def method5((a, b), c) puts "a: #{a}" puts "b: #{b}" puts "c: #{c}" end; def method6((a, *b), c) puts "a: #{a}" puts "b: #{b}" puts "c: #{c}" end; method1 [1, 2], 3; # a: [[1, 2], 3] method2 [1, 2], 3; # a: [1, 2], b: 3 method3 [1, 2], 3; # a: [1, 2], b: [3] method4 [1, 2], 3; # a: [1, 2], b: 3, c: [] method5 [1, 2], 3; # a: 1, b: 2, c: 3 method6 [1, 2], 3; # a: 1, b: [2], c: 3 splat・・・パラメータ文字の前に*を追加すると、長さが不定の引数リスト(可変長引数リスト)を受けられるようになります。これをsplatパラメータと呼んでいます。上の配列分解の例にも、splatパラメータが含まれているものがあります。splatパラメータは、さまざまな種類の引数をいくつ渡してもすべて受け取れます。 def foo(*a) # *aがsplatパラメータ puts "a: #{a}" end foo :one, "two", [:three, "four"] #=> a: [:one, "two", [:three, "four"]] post-required・・・splatパラメータの直後に置いた必須パラメータは、post-requiredパラメータとして動作します(本記事では英ママで表記します)。この場合ちょうどsplatパラメータのストッパーのような働きをし、splatパラメータに渡される引数リストの末尾の引数を受け取ります。 以下の例では、bがpost-requiredパラメータとして動作します。 ```rb def foo(*a, b) # bがpost-requiredパラメータ puts "a: #{a}" puts "b: #{b}" end foo :one, "two", {key1: "value"}, [:three, "four"] => a: [:one, "two", {:key1=>"value"}] => b: [:three, "four"] 6. キーワード・・・パラメータ名にRubyのシンボルの書式「キーワード:」を使うと、キーワード付きパラメータになります(キーワード付き引数と呼ばれることもよくあります)。 ```rb def foo(name) # ただの必須パラメータ puts "name: #{name}" end def foo(name:) # キーワード puts "name: #{name}" end def foo(name: "bar") # デフォルト値付きキーワード puts "name: #{name}" end キーワード付きパラメータの最大のメリットは、メソッド呼び出し側でのキーワード付き引数の順序が不問になることです。メソッドを呼び出す側にとっては順序を気にしなくてよくなるので大変使いやすくなります。 キーワード付きパラメータにデフォルト値を与えないと引数が必須になります 引数がない場合や、またはキーワードが示されていない場合にエラーになります デフォルト値を与えれば引数がなくてもエラーになりません 特にデフォルト値付きキーワードは、メソッド呼び出し側で{key: "value"}のようなハッシュでのオプション引数渡しと同じ感覚で、しかも順序不問でkey-valueペアのオプションを渡せるので便利です。 def foo(name: "bar", addr: "tokyo", tel: "03-9999-9999") puts "name: #{name}" puts "addr: #{addr}" puts "tel: #{tel}" end foo(tel: "03-0000-0000", addr: "shibuya", name: "baz") # 呼び出し側で順序を気にしなくてよい #=> name: baz #=> addr: shibuya #=> tel: 03-0000-0000 ''' 参考 Ruby 2.0.0リリース! – キーワード引数を使ってみよう Ruby 2.1.0リリース!注目の新機能を見てみましょう 7. ダブルsplat・・・パラメータ名の前に**を付けるとダブルsplatパラメータになります。splatパラメータと似ていますが、可変長のキーワード引数リストを受け取る前提である点が異なります。ダブルsplatは、上述のopts = {}形式のオプションパラメータと同様の動作です。 ```rb def foo(**profile) # ダブルsplat puts "profile: #{profile}" end foo(tel: "03-0000-0000", addr: "shibuya", name: "baz") #=> profile: {:tel=>"03-0000-0000", :addr=>"shibuya", :name=>"baz"} なお、可変長のキーワード引数リストをダブルでないsplatパラメータで受けると、配列の中にハッシュが保存されるので取り出しに一手間余計にかかります。 def foo(*profile) # ただのsplat puts "profile: #{profile}" end foo(tel: "03-0000-0000", addr: "shibuya", name: "baz") #=> profile: [{:tel=>"03-0000-0000", :addr=>"shibuya", :name=>"baz"}] <=配列の中にハッシュがある ブロック・・・最後のブロックは、他のパラメータと異なる点があります。メソッド定義でyieldでブロックを実行する場合は、パラメータに何も書かなくても、呼び出し側で引数リストの最後にブロックを置くことで渡せます(以下: 暗黙のブロックパラメータ)。逆に、パラメータの末尾に&付きのブロックパラメータを明示的に置いてブロックを受けることもできます(以下: 明示的なブロックパラメータ)。 # 暗黙 def foo # 普通のパラメータも、ブロックを受けるパラメータもない yield end foo { puts "hello" } #=> hello # 明示 def foo &blk # &blkはブロック専用のパラメータ blk.call end foo { puts "hello" } #=> hello 暗黙のブロックパラメータで受けたブロックには名前がありません。 明示的なブロックパラメータで受けたブロックには名前があるので、他のメソッドにブロックを渡したりできるようになります。後編の「ブロックとproc」を参照してください。 参考: #parametersメソッド・・・Method#parametersメソッドを使うと、メソッドのパラメータリストを取得できます。取得したリストには、上で説明したパラメータの種別も含まれます。先ほどのfooメソッドに対してこのメソッドを実行すると以下の結果が得られます。 method(:foo).parameters # [[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:keyreq, :e], [:key, :f], [:keyrest, :g], [:block, :blk]] 参考:hachi8833さん https://techracho.bpsinc.jp/hachi8833/2017_04_05/37930
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

csvファイルを開いてハッシュとして取り込むメソッド

私が未熟なためコードが動きません。 @scivolaさまのこの記事の下のコメントを元に修正させていただきました addresses = [] File.open("address_book.csv").each_line do |info| #---① a = info.split "," #---② addresses << AddressInfo.new(*a) #---③ end.close @scivolaさま提案 require "csv" addresses = [] CSV.foreach("address_book.csv") do |row| #---② addresses << AddressInfo.new(*row) #---③ end #---④ ①File.open("ファイル名")は読み込みモードで指定したファイルを開き、Fileクラスのオブジェクトを返します。ここでは返されたオブジェクトはeach_lineメソッドに利用されています。each_lineメソッドではファイルを行単位で読み込み読み込んだ行をブロック引数に格納します。 ②splitメソッドはinfoブロックに格納された行単位の文をしてしたカンマごとに文字列に分割します。 ③newクラスでオブジェクトを生成します。ここではアドレスに書かれたzip.code,prefecture,ward,cityなどカンマごとに分解されたものを<<で配列にして格納します。 ④closeメソッドで開いたファイルを閉じます。(開放) (注)「<<」の記号を使うことで配列末尾に配列要素を追加できます。 各パラメータの種類 Rubyのメソッド定義で使えるパラメータを以下の8つに分類しています。 種別 例 必須 a オプション b = 2 配列分解 (c, *d) splat *args post-required f キーワード g:, h: 7 ダブルsplat **kwargs ブロック &blk 必須・・・必須パラメータは、呼び出し側で引数を与えないとエラーになるパラメータです。つまりこの「必須」は「呼び出し側で引数を省略できない」という意味になります。 def foo(a) # aが必須パラメータ(普通のパラメータ) puts "a: #{a}" end foo #=> エラー オプション・・・パラメータにデフォルト値を与えたものはオプションのパラメータになります。オプションなので、引数を渡さない場合はデフォルト値が使われ、エラーになりません。 def foo(a = 1) # a = 1がオプションパラメータ(デフォルト値を持つ) puts "a: #{a}" end foo #=> a: 1 配列分解・・・配列分解は、入れ子になった配列をリテラルで(=変数に入れずに)渡された場合に配列を部分に切り分けて受け取る、特殊な動作です。分解のパターンは、パラメータ側のsplat(後述)の配置や丸かっこ( )によって複雑に変化します。引数に[1, 2], 3を与えた場合の例を以下に示します。 (*a) # a = [1, 2], 3 # a = [1, 2], b = 3 (a, *b) # a = [1, 2], b = 3 # a = [1, 2], b = 3, c = # a = 1, b = 2, c = 3 ((a, *b), c) # a = 1, b = [2], c = 3 かなり複雑ですね。パズルみたいで楽しそうですが、パラメータの数が増えると、入れ子の配列リテラルの分解を正確に理解して引数で渡すのは至難の業です。引数に配列リテラルをうかつに書くと落とし穴にハマりそうです。 def method1(*a) puts "a: #{a}" end; def method2(a, b) puts "a: #{a}" puts "b: #{b}" end; def method3(a, *b) puts "a: #{a}" puts "b: #{b}" end; def method4(a, b, *c) puts "a: #{a}" puts "b: #{b}" puts "c: #{c}" end; def method5((a, b), c) puts "a: #{a}" puts "b: #{b}" puts "c: #{c}" end; def method6((a, *b), c) puts "a: #{a}" puts "b: #{b}" puts "c: #{c}" end; method1 [1, 2], 3; # a: [[1, 2], 3] method2 [1, 2], 3; # a: [1, 2], b: 3 method3 [1, 2], 3; # a: [1, 2], b: [3] method4 [1, 2], 3; # a: [1, 2], b: 3, c: [] method5 [1, 2], 3; # a: 1, b: 2, c: 3 method6 [1, 2], 3; # a: 1, b: [2], c: 3 splat・・・パラメータ文字の前に*を追加すると、長さが不定の引数リスト(可変長引数リスト)を受けられるようになります。これをsplatパラメータと呼んでいます。上の配列分解の例にも、splatパラメータが含まれているものがあります。splatパラメータは、さまざまな種類の引数をいくつ渡してもすべて受け取れます。 def foo(*a) # *aがsplatパラメータ puts "a: #{a}" end foo :one, "two", [:three, "four"] #=> a: [:one, "two", [:three, "four"]] post-required・・・splatパラメータの直後に置いた必須パラメータは、post-requiredパラメータとして動作します(本記事では英ママで表記します)。この場合ちょうどsplatパラメータのストッパーのような働きをし、splatパラメータに渡される引数リストの末尾の引数を受け取ります。 以下の例では、bがpost-requiredパラメータとして動作します。 ```rb def foo(*a, b) # bがpost-requiredパラメータ puts "a: #{a}" puts "b: #{b}" end foo :one, "two", {key1: "value"}, [:three, "four"] => a: [:one, "two", {:key1=>"value"}] => b: [:three, "four"] 6. キーワード・・・パラメータ名にRubyのシンボルの書式「キーワード:」を使うと、キーワード付きパラメータになります(キーワード付き引数と呼ばれることもよくあります)。 ```rb def foo(name) # ただの必須パラメータ puts "name: #{name}" end def foo(name:) # キーワード puts "name: #{name}" end def foo(name: "bar") # デフォルト値付きキーワード puts "name: #{name}" end キーワード付きパラメータの最大のメリットは、メソッド呼び出し側でのキーワード付き引数の順序が不問になることです。メソッドを呼び出す側にとっては順序を気にしなくてよくなるので大変使いやすくなります。 キーワード付きパラメータにデフォルト値を与えないと引数が必須になります 引数がない場合や、またはキーワードが示されていない場合にエラーになります デフォルト値を与えれば引数がなくてもエラーになりません 特にデフォルト値付きキーワードは、メソッド呼び出し側で{key: "value"}のようなハッシュでのオプション引数渡しと同じ感覚で、しかも順序不問でkey-valueペアのオプションを渡せるので便利です。 def foo(name: "bar", addr: "tokyo", tel: "03-9999-9999") puts "name: #{name}" puts "addr: #{addr}" puts "tel: #{tel}" end foo(tel: "03-0000-0000", addr: "shibuya", name: "baz") # 呼び出し側で順序を気にしなくてよい #=> name: baz #=> addr: shibuya #=> tel: 03-0000-0000 ''' 参考 Ruby 2.0.0リリース! – キーワード引数を使ってみよう Ruby 2.1.0リリース!注目の新機能を見てみましょう 7. ダブルsplat・・・パラメータ名の前に**を付けるとダブルsplatパラメータになります。splatパラメータと似ていますが、可変長のキーワード引数リストを受け取る前提である点が異なります。ダブルsplatは、上述のopts = {}形式のオプションパラメータと同様の動作です。 ```rb def foo(**profile) # ダブルsplat puts "profile: #{profile}" end foo(tel: "03-0000-0000", addr: "shibuya", name: "baz") #=> profile: {:tel=>"03-0000-0000", :addr=>"shibuya", :name=>"baz"} なお、可変長のキーワード引数リストをダブルでないsplatパラメータで受けると、配列の中にハッシュが保存されるので取り出しに一手間余計にかかります。 def foo(*profile) # ただのsplat puts "profile: #{profile}" end foo(tel: "03-0000-0000", addr: "shibuya", name: "baz") #=> profile: [{:tel=>"03-0000-0000", :addr=>"shibuya", :name=>"baz"}] <=配列の中にハッシュがある ブロック・・・最後のブロックは、他のパラメータと異なる点があります。メソッド定義でyieldでブロックを実行する場合は、パラメータに何も書かなくても、呼び出し側で引数リストの最後にブロックを置くことで渡せます(以下: 暗黙のブロックパラメータ)。逆に、パラメータの末尾に&付きのブロックパラメータを明示的に置いてブロックを受けることもできます(以下: 明示的なブロックパラメータ)。 # 暗黙 def foo # 普通のパラメータも、ブロックを受けるパラメータもない yield end foo { puts "hello" } #=> hello # 明示 def foo &blk # &blkはブロック専用のパラメータ blk.call end foo { puts "hello" } #=> hello 暗黙のブロックパラメータで受けたブロックには名前がありません。 明示的なブロックパラメータで受けたブロックには名前があるので、他のメソッドにブロックを渡したりできるようになります。後編の「ブロックとproc」を参照してください。 参考: #parametersメソッド・・・Method#parametersメソッドを使うと、メソッドのパラメータリストを取得できます。取得したリストには、上で説明したパラメータの種別も含まれます。先ほどのfooメソッドに対してこのメソッドを実行すると以下の結果が得られます。 method(:foo).parameters # [[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:keyreq, :e], [:key, :f], [:keyrest, :g], [:block, :blk]] 参考:hachi8833さん https://techracho.bpsinc.jp/hachi8833/2017_04_05/37930
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ブロック変数

ブロック変数① 1.upto(10) do |i| print i, "¥n" end ブロック変数② 1.downto(10) do |i| print i, "¥n" end ブロック変数③ 10.times do |i| print i, "¥n" end ブロック変数④ 10.step(limit[.step]) do |i| print i, "¥n" end 戻り値は全てselfとします。 メソッド名 戻り値 説明 upto(max) do I i I self selfからmaxまで整数を1繰り上げながらブロック引数iとして処理内容を実行 downto(min) do I i I self selfからmaxまで整数を1繰り下げながらブロック引数iとして処理内容を実行 times do I i I self 0(ゼロ)からself-1まで整数を1繰り上げながらブロック引数iとして処理内容を実行。selfが負の場合には何もしない。 step(limit[, step]) I i I self selfからlimitまで整数をstepで指定した数だけ繰り上げながらブロック引数iとして処理内容を実行。stepを省略した場合は1を指定したものとする
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Regexpクラスとは?

Regexpクラスとは?を調査します。 @shizumaさん ものすごく参考になりました。 https://qiita.com/shizuma/items/4279104026964f1efca6 /(スラッシュ)で囲むと正規表現オブジェクトを生成 メタ文字「繰り返し」 メタ文字列 意味 * 0回以上 + 1回以上 ? 0回か1回 {n} n回 {n,} n回以上 {,n} n回以下 {n,m} n回以上m回以下 メタ文字「ワイルドカード」 . 改行以外の任意の文字列を表す 範囲を用いた文字クラス 表記 表す文字 範囲 [a-z] 小文字英字 [abcdefghijklmnopqrstuvwxyz] [A-Z] 大文字英字 [ABCDEFGHIJKLMNOPQRSTUVWXYZ] [0-9] 1桁数字 [0123456789] 省略記法「文字クラス」 メタ文字列 意味 \w 単語を構成する文字 [a-zA-Z0-9_] \W 単語を構成しない文字 [^a-zA-Z0-9_] \s 空白文字 [ \t\r\n\f] \S 空白でないような文字 [^ \t\r\n\f] \d 10進数の数字 [0-9] \D 10進数の数字でないような文字 [^0-9] \h 16進数の数字 [0-9a-fA-F] \H 16進数の数字でないような文字 [^0-9a-fA-F] (注1)否定文字クラス ^(ハット)・・・文字クラスの[の後に^を付けると先ほどとは逆にどの文字にもマッチしないというパターンを作成出来ます。 (注2)バックスラッシュ()と文字で改行などの特殊な文字を表現する 改行やタブなど特殊な文字にマッチさせるためにバックスラッシュ()と文字を組み合わせたメタ文字が利用できます。 \f 改ページ \n 改行 \r 復帰 \t タブ \v 垂直タブ 文字列「文字列の先頭、文末等を表現」 メタ文字列 意味 ^ 行頭 $ 行末 \A 文字列の先頭 \z 文字列の末尾 \Z 文字列の末尾(末尾が改行文字ならばその手前にマッチ) 具体例 全て数値(全角) /\A[0-9]+\z/ 表示「\A」:先頭文字 表示「[0-9]」:数字で 表示「+」:1回以上繰り返して 表示「\z」:終わる
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

NillClass,TrueClass,FalseClass

これらは擬似変数と呼ばれます。nilは存在しないオブジェクトを示す特別なオブジェクトです。falseとも0とも違う概念となっているため注意しましょう。また論理演算や条件分岐でtrueは真、false、nilは偽を表します。 参考:変数の種類を知っておこう!Rubyで変数のスコープを使う方法【初心者向け】 https://techacademy.jp/magazine/9704#sec6
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Rails]bulletを使ってN + 1問題を解消

N + 1問題とは 要約するとSQLが沢山発行して動作が重くなってしまう問題 詳しくは以下の記事をご確認ください私も参考にさせていただきました。 bulletとは N + 1クエリを自動で検出するgemですうっかりN+1問題が起こってもすぐに見つけることができます。 ただbulletが検出できないようなN + 1クエリがあるケースがあるので頼りすぎるのもよくないです。↓以下参考記事 bulletを使う前 自作のアプリケーションでSQLを発行し確認してみたところ以下のようになった Processing by QuestionsController#index as HTML User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 18], ["LIMIT", 1]] Rendering questions/index.html.erb within layouts/application Question Load (1.3ms) SELECT DISTINCT "questions".* FROM "questions" WHERE "questions"."best_answer_id" IS NULL ORDER BY "questions"."created_at" DESC LIMIT $1 OFFSET $2 [["LIMIT", 10], ["OFFSET", 0]] ↳ app/views/questions/index.html.erb:51 User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 18], ["LIMIT", 1]] ↳ app/views/questions/index.html.erb:52 これが100行ぐらい続くのである。。 bulletをインストール Gemfileに以下を追加します。 Gemfile group :development gem 'bullet' end bundle installを実行します。 $ bundle install そしてSQLを発行しているページにいく(筆者の場合indexページ)と以下のように表示された。 表示の通りコントローラーにincludes[:user])に書き換える - @questions = @q.result(distinct: true) + @questions = @q.result.includes(:user) こうするとポップアップが表示されなくなりSQLがどう発行されているか確認してみた。 Processing by QuestionsController#index as HTML User Load (1.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 18], ["LIMIT", 1]] Rendering questions/index.html.erb within layouts/application Question Load (0.7ms) SELECT "questions".* FROM "questions" WHERE "questions"."best_answer_id" IS NULL ORDER BY "questions"."created_at" DESC LIMIT $1 OFFSET $2 [["LIMIT", 10], ["OFFSET", 0]] ↳ app/views/questions/index.html.erb:51 User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" IN ($1, $2, $3, $4, $5, $6, $7, $8) [["id", 18], ["id", 17], ["id", 14], ["id", 19], ["id", 13], ["id", 9], ["id", 11], ["id", 3]] ↳ app/views/questions/index.html.erb:51 70行ぐらいに減っていた! includesを指定することで関連をまとめて取得し、最小限のクエリ回数で読み込みます。 以上です
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Railsチュートリアル】第9章 発展的なログイン機構 演習と解答

Ruby on Railsチュートリアル 第9章の演習問題と解答をまとめました。 第9章 発展的なログイン機構 - Railsチュートリアル 9.1.1 記憶トークンと暗号化 9.1.1 - 1 コンソールを開き、データベースにある最初のユーザーを変数userに代入してください。その後、そのuserオブジェクトからrememberメソッドがうまく動くかどうか確認してみましょう。また、remember_tokenとremember_digestの違いも確認してみてください。 ターミナル $ rails console >> user = User.first (0.4ms) SELECT sqlite_version(*) User Load (0.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]] => #<User id: 1, name: "Rails Tutorial", email: "example@railstutorial.org", created_at: "2021-04-28 02:52:06", updated_at: "2021-04-28 02:52:06", password_digest: [FILTERED], remember_digest: nil> >> user.remember (0.1ms) begin transaction User Update (0.4ms) UPDATE "users" SET "updated_at" = ?, "remember_digest" = ? WHERE "users"."id" = ? [["updated_at", "2021-04-29 18:55:53.256505"], ["remember_digest", "$2a$12$Ncf.pIz3.7yn0aGbsip1E.KzwxFMESmThMvmU5NUPI2/q5fh7cRaO"], ["id", 1]] (5.9ms) commit transaction => true >> user.remember_token => "Dhfkd3wtu32aiW_-c_VE5g" >> user.remember_digest => "$2a$12$Ncf.pIz3.7yn0aGbsip1E.KzwxFMESmThMvmU5NUPI2/q5fh7cRaO" 9.1.1 - 2 リスト 9.3では、明示的にUserクラスを呼び出すことで、新しいトークンやダイジェスト用のクラスメソッドを定義しました。実際、User.new_tokenやUser.digestを使って呼び出せるようになったので、おそらく最も明確なクラスメソッドの定義方法であると言えるでしょう。しかし実は、より「Ruby的に正しい」クラスメソッドの定義方法が2通りあります。1つはややわかりにくく、もう1つは非常に混乱するでしょう。テストスイートを実行して、ややわかりにくいリスト 9.4の実装でも、非常に混乱しやすいリスト 9.5の実装でも、いずれも正しく動くことを確認してみてください。ヒント: selfは、通常の文脈ではUser「モデル」、つまりユーザーオブジェクトのインスタンスを指しますが、リスト 9.4やリスト 9.5の文脈では、selfはUser「クラス」を指すことにご注意ください。わかりにくさの原因の一部はこの点にあります。 9.1.2 ログイン状態の保持 9.1.2 - 1 ブラウザのcookieを調べ、ログイン後のブラウザではremember_tokenと暗号化されたuser_idがあることを確認してみましょう。 9.1.2 - 2 コンソールを開き、リスト 9.6のauthenticated?メソッドがうまく動くかどうか確かめてみましょう。 ターミナル $ rails console --sandbox >> user = User.first (0.1ms) begin transaction User Load (0.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]] => #<User id: 1, name: "Rails Tutorial", email: "example@railstutorial.org", created_at: "2021-04-28 02:52:06", updated_at: "2021-04-29 20:04:41", password_digest: [FILTERED], remember_digest: "$2a$12$zbaViZSoqG1ECz0WwWZ2X.7VN.4uOYSbVYt3gV.9xot..."> >> user.remember (0.1ms) SAVEPOINT active_record_1 User Update (2.2ms) UPDATE "users" SET "updated_at" = ?, "remember_digest" = ? WHERE "users"."id" = ? [["updated_at", "2021-04-29 20:26:58.696526"], ["remember_digest", "$2a$12$I1V9PobnyDvVG4Unsxc2Puq1BZM1AKvTUca1w1WQpaO.icOiXkofK"], ["id", 1]] (0.1ms) RELEASE SAVEPOINT active_record_1 => true >> user.authenticated?(user.remember_token) => true 9.1.3 ユーザーを忘れる 9.1.3 - 1 ログアウトした後に、ブラウザの対応するcookiesが削除されていることを確認してみましょう。 ログイン時 ログアウト後 9.1.4 2つの目立たないバグ 9.1.4 - 1 リスト 9.16で修正した行をコメントアウトし、2つのログイン済みのタブによるバグを実際に確かめてみましょう。まず片方のタブでログアウトし、その後、もう1つのタブで再度ログアウトを試してみてください。 片方のタブでログアウト後、さらに一つのタブで再度ログアウトを試みる 一度ログアウトしたことにより、ユーザー情報を保持していた@\current_user変数の値がnilになる。 セッションを破棄するforgetメソッドが呼び出せなくなったため、エラー。 9.1.4 - 2 リスト 9.19で修正した行をコメントアウトし、2つのログイン済みのブラウザによるバグを実際に確かめてみましょう。まず片方のブラウザでログアウトし、もう一方のブラウザを再起動してサンプルアプリケーションにアクセスしてみてください。 Cloud9で異なるブラウザを使った動作確認ができなかったので、一度herokuにデプロイしてから chromeとsafariで動作を確認しました。 ターミナル $ heroku run rails db:migrate 9.1.4 - 3 上のコードでコメントアウトした部分を元に戻し、テストスイートが red から green になることを確認しましょう。 動作確認済み 9.2 [Remember me]チェックボックス 9.2 - 1 ブラウザでcookies情報を調べ、[remember me]をチェックしたときに意図した結果になっているかどうかを確認してみましょう。 [remember me]チェックなし [remember me]チェック時 9.2 - 2 コンソールを開き、三項演算子を使った実例を考えてみてください(コラム 9.2)。 ターミナル $ rails console --sandbox >> def war >> puts '1: きのこの山, 2: たけのこの里' >> print 'which do you choose, 1 or 2? => ' >> input = gets.chomp >> input == '1' ? "きのこ派" : "たけのこ派" >> end => :war >> war 1: Kinoko, 2: Takenoko which do you choose, 1 or 2? => 2 => "たけのこ派" 9.3.1 [Remember me]ボックスをテストする 9.3.1 - 1 リスト 9.25の統合テストでは、仮想のremember_token属性にアクセスできないと説明しましたが、実は、assignsという特殊なテストメソッドを使うとアクセスできるようになります。コントローラで定義したインスタンス変数にテストの内部からアクセスするには、テスト内部でassignsメソッドを使います。このメソッドにはインスタンス変数に対応するシンボルを渡します。例えばcreateアクションで@userというインスタンス変数が定義されていれば、テスト内部ではassigns(:user)と書くことでインスタンス変数にアクセスできます。本チュートリアルのアプリケーションの場合、Sessionsコントローラのcreateアクションでは、userを(インスタンス変数ではない)通常のローカル変数として定義しましたが、これをインスタンス変数に変えてしまえば、cookiesにユーザーの記憶トークンが正しく含まれているかどうかをテストできるようになります。このアイデアに従ってリスト 9.27とリスト 9.28の不足分を埋め(ヒントとして?やFILL_INを目印に置いてあります)、[remember me]チェックボックスのテストを改良してみてください。17 いろんなところからメソッドを呼び出す入り組んだテストケースになっているので、 各ファイルの役割やメソッドの動作などを理解していないと頭が混乱してしまいます。 app/controller/sessions_controller class SessionsController < ApplicationController def new end def create # ローカル変数userをインスタンス変数@userに定義しなおす @user = User.find_by(email: params[:session][:email].downcase) if @user && @user.authenticate(params[:session][:password]) log_in @user params[:session][:remember_me] == '1' ? remember(@user) : forget(@user) redirect_to @user else flash.now[:danger] = 'Invalid email/password combination' render 'new' end end def destroy log_out if logged_in? redirect_to root_url end end test/integration/users_login_test.rb require 'test_helper' class UsersLoginTest < ActionDispatch::IntegrationTest # (省略) test "login with remembering" do log_in_as(@user, remember_me: '1') # cookiesとユーザーの持つremember_tokenが一致するかチェック assert_equal cookies[:remember_token], assigns(:user).remember_token end # (省略) end 9.3.2 [Remember me]をテストする 9.3.2 - 1 リスト 9.33にあるauthenticated?の式を削除すると、リスト 9.31の2つ目のテストで失敗することを確かめてみましょう(このテストが正しい対象をテストしていることを確認してみましょう)。 動作確認済み この第9章あたりから難易度が高くなってきたように感じます
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む