- 投稿日:2020-07-31T23:57:50+09:00
Rails googleを使ったSNS認証
ゴール
ベースの作成
ログインして、投稿を作成できるアプリケーションを作成しました。
googleの設定をする
URLは開発環境の場合、こちらを入力してください
http://localhost:3000/users/auth/google_oauth2/callback
本番環境でも使われる場合は、こちらを入力してください
http://本番環境URL/users/auth/google_oauth2/callback
コード編集していきます
環境変数の設定をします。
devise.rb# ==> OmniAuth # Add a new OmniAuth provider. Check the wiki for more information on setting # up on your models and hooks. # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo' config.omniauth :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET']私は環境変数の管理に
dotenv-rails
を使用しました。gemfilegem 'dotenv-rails'
bundle install
します。
アプリケーションのルートディレクトリ直下に.env
を作成します以下の
クライアントID
,クライアントシークレット
をコピーして
.env
に以下のように貼り付けします.envGOOGLE_CLIENT_ID='クライアントIDを入力' GOOGLE_CLIENT_SECRET='クライアント シークレット'環境変数は、githubにpushする場合は
.env
を.ignore
に追加しておくと良いかと思います。.ignore# 以下を追記 .envgemfile編集
gemfilegem 'omniauth-google-oauth2'上記のgemを追加して
bundle install
ルーティング編集
gemfileRails.application.routes.draw do # deviseのコントローラを編集するときは以下を記述しないと変更が反映されないので注意 devise_for :users, controllers: { # deviseの階層を編集した場合は適宜pathを編集してください omniauth_callbacks: "users/omniauth_callbacks" } resources :posts root 'posts#index' endデータベースにカラムを追加する
認証に必要なカラム
provider
カラムと、uid
カラムを作成するためのマイグレーションファイルを作成します$ rails g migration AddOuthColumnToUsers provider:string uid:string
rails db:migrate
userモデルを編集
user.rb
に処理を書いていきますuser.rbclass User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable, # 以下を追加 # google以外の認証をする場合は %i[twitter, facebook]などとなります :omniauthable, omniauth_providers: %i[google_oauth2] # クラスメソッドを作成します def self.from_omniauth(auth) where(provider: auth.provider, uid: auth.uid).first_or_create do |user| # deviseのuserカラムに name を追加している場合は以下のコメントアウトも追記します # user.name = auth.info.name user.email = auth.info.email user.password = Devise.friendly_token[0,20] end end endここで出てくる
first_or_create
が初めて使うメソッドでした。
結構便利だなと、、、DBに
where
で検索したオブジェクトが存在しなければ、何も処理を行わず、
DBにwhere
で検索したオブジェクトが存在していれば、user
オブジェクトにdo
以降の処理を入力してDBに保存する処理になってます。一度
rails console -s
などを使っていろいろ試してみると良いかと!
rails console -s
を使えばデータベースに変更が加わらないので安心です。omniauthの処理を編集します
omniauth_callbacks_controller.rb# frozen_string_literal: true class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController # callback for google def google_oauth2 callback_for(:google) end def callback_for(provider) # 先ほどuser.rbで記述したメソッド(from_omniauth)をここで使っています # 'request.env["omniauth.auth"]'この中にgoogoleアカウントから取得したメールアドレスや、名前と言ったデータが含まれています @user = User.from_omniauth(request.env["omniauth.auth"]) sign_in_and_redirect @user, event: :authentication set_flash_message(:notice, :success, kind: "#{provider}".capitalize) if is_navigational_format? end def failure redirect_to root_path end end以上でgoogleでsns認証ができるかと思います!!
参考
Facebook/Twitter/Googleでのユーザー登録をDevise & Omniauthを使って爆速で実装する
- 投稿日:2020-07-31T21:47:46+09:00
プログラミングスクール行って良かったなっていう話。
※この記事、若干前置き長いです。
こんにちは、Shotaです!
僕がプログミングを勉強してからついに7カ月が経ちました。時が過ぎるのはあっという間ですね。。。
ちなみに、Ruby歴は4カ月程度です7月にプログラミングスクールを卒業して、今ではRubyで簡単なアプリを作れるようになった僕ですが、はじめはなかなかうまくいきませんでした。
最初の挫折は、Progateの道場です。
プログラミングをやろう!と思って、
まず最初に安定のProgateから始めてみました。しかし、大学生ということで勉強・2つの部活・バイト・遊び など、
やることも少なくなかったため、ずいぶんスローペースで進めてました。確か2カ月くらいでHTML,CSS,JS,jQueryを1~2周ずつくらいしたと思います。
一通りProgateやった僕は、腕試しにと、初めてHTMLの道場編をやりました。
そして、絶望しました。(笑)プログラミングで初めて、
「めちゃめちゃ難しくね???」
と感じた瞬間です。これを機に、僕がパソコンの前に座る回数は減っていきました。
典型的な挫折パターンです。
しかし僕は、プログラミングに対する思いを捨てきれず、挫折の4カ月後に
またProgateを再開しました。今度は冬休みということもあり、結構時間もあったので、1~2カ月独学でほぼ毎日プログラミングの勉強をしました。
でも、やっていくうちに気づいたんです。
「独学じゃプログラミングスクール行ってる人に勝てないんじゃないか。」
ということに。Twitterなんか見ると、
「独学でも案件取れる」とか「独学でもエンジニアになれる」
というのは、結構言われてる気はします。そういったものを見ると、
「独学でも案外行けんじゃね」
って簡単に思ってしまいます。たしかに、それは可能だとは思います。
でも個人的な意見としては、スクールに行った方が、成長できるし、得られるものが多いと思います。
また、案件を取れる確率やエンジニアになれる確率も、間違いなくスクールに行った方が上がるはずです。スポーツを例にすると分かりやすいですね。
例えば、テニススクールに通っている子と、テニススクールには通ってないけどテニスをしている子がいたとします。
テニススクールに行っている子は、
毎日、監督・コーチに教えてもらいながら、仲間と一緒に良い環境で練習や試合をやります。
フォームがおかしかったり、新しいプレーにチャレンジしたりするときは、基本からしっかり教えてもらえます。一方、テニススクールに行っていない子は、
毎日テニスの上手い人の動画や、解説動画を見ながら、壁当てをやり続けます。
自分だけでは、おかしいフォームになっても気づきづらいです。では、この2人が試合するとします。
皆さんもお分かりだと思いますが、スクールに行っていない子が
勝つ確率は、非常に低いでしょう。そりゃそうです。
スクールの方が練習環境がいいし、指導してもらえるから。
さらに言うと、スクールに行ってない子が見たテニスの動画は、スクールに行ってる子も見て参考にできます。これと同じことがプログラミングスクールの世界にも言えると、僕は思います。
だから、プログラミングスクールは行く価値があるのです。
「多くの人に影響を与え、前向きにさせるようなサービス開発をする」
というのが僕の目標です。
そのためには、スキルのある立派なエンジニアになる必要があります。そしてそれを実現するためには、
よりエンジニアになりやすい、プログラミングスクールに行った方が良い
ということになります。
これに気づいた僕は、すぐにプログラミングスクールに申し込みました。
プログラミングスクールの感想としましては、
「とにかく行って良かった」
この一言に尽きます。
一体なにが良かったのか。
ポイントは主に2つです。1つ目、分からないことをすぐに聞けること
2つ目、継続できること1つ目、分からないことがあればすぐに聞ける
独学だと、いくら調べてもなかなかエラーから抜け出せない
ということがあると思います。でも、分からないところを聞ける環境があれば、そこで多くの時間足止めをされる心配がなくなります。
メンターさんに質問した時、返ってくるのは答えではなく、ヒントでした。
だから無駄に時間をかけることなく、思考停止もせず、エラーを解決することができました。
運よく、僕の専属のメンターさんは非常にお優しい方で
とてもやりやすかったです。2つ目、継続できる
プログラミングは継続が大事といいますが、本当にそうだと思います。
独学だと挫折しやすいです。ほんとに。
まぁ現に僕も挫折しましたし、笑
プログラミングの独学で挫折する確率は90%と言われています。
プログラミングスクールって結構お金かかりますよね?
でもスクールに行くと、損したくない気持ちが出てくるおかげで、より継続しやすいと思います。
スクールには、受講生を継続させるシステムも整ってますし。とまぁ、こんな感じで、
すぐ聞ける、継続できるという点が非常に良かったかなと、僕は思います。
結論、
プログラミングスクール行って良かった。なるべく早く結果を出したい人や、プログラミングで何か高い目標がある人は、
プログラミングスクールに行くことを僕はオススメします!ちなみに、僕は
「テックアカデミーのWebアプリケーションコース」
で、12週間のプランでした。一応リンク貼っておきますね!
テックアカデミーのリンクはこちら ☞ https://techacademy.jp/長くなりましたが、最後まで読んでくださりありがとうございました!
- 投稿日:2020-07-31T21:07:29+09:00
slateとaglioというAPI Document toolを使ってみた
はじめに
API Documentページを作成するにあたって
slate
,aglio
というtoolを実際に触ったときの手順と感想です。slate について
rubyで作成されたAPIドキュメントを作成するための ツールでマークダウンでドキュメントを記述できます。
slate 導入手順
1 リポジトリの準備
本家のリポジトリを開いて[use this template]をクリックし任意の場所にリポジトリを作成します。作成したリポジトリをローカル環境へ
git clone
します。2 開発環境セットアップ
README.md
を見て頂くと分かるのですが起動方法は以下の3つが準備されています。
* Natively
* Using Vagrant
* Using Docker手順もこちらへ記載してあり非常に親切ですね。
今回は
Natively
とUsing Docker
の手順をやってみたいと思います。2-1 Natively(local環境へ直接installする) 手順
こちらに記載の手順を実行します。
※ 私の環境ではRuby、nodejsの開発環境は整っていたのでinstall部分は省略しました。cd slate bundle install # middlemanはrubyのgemで静的なサイトを簡単に生成してくれます bundle exec middleman server以上です!
これで
http://localhost:4567/
へアクセスすると以下のようなAPI Documentのテンプレートが表示されます。2-2 Using Dockerの手順
こちらに記載の手順を実行します。cd slate docker build . -t slate docker run -d --rm --name slate -p 4567:4567 -v $(pwd)/build:/srv/slate/build -v $(pwd)/source:/srv/slate/source slate以上でNativelyと同じように
http://localhost:4567/
へアクセスするとAPI Documentのテンプレートが表示されます。マークダウンファイルは
source
ディレクトリにあるのでドキュメントの内容を修正する場合はこれを書き換えます。3 Deploy手順
ここではこちらに記載してある手順でDeployしてみます。
ここに記載してあるのはGitHub Pagesに公開する手順で実行方法は下記コマンドを実行するだけです。./deploy.sh何とこれだけ!
これで実際に自分のGitHub Pagesのプロジェクトサイトが公開されているので確認してみて下さい。
URLは http://yourusername.github.io/slate です。
実際にdeployした私のGitHub Pagesはこちらです。簡単に
deploy.sh
の内容を見るとbundle exec middleman build --cleanで マークダウンファイルより
build
ディレクトリ配下へ静的ファイルを作成します。
その後に
build
ディレクトリの内容をgh-pages
ブランチへpushしています。続いてaglioについて記載します。
aglio について
aglioとはAPI Blueprintで記述されたファイルをhtmlへ変換してくれるツールです。
API Blueprint
API Blueprint とは Web API の仕様を表現するための言語のことです。 API の仕様を表現するための様々な文法を持っています。 書き方は Markdown と同じ形式ですので、書き方も馴染みのあるものです。aglio 導入手順
1 リポジトリの準備
GitHub上に任意のリポジトリを作成します。
(例: https://github.com/Nobuo-Hirai/api-document-use-aglio)
作成したリポジトリをgit clone
します。2 開発環境セットアップ
document用のディレクトリ、ファイルを作成します。
root直下にmd
ディレクトリを作成しその中にdocument用のマークダウンファイルを作成していきます。
※Dockerfile, docker-compose.yml
やbuildディレクトリ
やdeploy.sh
は後で説明するのでこの段階では必要ないです。環境構築用の
Dockerfile
とdocker-compose.yml
を作成します。Dockerfile
FROM node:latest WORKDIR /projects RUN npm install -g aglio --unsafe-permdocker-compose.yml
docker-compose.ymlversion: '3' services: aglio: build: . ports: - '4000:4000' volumes: - './md:/projects' - './:/docs' tty: true # htmlを作成するときのテーマを決めれます。 # https://github.com/danielgtaylor/aglio#example-output command: aglio --theme-variables default --theme-template triple -i index.md -s -h 0.0.0.0 -p 4000dockerコンテナ構築・起動します。
docker-compose up --build
以上で http://localhost:4000/
へアクセスするとAPI Documentのテンプレートが表示されていると思います。
md
ディレクトリ配下のマークダウンファイルを修正しAPI documentを作成していきます。3 静的ファイルの作成
deploy用の静的ファイルを作成するため以下のコマンドを実行します。# コンテナ内でhtmlを生成するコマンドを実行 docker-compose exec aglio bash aglio --theme-variables default --theme-template triple -i index.md -o ../docs/index.html以上で、
index.html
ファイルが作成されたと思います。
続いて今回もGitHubPagesへdeployしたいと思います。4
deploy.sh
の作成
ここではslate
で使用したdeploy.sh
を活用します。
slate
で使用したdeploy.sh
をコピーしてroot直下へ配置します。修正点は以下の部分です。
## slate run_build() { bundle exec middleman build --clean } ↓ ↓ ## aglio用に以下に書き換えます run_build() { [[ ! -e ${deploy_directory} ]] && mkdir -p ${deploy_directory} cp index.html build/. }5 deploy手順
slateと同じように以下のコマンドを実行して終わりです。
./deploy.shこれで実際にGitHub Pagesのプロジェクトサイトを確認してみて下さい。
実際にdeployした私のGitHub Pagesはこちらです。2つを試してみての感想
自分がrubyの開発経験があったり環境を既に持っていたというのもありslateの方が簡単でした。
またslateの方がドキュメントが豊富で、star数も多いのでslateが無難かなという印象でした。他に良いAPI Document toolがあれば紹介お願いします!
- 投稿日:2020-07-31T21:07:29+09:00
slateとaglioというAPI Document toolを使ってみたときの手順
はじめに
API Documentページを作成するにあたって
slate
,aglio
というtoolを実際に触ったときの手順と感想です。slate について
rubyで作成されたAPIドキュメントを作成するための ツールでマークダウンでドキュメントを記述できます。
slate 導入手順
1 リポジトリの準備
本家のリポジトリを開いて[use this template]をクリックし任意の場所にリポジトリを作成します。作成したリポジトリをローカル環境へ
git clone
します。2 開発環境セットアップ
README.md
を見て頂くと分かるのですが起動方法は以下の3つが準備されています。
* Natively
* Using Vagrant
* Using Docker手順もこちらへ記載してあり非常に親切ですね。
今回は
Natively
とUsing Docker
の手順をやってみたいと思います。2-1 Natively(local環境へ直接installする) 手順
こちらに記載の手順を実行します。
※ 私の環境ではRuby、nodejsの開発環境は整っていたのでinstall部分は省略しました。cd slate bundle install # middlemanはrubyのgemで静的なサイトを簡単に生成してくれます bundle exec middleman server以上です!
これで
http://localhost:4567/
へアクセスすると以下のようなAPI Documentのテンプレートが表示されます。2-2 Using Dockerの手順
こちらに記載の手順を実行します。cd slate docker build . -t slate docker run -d --rm --name slate -p 4567:4567 -v $(pwd)/build:/srv/slate/build -v $(pwd)/source:/srv/slate/source slate以上でNativelyと同じように
http://localhost:4567/
へアクセスするとAPI Documentのテンプレートが表示されます。マークダウンファイルは
source
ディレクトリにあるのでドキュメントの内容を修正する場合はこれを書き換えます。3 Deploy手順
ここではこちらに記載してある手順でDeployしてみます。
ここに記載してあるのはGitHub Pagesに公開する手順で実行方法は下記コマンドを実行するだけです。./deploy.sh何とこれだけ!
これで実際に自分のGitHub Pagesのプロジェクトサイトが公開されているので確認してみて下さい。
URLは http://yourusername.github.io/slate です。
実際にdeployした私のGitHub Pagesはこちらです。簡単に
deploy.sh
の内容を見るとbundle exec middleman build --cleanで マークダウンファイルより
build
ディレクトリ配下へ静的ファイルを作成します。
その後に
build
ディレクトリの内容をgh-pages
ブランチへpushしています。続いてaglioについて記載します。
aglio について
aglioとはAPI Blueprintで記述されたファイルをhtmlへ変換してくれるツールです。
API Blueprint
API Blueprint とは Web API の仕様を表現するための言語のことです。 API の仕様を表現するための様々な文法を持っています。 書き方は Markdown と同じ形式ですので、書き方も馴染みのあるものです。aglio 導入手順
1 リポジトリの準備
GitHub上に任意のリポジトリを作成します。
(例: https://github.com/Nobuo-Hirai/api-document-use-aglio)
作成したリポジトリをgit clone
します。2 開発環境セットアップ
document用のディレクトリ、ファイルを作成します。
root直下にmd
ディレクトリを作成しその中にdocument用のマークダウンファイルを作成していきます。
※Dockerfile, docker-compose.yml
やbuildディレクトリ
やdeploy.sh
は後で説明するのでこの段階では必要ないです。環境構築用の
Dockerfile
とdocker-compose.yml
を作成します。Dockerfile
FROM node:latest WORKDIR /projects RUN npm install -g aglio --unsafe-permdocker-compose.yml
docker-compose.ymlversion: '3' services: aglio: build: . ports: - '4000:4000' volumes: - './md:/projects' - './:/docs' tty: true # htmlを作成するときのテーマを決めれます。 # https://github.com/danielgtaylor/aglio#example-output command: aglio --theme-variables default --theme-template triple -i index.md -s -h 0.0.0.0 -p 4000dockerコンテナ構築・起動します。
docker-compose up --build
以上で http://localhost:4000/
へアクセスすると以下のようなAPI Documentのテンプレートが表示されていると思います。
md
ディレクトリ配下のマークダウンファイルを修正しAPI documentを作成していきます。3 静的ファイルの作成
deploy用の静的ファイルを作成するため以下のコマンドを実行します。# コンテナ内でhtmlを生成するコマンドを実行 docker-compose exec aglio bash aglio --theme-variables default --theme-template triple -i index.md -o ../docs/index.html以上で、
index.html
ファイルが作成されたと思います。
続いて今回もGitHubPagesへdeployしたいと思います。4
deploy.sh
の作成
ここではslate
で使用したdeploy.sh
を活用します。
slate
で使用したdeploy.sh
をコピーしてroot直下へ配置します。修正点は以下の部分です。
## slate run_build() { bundle exec middleman build --clean } ↓ ↓ ## aglio用に以下に書き換えます run_build() { [[ ! -e ${deploy_directory} ]] && mkdir -p ${deploy_directory} cp index.html build/. }5 deploy手順
slateと同じように以下のコマンドを実行して終わりです。
./deploy.shこれで実際にGitHub Pagesのプロジェクトサイトを確認してみて下さい。
実際にdeployした私のGitHub Pagesはこちらです。参考リポジトリ
2つを試したリポジトリを以下に公開しています。
https://github.com/Nobuo-Hirai/api-document-use-slate
https://github.com/Nobuo-Hirai/api-document-use-aglio2つを試してみての感想
自分がrubyの開発経験があったり環境を既に持っていたというのもありslateの方が簡単でした。
またslateの方がドキュメントが豊富で、star数も多いのでslateが無難かなという印象でした。他に良いAPI Document toolがあれば紹介お願いします!
- 投稿日:2020-07-31T21:07:29+09:00
slateとaglioというAPI Document toolを使ったときの手順
はじめに
API Documentページを作成するにあたって
slate
,aglio
というtoolを実際に触ったときの手順と感想です。slate について
rubyで作成されたAPIドキュメントを作成するための ツールでマークダウンでドキュメントを記述できます。
slate 導入手順
1 リポジトリの準備
本家のリポジトリを開いて[use this template]をクリックし任意の場所にリポジトリを作成します。作成したリポジトリをローカル環境へ
git clone
します。2 開発環境セットアップ
README.md
を見て頂くと分かるのですが起動方法は以下の3つが準備されています。
* Natively
* Using Vagrant
* Using Docker手順もこちらへ記載してあり非常に親切ですね。
今回は
Natively
とUsing Docker
の手順をやってみたいと思います。2-1 Natively(local環境へ直接installする) 手順
こちらに記載の手順を実行します。
※ 私の環境ではRuby、nodejsの開発環境は整っていたのでinstall部分は省略しました。cd slate bundle install # middlemanはrubyのgemで静的なサイトを簡単に生成してくれます bundle exec middleman server以上です!
これで
http://localhost:4567/
へアクセスすると以下のようなAPI Documentのテンプレートが表示されます。2-2 Using Dockerの手順
こちらに記載の手順を実行します。cd slate docker build . -t slate docker run -d --rm --name slate -p 4567:4567 -v $(pwd)/build:/srv/slate/build -v $(pwd)/source:/srv/slate/source slate以上でNativelyと同じように
http://localhost:4567/
へアクセスするとAPI Documentのテンプレートが表示されます。マークダウンファイルは
source
ディレクトリにあるのでドキュメントの内容を修正する場合はこれを書き換えます。3 Deploy手順
ここではこちらに記載してある手順でDeployしてみます。
ここに記載してあるのはGitHub Pagesに公開する手順で実行方法は下記コマンドを実行するだけです。./deploy.sh何とこれだけ!
これで実際に自分のGitHub Pagesのプロジェクトサイトが公開されているので確認してみて下さい。
URLは http://yourusername.github.io/slate です。
実際にdeployした私のGitHub Pagesはこちらです。簡単に
deploy.sh
の内容を見るとbundle exec middleman build --cleanで マークダウンファイルより
build
ディレクトリ配下へ静的ファイルを作成します。
その後に
build
ディレクトリの内容をgh-pages
ブランチへpushしています。続いてaglioについて記載します。
aglio について
aglioとはAPI Blueprintで記述されたファイルをhtmlへ変換してくれるツールです。
API Blueprint
API Blueprint とは Web API の仕様を表現するための言語のことです。 API の仕様を表現するための様々な文法を持っています。 書き方は Markdown と同じ形式ですので、書き方も馴染みのあるものです。aglio 導入手順
1 リポジトリの準備
GitHub上に任意のリポジトリを作成します。
(例: https://github.com/Nobuo-Hirai/api-document-use-aglio)
作成したリポジトリをgit clone
します。2 開発環境セットアップ
document用のディレクトリ、ファイルを作成します。
root直下にmd
ディレクトリを作成しその中にdocument用のマークダウンファイルを作成していきます。
※Dockerfile, docker-compose.yml
やbuildディレクトリ
やdeploy.sh
は後で説明するのでこの段階では必要ないです。環境構築用の
Dockerfile
とdocker-compose.yml
を作成します。Dockerfile
FROM node:latest WORKDIR /projects RUN npm install -g aglio --unsafe-permdocker-compose.yml
docker-compose.ymlversion: '3' services: aglio: build: . ports: - '4000:4000' volumes: - './md:/projects' - './:/docs' tty: true # htmlを作成するときのテーマを決めれます。 # https://github.com/danielgtaylor/aglio#example-output command: aglio --theme-variables default --theme-template triple -i index.md -s -h 0.0.0.0 -p 4000dockerコンテナ構築・起動します。
docker-compose up --build
以上で http://localhost:4000/
へアクセスすると以下のようなAPI Documentのテンプレートが表示されていると思います。
md
ディレクトリ配下のマークダウンファイルを修正しAPI documentを作成していきます。3 静的ファイルの作成
deploy用の静的ファイルを作成するため以下のコマンドを実行します。# コンテナ内でhtmlを生成するコマンドを実行 docker-compose exec aglio bash aglio --theme-variables default --theme-template triple -i index.md -o ../docs/index.html以上で、
index.html
ファイルが作成されたと思います。
続いて今回もGitHubPagesへdeployしたいと思います。4
deploy.sh
の作成
ここではslate
で使用したdeploy.sh
を活用します。
slate
で使用したdeploy.sh
をコピーしてroot直下へ配置します。修正点は以下の部分です。
## slate run_build() { bundle exec middleman build --clean } ↓ ↓ ## aglio用に以下に書き換えます run_build() { [[ ! -e ${deploy_directory} ]] && mkdir -p ${deploy_directory} cp index.html build/. }5 deploy手順
slateと同じように以下のコマンドを実行して終わりです。
./deploy.shこれで実際にGitHub Pagesのプロジェクトサイトを確認してみて下さい。
実際にdeployした私のGitHub Pagesはこちらです。参考リポジトリ
2つを試したリポジトリを以下に公開しています。
https://github.com/Nobuo-Hirai/api-document-use-slate
https://github.com/Nobuo-Hirai/api-document-use-aglio2つを試してみての感想
自分がrubyの開発経験があったり環境を既に持っていたというのもありslateの方が簡単でした。
またslateの方がドキュメントが豊富で、star数も多いのでslateが無難かなという印象でした。他に良いAPI Document toolがあれば紹介お願いします!
- 投稿日:2020-07-31T20:43:07+09:00
今日のメモ(パーセント記法、文字列演算、シンボル)
パーセント記法
『'』や『"』で囲んできた文字列を、パーセント記法では囲む記号を指定できる。
文字列の中で『"』を使うときにエスケープしなくてもよくなる。例
#『"』無し a = %*TEST* p a #=> "TEST" #『"』あり a = %*"TEST"* p a #=> "\"TEST\""
書式 生成される値 % ダブルクォート文字列 %Q ダブルクォート文字列 %q シングルクォート文字列 %s シンボル %x コマンド出力 %r 正規表現 文字列演算
文字列では『+』と『*』を適用して連結することができる。
a = "ru" + "by" puts a #=> ruby他にも末尾に連結する場合は『<<』も使用することができる。
a = "ru" puts a << "by" #=> ruby※ですが、異なる文字コード(UTF-8とSJISなど)の連結はエラーが発生します。
追記:文字列の比較はlengthやsizeメソッドで文字数を参照できます。
シンボル
シンボルは主に文字列の前に『:』を置いて定義したもの。
ただし『"』で文字列を囲む必要は無い。a = "ruby" b = :study p str.class #=> String p sym.class #=> Symbolパーセント記法を使ってもシンボルを生成することができる。
%s*test* #=> :test文字列からシンボルを生成する方法
a1 = "test" a2 = a1.to_sym # to_symメソッドを使用 p a2.class #=> Symbol作成したシンボルは、文字の並びが同じなら同一のオブジェクトIDを参照しますが、
文字列リテラルの場合は、文字の並びが同じでも、毎回新たにオブジェクトを生成するのでオブジェクトIDが変化します。
- 投稿日:2020-07-31T19:55:10+09:00
Railsアプリで日時の取得にはどのクラスを使うべきか(Time, DateTime, TimeWithZone)
日時の取得はどのクラスを使うべきか
- Timeクラス
- DateTimeクラス
- TimeWithZoneクラス
Railsでは、特別な理由がない限り、
TimeクラスやDateTimeクラスより、TimeWithZoneクラスで統一した方が良い。タイムゾーンについて
タイムゾーンを設定する場所は3箇所あります。
- システム
- 環境変数
ENV['TZ']
- application.rb
application.rbにどのタイムゾーンが設定してあるか確認するには、
Time.zone.name
を使います。# application.rb config.time_zone = 'Tokyo' Time.zone.name => "Tokyo"どのタイムゾーンが使われるのか
ややこしいことに、クラスやそのクラスに関連するメソッドによってどのタイムゾーンが使われるか変わります。
例えば、
Timeクラスに関連するメソッドnow
を使ったTime.now
は環境変数のタイムゾーンを使い、
Timeクラスに関連するメソッドcurrent
を使ったTime.current
はapplication.rbのタイムゾーンを使います。#環境変数が使われ、classはTimeになる [1] pry(main)> Time.now => 2020-07-31 19:39:18 +0900 [2] pry(main)> Time.now.class => Time #application.rbが使われ、classはTimeWithZoneになる [3] pry(main)> Time.current => Fri, 31 Jul 2020 19:39:35 JST +09:00 [4] pry(main)> Time.current.class => ActiveSupport::TimeWithZone現在の日時の取得にはTime.currentかTime.zone.nowを使おう
現在の日時を取得する場合、以下の方法があります。
- Time.now (環境変数のタイムゾーンを使う)
- DateTime.now (環境変数のタイムゾーンを使う)
- Time.current (application.rbのタイムゾーンを使う)
- Time.zone.now (application.rbのタイムゾーンを使う)
結論としては、TimeWithZoneクラスである3または4を使っておいた方が良いです(もし国際的なアプリケーションにしようと思ったら色々と器用に扱える為)。
# 環境変数のタイムゾーンが使われる [1] pry(main)> Time.now => 2020-07-31 19:43:14 +0900 #Timeクラス [2] pry(main)> DateTime.now => Fri, 31 Jul 2020 19:43:21 +0900 #DateTimeクラス # application.rbのタイムゾーンが使われる [3] pry(main)> Time.current => Fri, 31 Jul 2020 19:43:26 JST +09:00 #ActiveSupport::TimeWithZoneクラス [4] pry(main)> Time.zone.now => Fri, 31 Jul 2020 19:43:32 JST +09:00 #ActiveSupport::TimeWithZoneクラス参考記事
以下の記事を参考にしました。記事ではとても詳しく説明してあります。
https://qiita.com/jnchito/items/cae89ee43c30f5d6fa2c
- 投稿日:2020-07-31T19:34:12+09:00
その5「Rails初心者」が5回連続で発生したエラーをなんとか切り抜けた話。「NameError」
前回の「その4」の続きです
前回の記事☞https://qiita.com/Shota_U/items/f41a2e0f2a1e24f98fc9
ついにこれが最後のエラーです。
今回発生したエラーは、
NameError (uninitialized constant)
というエラーです。
このエラーの
uninitialized constant
は、
定義したクラスを読み取ることができない。という意味だそうです。
そこで、まずファイル名とファイルパス、ファイルの中のクラス名を確認。
すると一か所、
単数形でないといけないファイル名をと複数形にしていたことが判明。すぐ直してエラーが消えました!
これは割とうっかりミス、という感じです。これまでのエラーよりは解決しやすかったかなと思います。
これで、5つすべてのエラーを解消することができました!一応、ほかの4つの記事も載せておきます
その1 https://qiita.com/Shota_U/items/1f91709704476618aa0d
その2 https://qiita.com/Shota_U/items/c93eb669b3f8078785eb
その3 https://qiita.com/Shota_U/items/a589a080815032a24092
その4 https://qiita.com/Shota_U/items/f41a2e0f2a1e24f98fc9これらのエラーと戦い、どうにか解決したうえで
改めて気づいたことが3つありました。(どれも初心者向けですが。。。)ですので、ここで学んだことをまた次の記事で書こうと思います!
読んでくださり、ありがとうございました!
- 投稿日:2020-07-31T19:30:03+09:00
その4「Rails初心者」が5回連続で発生したエラーをなんとか切り抜けた話。「ArgumentError in income_Values#index」
前回の「その3」の続きです
前回の記事☞https://qiita.com/Shota_U/items/a589a080815032a24092
今回発生した新たなエラーは、
ArgumentError in income_Values#index
です
※すみません!エラーのスクショは撮っておりません
こちらのエラーは、
「引数の数があっていないときや、数は合っていて、期待される振る舞いを持ってはいるが、期待される値ではないときに発生する」
みたいです。
エラー文をよく見たところ、
wrong number of arguments (given 1, expected 0)
とありました。これは、
「引数の数がちがうよー」
「正常な引数の数は0のはずなのに1個入ってるよ」ってことらしいです
そこで引数を正しい数にしたところ、
やっと、一覧画面を表示することができました!!!エラー文を知るって大事だなぁ。。。」
しかし、今度は新規投稿ができなくなっていました。
今度は
NameError
です。せっかく実装できた!と思ったのに、、、
その5に続く?
- 投稿日:2020-07-31T19:28:18+09:00
その3「Rails初心者」が5回連続で発生したエラーをなんとか切り抜けた話。「NoMethodError in IncomeValues#index」
前回の「その2」の続きです
前回の記事☞https://qiita.com/Shota_U/items/c93eb669b3f8078785eb
「NoMethodError in IncomeValues#index」
というのがでてきました。
これは、「NillClassにstrftimeなんていうメソッドはないよ」
ということみたいです
そこで、
income_value.year_month.strftime('%Y年%m月')を
income_value.year_month&.strftime('%Y年%m月')としたところ、無事解決できました。
しかし、
また次のエラー「ArgumentError」がでてきてしまいました。。。これは、正直心折れそうでした(笑)。
その4へ続く?
https://qiita.com/Shota_U/items/f41a2e0f2a1e24f98fc9
- 投稿日:2020-07-31T19:24:15+09:00
その2「Rails初心者」が5回連続で発生したエラーをなんとか切り抜けた話。「ActiveRecord::StatementInvalid in IncomeValues#index」
前回の「その1」の続きです
前回の記事はこちら☞https://qiita.com/Shota_U/items/1f91709704476618aa0d
2つ目のエラーは
ということで、
「ActiveRecord::StatementInvalid in IncomeValues#index」
「データベースがおかしいよ」
ってことみたいです。
色々調べてみましたが、全く解決できませんでした。。
そこでQiitaで質問しました。すると、ありがたいことに回答をいくつかいただきました。
どうやら、controllerの
IncomeValue.order("year_month asc")が怪しいみたく、orderの指定の仕方がおかしいようです。
そこで、
IncomeValue.order("year_month asc")としたところ、
このエラーがなくなりました!君には苦戦したよ。。。って感じで
エラーが解消されたのはよいものの、、、また次に
「NoMethodError in IncomeValues#index」
がでてきてしまったのです。。。その3に続く?
https://qiita.com/Shota_U/items/a589a080815032a24092
- 投稿日:2020-07-31T19:20:10+09:00
その1「Rails初心者」が5回連続で発生したエラーをなんとか切り抜けた話。「index (投稿一覧) が表示できない」
ポートフォリオの家計簿アプリ作成中、非常に躓いた箇所がありましたので備忘録として書いていきます。
何に躓いたかというと、同じところで5回連続エラーが起こったのです。
※3~4日ほどでやっと解消できました?
今回はエラーの内容と、それを解決した方法をそれぞれ書いていきます。
苦悩の連続の全てはここから始まりました。
まず、エラー画面はでていないのですが、
投稿一覧が表示されないという事態が起こりました。関係のあるコードはこちら
index.html.erb<% require 'active_support/core_ext/numeric/conversions' %> <h2>収入科目の新規データ登録</h2> <p>登録年月を設定してください</p> <%= form_tag({controller: :income_values, action: :new}, {method: :post}) do %> <input type="month" name="year_month"> <input type="submit"> <% end %> <h2>収入科目 データ一覧 </h2> <% if @income_value.present? %> <table> <tr> <th>登録年月</th> <th>名称</th> <th>値</th> <th>備考</th> <th>操作</th> </tr> <% @income_values.each do |income_value| %> <tr> <td><%= income_value.year_month.strftime('%Y年%m月') %></td> <td><%= @incomes.find(income_value.income_id).name %></td> <td><%= income_value.value.to_s(:delimited) %> 円</td> <td><%= income_value.description %></td> <td><%= link_to "編集", [:edit, income_value] %> | <%= link_to "削除", income_value, method: :delete, data: { confirm: "本当に削除しますか?"} %></td> </tr> <% end %> </table> <% else %> <p>登録されているデータがありません。</p> <% end %>income_values_controller.rbclass IncomeValuesController < ApplicationController def index @incomes = Income.order(created_at: :asc) @income_values = IncomeValue.order("year_month asc") end def show @income_value = IncomeValue.find(params[:id]) end def new year_month_day = params[:year_month] + "-01" @year_month = year_month_day.to_date @incomes = Income.order(created_at: :asc) @form = Form::IncomeForm.new end def edit @income_value = IncomeValue.find(params[:id]) @income = Income.find(@income_value.income_id) end def create @form = Form::IncomeForm.new(income_form_params) if @form.save redirect_to :income_values, notice: "登録しました" else redirect_to :income_values, notice: "登録に失敗しました" end end def income_form_params params .require(:form_income_form) .permit(income_values_attributes: Form::IncomeValue::REGISTRABLE_ATTRIBUTES) end def update @income_value = IncomeValue.find(params[:id]) @income_value.assign_attributes(params[:income_value]) if @income_value.save redirect_to :income_values, notice: "情報を更新しました" else一覧が表示されなかった原因は、
index.html.erb
の<% if @income_value.present? %>の変数が単数形だったからでした。
<% if @income_values.present? %>として、解決!
しっかり確認することの大切さを改めて実感しました。
原因が分かって、
「一覧が表示される!」と思いきや、「ActiveRecord::StatementInvalid」というエラーがでてしまったのです。。。
そして僕はこのエラーにとてつもなく苦しみました。
その2に続く?
https://qiita.com/Shota_U/items/c93eb669b3f8078785eb
- 投稿日:2020-07-31T18:08:51+09:00
木構造のacts_as_treeで、N+1を消し去る
木構造
古いコードを見ると、アンチパターンが多いですね。今回も同様にアンチパターンの一つである隣接リストが使われていました。さらに、N+1問題が放置され、パフォーマンス的に悪いということで対応することになりました。
今回は、たった2階層だったので、隣接リストでもあまり問題がなさそうです。GitHub
https://github.com/amerine/acts_as_tree
使い方
https://github.com/amerine/acts_as_tree#example 引用
class Category < ActiveRecord::Base acts_as_tree order: "name" end root = Category.create("name" => "root") child1 = root.children.create("name" => "child1") subchild1 = child1.children.create("name" => "subchild1") root.parent # => nil child1.parent # => root root.children # => [child1] root.children.first.children.first # => subchild1前提
parent_id
(あるいは、任意のキー) を木構造の親キーとします。schema例
create_table "technologies", force: :cascade do |t| t.string "name" t.bigint "parent_id" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.index ["parent_id"], name: "index_technologies_on_parent_id" endN+1の消し去り方
modelに追加した
acts_at_tree
によって、children
メソッドが生えますので、そちらをincludesして関連付け、事前に最小限のクエリ回数にて読み込まれるようにします。解消コード
# model class Technology < ApplicationRecord acts_as_tree def dig if children.empty? self else children.map(&:dig) end end endincludesを付与してあげます。
# console Technology .where(parent: nil) .includes(children: { children: [:children] })) .map(&:dig)
- 投稿日:2020-07-31T18:08:51+09:00
Ruby on Railsの木構造Gemのacts_as_treeで、N+1を消し去る
手元動作環境
当然、サービスインしているコードを乗せるわけにはいかないので、手元環境で似たようなコードを書いて動作検証しています。
- ruby 2.7.1p83
- Rails 6.0.3.2
- acts_as_tree (2.9.1)
木構造
古いコードを見ると、アンチパターンが多いですね。今回も同様にアンチパターンの一つである隣接リストが使われていました。さらに、N+1問題が放置され、パフォーマンス的に悪いということで対応することになりました。
今回は、たった2階層だったので、隣接リストでもあまり問題がなさそうです。GitHub
https://github.com/amerine/acts_as_tree
使い方
https://github.com/amerine/acts_as_tree#example 引用
class Category < ActiveRecord::Base acts_as_tree order: "name" end root = Category.create("name" => "root") child1 = root.children.create("name" => "child1") subchild1 = child1.children.create("name" => "subchild1") root.parent # => nil child1.parent # => root root.children # => [child1] root.children.first.children.first # => subchild1前提
parent_id
(あるいは、任意のキー) を木構造の親キーとします。schema例
create_table "technologies", force: :cascade do |t| t.string "name" t.bigint "parent_id" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.index ["parent_id"], name: "index_technologies_on_parent_id" endN+1の消し去り方
modelに追加した
acts_at_tree
によって、children
メソッドが生えますので、そちらをincludesして関連付け、事前に最小限のクエリ回数にて読み込まれるようにします。解消コード
# model class Technology < ApplicationRecord acts_as_tree def dig if children.empty? self else children.map(&:dig) end end endincludesを付与してあげます。
# console Technology .where(parent: nil) .includes(children: { children: [:children] })) .map(&:dig)response
2階層のコードを抜き出して見ると、このような形になります。
{ "id":6, "name":"AWS", "parent_id":null, "children":[ { "id":7, "name":"コンピューティング", "parent_id":6, "children":[ { "id":8, "name":"EC2", "parent_id":7 }, { "id":9, "name":"Elastic Beanstalk", "parent_id":7 }, { "id":10, "name":"Lambda", "parent_id":7 } ] } ] }発行SQLの比較
includesがない場合の例
60件ぐらいデータを入れてみた
データに応じて、SQLの数が増加していくSELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" IS NULL SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 1], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 2], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 3], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 4], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 5], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 6], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 6]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 7], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 7]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 8], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 9], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 10], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 11], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 11]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 12], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id SELECT 1 AS one F_i SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id SE= $1 [["parent_id", 14]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 15], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 16], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 16]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 17], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["paren SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["paren SELECT 1 AS one FROM "ent_id", 19], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 20], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 20]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 21], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 22], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 23], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIM SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIM SELECT 1 AS one FROM "technologies" W" = $1 [["parent_id", 24]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 25], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 26], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 27], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 28], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 29], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIM SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIM SELECT 1 AS one FROM "technologies" WIMIT $2 [["parent_id", 31], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 31]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 32], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 33], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 34], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 34]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 35], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 36], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 37], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 38], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 39], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 39]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 40], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 41], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 42], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 42]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 43], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 44], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 44]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 45], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 46], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 46]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 47], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 48], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 49], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["paren SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["paren SELECT 1 AS one FROM "ent_id", 51], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 51]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 52], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 53], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 54], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 55], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" SELECT "technologies".* FROM "technolent_id", 56], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 57], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 58], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 59], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 59]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["paren SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["paren SELECT 1 AS one FROM "ent_id", 61], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 62], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 63], ["LIMIT", 1]]N+1問題解消時の例
SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" IS NULL SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" IN ($1, $2, $3, $4, $5, $6) [["parent_id", 1], ["parent_id", 6], ["parent_id", 46], ["parent_id", 51], ["parent_id", 55], ["parent_id", 59]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" IN ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29) [["parent_id", 2], ["parent_id", 3], ["parent_id", 4], ["parent_id", 5], ["parent_id", 7], ["parent_id", 11], ["parent_id", 14], ["parent_id", 16], ["parent_id", 20], ["parent_id", 24], ["parent_id", 31], ["parent_id", 34], ["parent_id", 39], ["parent_id", 42], ["parent_id", 44], ["parent_id", 47], ["parent_id", 48], ["parent_id", 49], ["parent_id", 50], ["parent_id", 52], ["parent_id", 53], ["parent_id", 54], ["parent_id", 56], ["parent_id", 57], ["parent_id", 58], ["parent_id", 60], ["parent_id", 61], ["parent_id", 62], ["parent_id", 63]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" IN ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28) [["parent_id", 8], ["parent_id", 9], ["parent_id", 10], ["parent_id", 12], ["parent_id", 13], ["parent_id", 15], ["parent_id", 17], ["parent_id", 18], ["parent_id", 19], ["parent_id", 21], ["parent_id", 22], ["parent_id", 23], ["parent_id", 25], ["parent_id", 26], ["parent_id", 27], ["parent_id", 28], ["parent_id", 29], ["parent_id", 30], ["parent_id", 32], ["parent_id", 33], ["parent_id", 35], ["parent_id", 36], ["parent_id", 37], ["parent_id", 38], ["parent_id", 40], ["parent_id", 41], ["parent_id", 43], ["parent_id", 45]]
- 投稿日:2020-07-31T17:43:07+09:00
Controllerに定義するアクション一覧
- 投稿日:2020-07-31T17:16:11+09:00
【Rails入門】renderの使い方
rendearの使い方
renderメソッドを用いることで、別のアクションを経由せずに、直接ビューを表示することができます。
render("フォルダ名/ファイル名")のように表示したいビューを指定します。
renderメソッドを使うと、redirect_toメソッドを使った場合と違い、そのアクション内で定義した@変数をビューでそのまま使うことができます。user_controller.rbclass UserController < ApplicationController def top @user = User.find_by(email: params[:email], password: params[:password]) if @user else render ("home/signup") end end end
- 投稿日:2020-07-31T16:34:34+09:00
【初心者】Rubyの配列に対する繰り返し処理色々
実行環境
超基本的な内容なので、実行環境に左右されないと思いますが、一応明記しておきます。
OS : macOS Catalina ver10.15.5
Ruby : 2.7.1p83each
基本的な繰り返し処理。要素を一つづつ取り出して処理を行なっていく。
do ~ end で囲むのが基本。変数のスコープに注意。sample.rbnumbers = [1, 2, 4, 5, 6] total = 0 numbers.each do |num| total += num end p total # 18map
配列を返してくれることが特徴。下記の処理は要素に10を足して出力している。
簡単な処理ならばdo ~ end の代わりに { }で記入可能。sample.rbnumbers = [1, 2, 4, 5, 6] nuadd_num = numbers.map {|num| num + 10} p add_num # [11, 12, 14, 15, 16]select
処理内の判定に合致した値を配列として返している。
sample.rbnumbers = [1, 2, 4, 5, 6] numbers2 = numbers.select {|num| num % 2 == 0} p numbers2 # [2, 4, 6]reject
処理内の判定に合致しない値を配列として返している。selectの逆。
sample.rbnumbers = [1, 2, 4, 5, 6] numbers2 = numbers.reject {|num| num % 2 == 0} p numbers2 # [1, 5]inject
たたみ込み処理。num と i にそれぞれ要素が代入され処理を行なっていく。
sample.rbnumbers = [1, 2, 4, 5, 6] numbers2 = numbers.inject {|num, i| num + i} # 1回目のループ num = 1, i = 2 # 2回目のループ num = 3, i = 4 # 3回目のループ num = 7, i = 5 # 4回目のループ num = 12, i = 6 p numbers2 # 18
- 投稿日:2020-07-31T16:06:37+09:00
Ruby: CouchDB のデータを削除 (Delete)
couch_delete.rb#! /usr/bin/ruby # -*- encoding: utf-8 -*- # # couch_delete.rb # # Jul/31/2020 # # --------------------------------------------------------------------- require 'faraday' require 'json' # # --------------------------------------------------------------------- STDERR.puts "*** 開始 ***" # key_in = ARGV[0] puts key_in URL="http://localhost:5984/nagano/" + key_in # res = Faraday.get URL puts res.status if res.status == 200 then json_str = res.body data_aa=JSON.parse(json_str) # puts data_aa puts data_aa["_rev"] # url_del = URL + "?rev=" + data_aa["_rev"] res = Faraday.delete url_del puts res.status end STDERR.puts "*** 終了 ***" # ---------------------------------------------------------------------実行
./couch_delete.rb t2026
- 投稿日:2020-07-31T16:04:30+09:00
Ruby: CouchDB のデータを更新 (Update)
couch_update.rb#! /usr/bin/ruby # -*- encoding: utf-8 -*- # # couch_update.rb # # Jul/31/2020 # # --------------------------------------------------------------------- require 'faraday' require 'json' require 'date' # # --------------------------------------------------------------------- STDERR.puts "*** 開始 ***" # key_in = ARGV[0] population_in = ARGV[1].to_i puts key_in,population_in URL="http://localhost:5984/nagano/" + key_in # res = Faraday.get URL puts res.status if res.status == 200 then json_str = res.body data_aa=JSON.parse(json_str) # puts data_aa puts data_aa["_rev"] puts data_aa["name"] # args = {} args["name"] = data_aa["name"] args["population"] = population_in args["date_mod"] = Date.today url_up = URL + "?rev=" + data_aa["_rev"] con = Faraday.new res = con.put do |req| req.url url_up req.headers['Content-Type'] = 'application/json' req.body = JSON.pretty_generate(args) end puts res.status end STDERR.puts "*** 終了 ***" # ---------------------------------------------------------------------実行
./couch_update.rb t2029 4213500
- 投稿日:2020-07-31T16:03:03+09:00
Ruby: CouchDB のデータを読む (Read)
couch_read.rb#! /usr/bin/ruby # -*- encoding: utf-8 -*- # # couch_read.rb # # Jul/31/2020 # # --------------------------------------------------------------------- require 'faraday' require 'json' # # --------------------------------------------------------------------- STDERR.puts "*** 開始 ***" # URL="http://localhost:5984/nagano/_all_docs?include_docs=true" # res = Faraday.get URL # puts res.status json_str = res.body dict_data=JSON.parse(json_str) # dict_data['rows'].each {|value| doc = value["doc"] str_out = doc["_id"] + "\t" + doc['name'] + "\t" \ + doc["population"].to_s + "\t" + doc['date_mod'] print(str_out,"\n") } # STDERR.puts "*** 終了 ***" # ---------------------------------------------------------------------実行
./couch_read.rb
- 投稿日:2020-07-31T16:01:02+09:00
Ruby: CouchDB のデータを作成 (Create)
couch_create.rb#! /usr/bin/ruby # -*- encoding: utf-8 -*- # # couch_create.rb # # Jul/31/2020 # # --------------------------------------------------------------------- require 'faraday' require 'json' # # --------------------------------------------------------------------- def dict_append_proc (dict_aa,key,name,population,date_mod) unit = {} unit['name'] = name unit['population'] = population unit['date_mod'] = date_mod dict_aa[key] = unit return dict_aa end # --------------------------------------------------------------------- def prepare_data_proc () dict_aa={} dict_aa=dict_append_proc(dict_aa,'t2021',"長野",51847,"2006-3-19") dict_aa=dict_append_proc(dict_aa,'t2022',"松本",23789,"2006-7-27") dict_aa=dict_append_proc(dict_aa,'t2023',"上田",47251,"2006-2-8") dict_aa=dict_append_proc(dict_aa,'t2024',"小諸",78623,"2006-1-22") dict_aa=dict_append_proc(dict_aa,'t2025',"岡谷",91489,"2006-5-11") dict_aa=dict_append_proc(dict_aa,'t2026',"塩尻",27915,"2006-4-17") dict_aa=dict_append_proc(dict_aa,'t2027',"茅野",36972,"2006-9-18") dict_aa=dict_append_proc(dict_aa,'t2028',"飯田",74921,"2006-8-15") dict_aa=dict_append_proc(dict_aa,'t2029',"中野",81923,"2006-10-11") dict_aa=dict_append_proc(dict_aa,'t2030',"諏訪",47598,"2006-9-12") dict_aa=dict_append_proc(dict_aa,'t2031',"駒ヶ根",51738,"2006-7-22") dict_aa=dict_append_proc(dict_aa,'t2032',"佐久",82514,"2006-8-17") dict_aa=dict_append_proc(dict_aa,'t2033',"伊那",74361,"2006-12-29") dict_aa=dict_append_proc(dict_aa,'t2034',"千曲",67293,"2006-10-18") end # --------------------------------------------------------------------- STDERR.puts "*** 開始 ***" # URL="http://localhost:5984/nagano" # res = Faraday.delete URL puts res.status res = Faraday.put URL puts res.status # dict_aa=prepare_data_proc() # dict_aa.sort.each {|key, value| url_aa = URL + "/" + key puts url_aa con = Faraday.new res = con.put do |req| req.url url_aa req.headers['Content-Type'] = 'application/json' req.body = JSON.pretty_generate(value) end } STDERR.puts "*** 終了 ***" # ---------------------------------------------------------------------実行
./couch_create.rb
- 投稿日:2020-07-31T14:50:48+09:00
【エラー】Ruby on Rails のoss(オープンソース)を使うために、環境構築 切り替え
はじめに
OSSから知識をパク...、引き出しを増やす!!
独学で知識を広げるために、先人が開発したオープンソースから技術を学ぶことにしました。
そのため、ruby環境を切り替えなどが必要になりました。dockerで気軽に遊べるので、ローカル環境で直接環境を切り替えるのは、普段避けてきました。しかしこの際、ローカル環境でやってしまおう!と思い試みました。
結果的に理解が深まり、自分のためになりました。早速やっていく
まず、Railsで開発されているOSSの記事より、面白そうで、美味しそうなOSSをニヤニヤ眺め、獲物を定めます。
業務システム?
なんとも美味しそうだ明細を出すシステム? おお、管理画面含めて面白そうかもしれない。
https://github.com/vteams/open-source-billing/
ただ単に明細を出すなら調べて出るが、UIまで学べるのは美味しい君に決めた!!
$ git clone https://github.com/vteams/open-source-billing.git相当なコード量なのでしょう。
ダウンロードに恐ろしく時間がかかります。楽しみでならない。
ウハウハしながら待ちます。ついに、ダウンロードできた!!
よし、db:createだ!!!
open-source-billing owner$ rake db:create rake aborted! LoadError: cannot load such file -- bundler/setup /Users/owner/projects/oss/open-source-billing/config/boot.rb:3:in `<top (required)>' /Users/owner/projects/oss/open-source-billing/config/application.rb:1:in `<top (required)>' /Users/owner/projects/oss/open-source-billing/Rakefile:5:in `<top (required)>' (See full trace by running task with --trace)うぇーい
エラー 出ますやん。LoadError: cannot load such file -- bundler/setupままま、 bundlerのバージョンが違うとかだろ。
わかってるよ。$ bundle -vこれで、バージョン確認だ!!
open-source-billing owner$ bundle -v Traceback (most recent call last): 2: from /Users/owner/.rbenv/versions/2.5.1/bin/bundle:23:in `<main>' 1: from /Users/owner/.rbenv/versions/2.5.1/lib/ruby/2.5.0/rubygems.rb:308:in `activate_bin_path' /Users/owner/.rbenv/versions/2.5.1/lib/ruby/2.5.0/rubygems.rb:289:in `find_spec_for_exe': can't find gem bundler (>= 0.a) with executable bundle (Gem::GemNotFoundException)ははーん、バージョン見せてくれませんか
なるほど。じゃあ、Gemfile.lockから見てみよう
Gemfile.lockBUNDLED WITH 2.1.4やっぱり、載ってますやーん
2.1.4を利用しているのね。じゃあ、今自分のmacのbundlerは、、、、、
~ owner$ bundle -v Bundler version 2.0.22.0.2を使っているので、だからエラーが起こっているのか。
あれ? 過去に2.1.4使ってなかったっけ?
$ gem list bundlerこれで確認だ!!
~ owner$ gem list bundler *** LOCAL GEMS *** bundler (2.0.2, 1.3.0) capistrano-bundler (1.6.0)使ってないわ笑
思い過ごしか。じゃあ、2.1.4をインストールしよう!!
bundlerをインストール!!!
~ owner$ gem install bundler -v 2.1.4これでインストールだ!!
~ owner$ gem install bundler -v 2.1.4 ERROR: While executing gem ... (Errno::EACCES) Permission denied @ rb_sysopen - /Users/owner/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-2.1.4/CHANGELOG.mdなんだって。。。。
Permission deniedPermissionだから、許可されてねーのか。権限関連みたいだな
それより、
ERROR: While executing gem ... (Errno::EACCES)このエラーは、なんだろうか???
早速ググってみよう。ERROR: While executing gem ... (Errno::EACCES)が出た時の解決法
先人の方、ありがとうございます!!!どれどれ
うんうん、よくわからん。
この人が参考にした元の記事を見よう$sudo chown -R (ユーザ名):staff /Users/(ユーザ名)/.rbenvこのコマンドをすればいいのね
ownerアカウントを使っているから$sudo chown -R owner:staff /Users/owner/.rbenvでいいのかな
早速実行だMacBook-Air:~ owner$ sudo chown -R owner:staff /Users/owner/.rbenv MacBook-Air:~ owner$ gem install bundler -v 2.1.4 Successfully installed bundler-2.1.4 Parsing documentation for bundler-2.1.4 Done installing documentation for bundler after 4 seconds 1 gem installed成功したやん!!
先人の方、ありがとおおおおう!!LGTM押しておこう
じゃあ、もう一度 db:createだ!
$ rake db:create実行!!
MacBook-Air:open-source-billing owner$ rake db:create Your Ruby version is 2.5.1, but your Gemfile specified 2.7.1あれま、rubyのバージョンも違うのか。
自分が使っているのが、2.5.1 で, このOSSは2.7.1を利用しているのか。じゃあ、ruby 2.7.1をインストールだ!!!
とりあえず、どのバージョンをインストールできるか確認してみようか
$ rbenv install -lで確認っと。
OwnernoMacBook-Air:~ owner$ rbenv install -l 2.5.8 2.6.6 2.7.1 jruby-9.2.11.1 maglev-1.0.0 mruby-2.1.0 rbx-4.15 truffleruby-20.1.0 Only latest stable releases for each Ruby implementation are shown. Use 'rbenv install --list-all' to show all local versions.しっかり、2.7.1ありますね
じゃあ、2.7.1を指定して、インストールっと。
$ rbenv install 2.7.1なかなかに長い。。。。
OwnernoMacBook-Air:~ owner$ rbenv install 2.7.1 Downloading openssl-1.1.1g.tar.gz... -> https://dqw8nmjcqpjn7.cloudfront.net/ddb04774f1e32f0c49751e21b67216ac87852ceb056b75209af2443400636d46 Installing openssl-1.1.1g... Installed openssl-1.1.1g to /Users/owner/.rbenv/versions/2.7.1 Downloading ruby-2.7.1.tar.bz2... -> https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.1.tar.bz2 Installing ruby-2.7.1... ruby-build: using readline from homebrew Installed ruby-2.7.1 to /Users/owner/.rbenv/versions/2.7.1ようやく終わった!!!
念のためにリフレッシュして、再読み込みさせておきますかね
再読み込み$rbenv rehashあとは、最近はdockerを使っているので、
標準利用しているバージョンをossに合わせようrubyは2.7.1を基本的に利用rbenv global 2.7.1じゃあ、これで db:createやってみますかね
open-source-billing owner$ rake db:create Could not find rake-10.5.0 in any of the sources Run `bundle install` to install missing gems.ほうほう、
Run'bundle install'
`と出てるから、$ bundle installすればいいのね
bundle install 実行!!
. . . Installing libv8 3.16.14.19 with native extensions Gem::Ext::BuildError: ERROR: Failed to build gem native extension. . . . An error occurred while installing libv8 (3.16.14.19), and Bundler cannot continue. Make sure that `gem install libv8 -v '3.16.14.19' --source 'https://rubygems.org/'` succeeds before bundling.え、、、、。
まだ、エラー出るの???よくみたら二つエラーがあるみたい。
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
これからググって見ようGem::Ext::BuildError: ERROR: Failed to build gem native extension.
先人ありがとう><どうも、このエラーの直前のgemでエラーの原因のようだ
Installing libv8 3.16.14.19 with native extensions Gem::Ext::BuildError: ERROR: Failed to build gem native extension.この場合だと
libv8
が原因みたいだねさっきのもう一つのエラーも
libv8
だったようなAn error occurred while installing libv8 (3.16.14.19), and Bundler cannot continue. Make sure that `gem install libv8 -v '3.16.14.19' --source 'https://rubygems.org/'` succeeds before bundling.あーー、やっぱりそうだね。
$ gem install libv8 -v '3.16.14.19' --source 'https://rubygems.org/'上記のコマンドしろって命が書かれているから、まずはこっちからやってみよう。
$ gem install libv8 -v '3.16.14.19' --source 'https://rubygems.org/' . . . An error occurred while installing libv8 (3.16.14.19), and Bundler cannot continue. Make sure that `gem install libv8 -v '3.16.14.19' --source 'https://rubygems.org/'` succeeds before bundling.変わらないかあT^T
どうもよくあるエラーっぽいなあ
In Gemfile: therubyracer was resolved to 0.12.3, which depends on libv8うんうん、
therubyracer
が原因みたいだこのサイトに同じ症状が載っていたので、実行してみよう
ジッッ香
$ bundle config --local build.libv8 --with-system-v8 You are replacing the current $ bundle config --local build.therubyracer --with-v8-dir=$(brew --prefix v8-315)お、エラーも何もない
じゃあ、`
bundle install
してみましょうかねええopen-source-billing owner$ bundle installん??
An error occurred while installing rmagick (2.15.4), and Bundler cannot continue. Make sure that `gem install rmagick -v '2.15.4' --source 'https://rubygems.org/'` succeeds before bundling.今度は、
rmagick
のエラーですか。
もしかして、、、いろんなgemこれの繰り返しなんじゃ。。。。。とにかくやってみよう
$gem install rmagick -v '2.15.4' --source 'https://rubygems.org/'open-source-billing owner$ gem install rmagick -v '2.15.4' --source 'https://rubygems.org/' Building native extensions. This could take a while... ERROR: Error installing rmagick: ERROR: Failed to build gem native extension. current directory: /Users/owner/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/rmagick-2.15.4/ext/RMagick /Users/owner/.rbenv/versions/2.7.1/bin/ruby -I /Users/owner/.rbenv/versions/2.7.1/lib/ruby/2.7.0 -r ./siteconf20200730-12130-sp4zhp.rb extconf.rb checking for clang... yes checking for Magick-config... no checking for pkg-config... yes checking for outdated ImageMagick version (<= 6.4.9)... no checking for Ruby version >= 1.8.5... yes checking for stdint.h... yes checking for sys/types.h... yes checking for wand/MagickWand.h... no Can't install RMagick 2.15.4. Can't find MagickWand.h. *** extconf.rb failed *** Could not create Makefile due to some reason, probably lack of necessary libraries and/or headers. Check the mkmf.log file for more details. You may need configuration options.おーーーー、、、、やはり出たか
んーーーーー。なんだ
よくわからん。ひとまず
ERROR: Error installing rmagick:
で検索してみよう。先人ありがとうううう!!!
どれどれ、
うんうん、ダウンロードして、直接macに入れる...。
よし、却下だ。
絶対にコマンドでいけるでしょ。
だって、コマンドでもダウンロードできるのだから。他に良い記事はないかなと、、、
gem install rmagickでchecking for Magick-config... noがでる解決方法
hecking for Magick-config... no
が怪しい?
どれどれERROR: Error installing rmagick: ERROR: Failed to build gem native extension. current directory: /Users/owner/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/rmagick-2.15.4/ext/RMagick /Users/owner/.rbenv/versions/2.7.1/bin/ruby -I /Users/owner/.rbenv/versions/2.7.1/lib/ruby/2.7.0 -r ./siteconf20200730-12130-sp4zhp.rb extconf.rb checking for clang... yes checking for Magick-config... no checking for pkg-config... yes checking for outdated ImageMagick version (<= 6.4.9)... no checking for Ruby version >= 1.8.5... yes checking for stdint.h... yes checking for sys/types.h... yes checking for wand/MagickWand.h... noあ、このエラーの
yes
は問題なくて、no
に問題があるのか!!!
なるほど!!!で、
Magick-config
とImageMagick
が怪しいと!!
なるほどねえええ!!じゃあ、解決策を参考にさせていただきます。
sudo: yum: command not foundあ、使えないのか
command not foundのエラーの解消方法
何気なくコマンド使っていたけど、こういう違いがあったのか、勉強になりました。
しかも、この人おそらく同じエラーじゃないですか$ brew install ImageMagickこれでやってみようかな
$ brew install ImageMagick Error: imagemagick 7.0.10-18 is already installed To upgrade to 7.0.10-24, run `brew upgrade imagemagick`.うんうん、すでに入っているみたいですねえ。そうですよねえ、過去に使ったことありますもんねええ
$ brew upgrade imagemagickひとまずアップデートしてみます
Error: Your Xcode (10.3) is too outdated. Please update to Xcode 11.5 (or delete it). Xcode can be updated from the App Store. Error: Could not find an SDK that supports macOS 10.15. You may have have an outdated or incompatible Xcode. Homebrew found the following SDKs in the Xcode install: 10.14なんだか、これ以上やると環境を破壊する気配がする。。。
いや、それはないな。そもそも、xcodeってiOSのシュミレーター用に入れたアプリだよね
Xcode can be updated from the App Store.あー、やっぱりそうだよねえ。
ということは、最新バージョンのXcodeにアップデートしなはれと言われているのか。
そういえば、macアップデートしてから、xcodeアップデートしてなかったもんなあということで、Appp Storeから最新版のXcodeをインストール
その後に$brew reinstall imagemagick@6$open-source-billing owner$ gem install rmagick Building native extensions. This could take a while... Successfully installed rmagick-4.1.2 Parsing documentation for rmagick-4.1.2 Done installing documentation for rmagick after 1 seconds 1 gem installedお、成功しました!!
これで、bundle installしてみると、、、
Fetching rmagick 2.15.4 Installing rmagick 2.15.4 with native extensions Gem::Ext::BuildError: ERROR: Failed to build gem native extension. An error occurred while installing rmagick (2.15.4), and Bundler cannot continue. Make sure that `gem install rmagick -v '2.15.4' --source 'https://rubygems.org/'` succeeds before bundling.やっぱり、ダメですね
ん???
よくみるとエラーで要求されているのは
rmagick (2.15.4)
で、先ほど入れたrmagickはrmagick-4.1.2
でしたから、バージョンが違うことでエラーが起こっているかもしれない。Gemfilegem 'rmagick', '4.1.2'に変更します。
これでいけるかなあ?とbundle install
An error occurred while installing therubyracer (0.12.3), and Bundler cannot continue. Make sure that `gem install therubyracer -v '0.12.3' --source 'https://rubygems.org/'` succeeds before bundling.
therubyracer
また君かい(笑)
さっき解決したでしょう(笑)therubyracerも今の環境に合わせて、バージョンを指定すればいけるかな?
と思いぐぐるとある記事に遭遇する時代はmini_racerだった
ッッハ!!
gem: 'therubyracer'
は削除!!Gemfilegem 'mini_racer'代わりに
mini_racer
足しましたよこれでどうだ!!
$ bundle install Using slim-rails 3.1.0 Using stripe 1.56.0 Fetching tinymce-rails 4.3.13 Installing tinymce-rails 4.3.13 Fetching to_words 1.1.1 Installing to_words 1.1.1 Fetching trackstamps 0.0.9 Installing trackstamps 0.0.9 Fetching twitter-bootstrap-rails 2.1.9 Installing twitter-bootstrap-rails 2.1.9 Fetching uglifier 3.0.0 Installing uglifier 3.0.0 Fetching unix_utils 0.0.15 Installing unix_utils 0.0.15 Fetching whenever 0.9.7 Installing whenever 0.9.7 Fetching wicked_pdf 2.0.2 Installing wicked_pdf 2.0.2 Fetching wkhtmltopdf-binary 0.9.9.3 Installing wkhtmltopdf-binary 0.9.9.3 Fetching xlsx_writer 0.4.4 Installing xlsx_writer 0.4.4 Fetching yajl-ruby 1.3.1 Installing yajl-ruby 1.3.1 with native extensions Bundle complete! 104 Gemfile dependencies, 230 gems now installed. Use `bundle info [gemname]` to see where a bundled gem is installed. Post-install message from twitter-bootstrap-rails: Important: You may need to add a javascript runtime to your Gemfile in order for bootstrap's LESS files to compile to CSS. ********************************************** ExecJS supports these runtimes: therubyracer - Google V8 embedded within Ruby therubyrhino - Mozilla Rhino embedded within JRuby Node.js Apple JavaScriptCore - Included with Mac OS X Microsoft Windows Script Host (JScript) **********************************************いちよう、成功したみたいです。
ただ、
Important: You may need to add a javascript runtime to your Gemfile in order for bootstrap's LESS files to compile to CSS. #重要: bootstrapのLESSファイルをCSSにコンパイルするために、javascriptランタイムをGemfileに追加する必要があるかもしれません。 ********************************************** ExecJS supports these runtimes: therubyracer - Google V8 embedded within Ruby therubyrhino - Mozilla Rhino embedded within JRuby Node.js Apple JavaScriptCore - Included with Mac OS X Microsoft Windows Script Host (JScript) **********************************************jsが使えるかどうか、確認する必要はあるみたいですね
ExecJS::RubyRacerRuntime is not supported. Please replace therubyracer with mini_racer in your Gemfile or use Node.js as ExecJS runtime. #ExecJS::RubyRacerRuntimeはサポートされていません。Gemfileでtherubyracerをmini_racerに置き換えるか、ExecJSランタイムとしてNode.jsを使用してください。モノによっては、上記のよ8うに
therubyracerをmini_racerに置き換える
ように指示がある程ですし、問題ないでしょう。$rails sひとまず、サーバー起動できるか確認してみます。
Change: >> #<#<Class:0x00007fe292f30580>:0x00007fe29a81d588>.call(template) To: >> #<#<Class:0x00007fe292f30580>:0x00007fe29a81d588>.call(template, source) (called from <top (required)> at /Users/owner/projects/oss/open-source-billing/config/application.rb:8) [DEPRECATION] This gem has been renamed to hashie-forbidden_attributes and will no longer be supported. Please switch to hashie-forbidden_attributes as soon as possible.何かのgemがサポート終了しているので、
hashie-forbidden_attributes
に書き換えろと言われています。怪しいのはこれ
gem 'hashie_rails', '0.0.4'gem 'hashie_rails'のgithubをみてみます。
HashieRails Moved to HashieForbiddenAttributes.お!、やっぱり、
hashie-forbidden_attributes
に変わっていますね!!gem 'hashie-forbidden_attributes'これに、書き換えて、
bundle install
します。$ rails sこれで起動できるかな????
$ rails s DEPRECATION WARNING: Single arity template handlers are deprecated. Template handlers must now accept two parameters, the view object and the source for the view object. Change: >> #<#<Class:0x00007f9aa1b5e5f8>:0x00007f9aa1b574b0>.call(template) To: >> #<#<Class:0x00007f9aa1b5e5f8>:0x00007f9aa1b574b0>.call(template, source) (called from <top (required)> at /Users/owner/projects/oss/open-source-billing/config/application.rb:8) => Booting Puma => Rails 6.0.2.2 application starting in development => Run `rails server --help` for more startup optionsダメですねえ
DEPRECATION WARNING: Single arity template handlers are deprecated. Template handlers must now accept two parameters, the view object and the source for the view object.警告: シングルアリティのテンプレートハンドラは非推奨です。テンプレートハンドラは
ビューオブジェクトとビューオブジェクトのソースの2つのパラメータを受け付けるようになりました。
という意味みたいです。とりあえず検索してみます。
本当にありがたい。
いったん、試してみます
$ bundle update slimこれでダメなら、
https://github.com/rails/rails/issues/35505
の方法を試していきたいと思います。$ rails s DEPRECATION WARNING: Single arity template handlers are deprecated. Template handlers must now accept two parameters, the view object and the source for the view object. Change: >> #<#<Class:0x00007f8216263780>:0x00007f8211d3abe0>.call(template) To: >> #<#<Class:0x00007f8216263780>:0x00007f8211d3abe0>.call(template, source) (called from <top (required)> at /Users/owner/projects/oss/open-source-billing/config/application.rb:8) => Booting Puma => Rails 6.0.2.2 application starting in development => Run `rails server --help` for more startup options Exitingダメですね
Gemfilegem 'slim', '3.0.7'これを削除してみます。
$ rails s DEPRECATION WARNING: Single arity template handlers are deprecated. Template handlers must now accept two parameters, the view object and the source for the view object. Change: >> #<#<Class:0x00007fe53a1117b0>:0x00007fe53a132ff0>.call(template) To: >> #<#<Class:0x00007fe53a1117b0>:0x00007fe53a132ff0>.call(template, source) (called from <top (required)> at /Users/owner/projects/oss/open-source-billing/config/application.rb:8)ダメですね
じゃあ、この記事を参考にしていきます。
Gemfile# gem 'jbuilder', '~> 2.0' gem 'jbuilder', github: 'rails/jbuilder', branch: 'master'これでやってみましょう
bundle update
するように指示があるので、先にしておきます。$ rails s$ rails s => Booting Puma => Rails 6.0.2.2 application starting in development => Run `rails server --help` for more startup options Exiting Traceback (most recent call last): 50: from bin/rails:4:in `<main>' 49: from bin/rails:4:in `require'先ほどのエラーはなくなりましたが、それでもまだ読み込めない様子です。
エラー`database_configuration': Cannot load database configuration: (RuntimeError) Could not load database configuration. No such file - ["config/database.yml"]どうもconfigフォルダにdatabase.ymlが入っていないようです。
database.ymlを追加すれば改善するでしょう。
その前に先ほど消した
slim
を戻して検証しておきましょうGemfilegem: 'slim'これで起動っと
$ rails s => Booting Puma => Rails 6.0.2.2 application starting in development => Run `rails server --help` for more startup options Exiting Traceback (most recent call last):うんうん、先ほどの
Change: >> #<#<Class:0x00007fe53a1117b0>:0x00007fe53a132ff0>.call(template)がないことから、slimは関係なさそうです。
どうも,rails 6のjbuilderのバグのようですねでは続けてdatabase.ymlを作成していきます。
config/database.ymldefault: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: socket: /tmp/mysql.sock host: localhost development: <<: *default database: open-source-billing_development test: <<: *default database: open-source-billing_testこれで、ひとまず
rails s
してみます。/Users/owner/.rbenv/versions/2.7.1/lib/ruby/2.7.0/psych.rb:577:in `initialize': No such file or directory @ rb_sysopen - /Users/owner/projects/oss/open-source-billing/config/config.yml (Errno::ENOENT)ん
ひとまずNo such file or directory @ rb_sysopen
でググると記事が出てきました何か記述が足りないようですね
今回の場合config/config.yml
がないため、発生しているようです。
ただ、config/config.copy.yml
というファイルが用意されていたので、copy
の記述を消して、cofig.yml
としました。$ rails db:create Created database 'open-source-billing_development' Created database 'open-source-billing_test' $rails db:migrate ズガガガガガガガ.....$rails sでたああああああああああああああああああああああああああ
ようやくですよおお
- 投稿日:2020-07-31T13:07:16+09:00
2020年7月 gem Omniauthでgoogleログイン 認証
概要
Devise + omniauth + omniauth-google-oauth2
でgoogle ログインを実装する
色々な記事があったのですが、とりあえず忘れないように、備忘録としてのしておきます*注意*
*新規登録をしたあと2回目行こうを入力をせずにグーグルのボタンだけでログインできる機能であり、新規登録がGooleでできる訳ではないのであしからず。*
その方法は、また別の時に解説します。1. まずはGoogle Developers Consoleで登録
1-1. 下準備
こちらを参照してまずは、
クライアントID、クライアントシークレットを発行してください。1.2 Gemfile追加
クライアントID、クライアントシークレットが発行されたら
Gemfileに追加しますGemfile#省略 gem 'devise' gem 'omniauth' gem 'omniauth-google-oauth2' ...terminal$ bundle installDeviseの設定
terminal$ rails g devise:installユーザ認証用のテーブル作成
termina$ rails g devise user2020******_add_column_to_users.rbclass DeviseCreateUsers < ActiveRecord::Migration def change create_table(:users) do |t| add_column :users, :provider, :string add_column :users, :uid, :string add_column :users, :token, :string add_column :users, :meta, :string end end$ rake db:migrate
Model修正
app/models/user.rbclass User < ApplicationRecord devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable, :confirmable, :omniauthable, omniauth_providers: %i(google) ... ... ... def self.find_for_google_oauth2(auth) user = User.where(email: auth.info.email).first unless user user = User.create(name: auth.info.name, provider: auth.provider, uid: auth.uid, email: auth.info.email, token: auth.credentials.token, password: Devise.friendly_token[0, 20], meta: auth.to_yaml) end user end end:trackable, :omniauthableだけでOKです。deviseに新たに機能を持たせたいときは、そのとき新たに追記する方がスマートだと思います。今回は、とりあえずログインすることが目的なので、これでよい!
また、def self.find_for_google(auth)は、コールバックを受けた時にユーザが既にアプリケーションの中で認知されているかどうかを判断するメソッドです。後で使います。
config修正
ここが他のサイトに乗っているのとは違うかったとこ!!!
config/initializers/devise.rbDevise.setup do |config| require 'devise/orm/active_record' config.omniauth :google_oauth2, GOOGLE_CLIENT_ID="***sdps.apps.googleusercontent.com", GOOGLE_CLIENT_SECRET="***********", name: :google, scope: %w(email) endGOOGLE_CLIENT_IDのとこがENV=['...']
となっているとこが多い。。
It's Simple!!
scopeについて、デフォルト(ここに記述しない状態)だとemailとprofileになります。ユーザ認証のための必須ではないため、emailだけにしちゃいましょうログインボタンを設置するページ作る
app/controllers/views/home.html.erb= link_to image_tag('#.png'), omniauth_authorize_path(resource_name, provider)omniauth_callbacks_controller.rbを作成
app/controllers/usersディレクトリを作成して、omniauth_callbacks_controller.rbというコントローラーを作成します。
omniauth_callbacks_controller.rbclass Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController def google @user = User.find_for_google_oauth2(request.env['omniauth.auth']) if @user.persisted? flash[:notice] = I18n.t 'devise.omniauth_callbacks.success', kind: 'Google' sign_in_and_redirect @user, event: :authentication else session['devise.google_data'] = request.env['omniauth.auth'] redirect_to new_user_registration_url end end endサーバ起動
terminal$ rails sで、サーバを起動し、
http://localhost:3000 にアクセスしてするとgoogle loginを押すと...routes.rbでログイン後に遷移する先を記述していないのでrootに行ってますね。ログイン後、viewなどでcurrent_user.emailなどを表示させてみれば、ログインしているユーザのemailアドレスが表示されるかと思います。!
- 投稿日:2020-07-31T12:35:28+09:00
resourcesとresourceを組み合わせて使う時の注意点についてまとめてみた
先日、resourcesとresourceの違いについてまとめてみましたが、組み合わせて使う際の注意点もあったのでまとめてみました。
違いについてはこちら → resourcesとresourceの違い - Qiitaresourcesとresourceを組み合わせて使う場合
resourcesとresourceを組み合わせて使うと、下記のようなルーティングが簡単に生成できます。
- 全ユーザーの一覧表示
- 全ユーザーの詳細表示
- 自ユーザーの詳細表示
- 自ユーザー情報の編集
全ユーザー一覧、各ユーザーの詳細については、誰でも表示できるが、ユーザー情報の編集は自分のものしかできないという状態。
config/routes.rbresources :users, only: [:index, :show] resource :user, only: [:show, :edit, :update]
rails routes
で生成されたルートを確認すると、下記のような感じ。ターミナルPrefix Verb URI Pattern Controller#Action users GET /users(.:format) users#index user GET /users/:id(.:format) users#show edit_user GET /user/edit(.:format) users#edit GET /user(.:format) users#show PATCH /user(.:format) users#update PUT /user(.:format) users#update
user GET /users/:id(.:format) users#show
の部分、user_pathが/users/:idに割り当てられてしまうことで、/userを返すべきヘルパーメソッドが生成されない。
ということで、順番を逆にして記載してみた。config/routes.rbresource :user, only: [:show, :edit, :update] resources :users, only: [:index, :show]
rails routes
で生成されたルートを確認すると、下記のような感じ。ターミナルPrefix Verb URI Pattern Controller#Action edit_user GET /user/edit(.:format) users#edit user GET /user(.:format) users#show PATCH /user(.:format) users#update PUT /user(.:format) users#update users GET /users(.:format) users#index GET /users/:id(.:format) users#show自ユーザーは、ログイン機能(session管理)で特定できれば、リクエストに:idを含む必要はないので、自ユーザーに関するルーティングは
resource
を使用しています。自分以外のユーザーの詳細画面を見るには、対象となるユーザーのIDを指定する必要があるので、
resources
でリクエストに:idを含むルートを生成しています。結論
単数形で使用する
resource
と、複数形で使用するresources
を組み合わせてルーティングを作る際は、単数形のresource
を上に書くようにする。
- 投稿日:2020-07-31T11:39:37+09:00
Rails 本番環境で画像が読み込まれないエラー
この記事について
本番環境でbackground-imageの画像を読み込む時にはエラーが出ないのに、image_tagのところだけでエラーが出てしまっていたので、そのエラー解決方法について
環境
・Ruby 2.6.6, Rails 6.0.3.2
・Docker,Docker-compose(開発環境)
・AWS/本番環境(EC2, RDS, VPC, EIP, Route53, IAM, S3)参考URL
https://stackoverflow.com/questions/49440304/rails-asset-is-not-present-in-asset-pipeline-when-using-image-tag
この人と全く同じ現象になってました。出ていたエラー
qiita.rbActionView::Template::Error (The asset "chat_example.jpeg" is not present in the asset pipeline.):asset へのパイプラインがうまくいっていない様子
解決方法
config/environments/production.rbにある、config.assets.compile = falseをtrueに変えてあげる。
config/environments/production.rb- config.assets.compile = false + config.assets.compile = true
- 投稿日:2020-07-31T11:15:58+09:00
Controller作成と同時にアクションとviewファイルを作成(rails)
Controller作成と同時にアクションとviewファイルを作成
railsではcontrollerを作成する際、同時にアクションとviewファイルを作成することができます。
実際に手動でアクションやviewファイルを作成する手間を省くことができます。
以下がコマンドの型です。$ rails g controller コントローラ名 アクション名例えば、book controllerを作成し、newアクションを追加したい場合、、、
$ rails g controller book newこんな感じになれば、成功。
[vagrant@localhost sample_app]$ rails g controller books new Running via Spring preloader in process 25819 create app/controllers/books_controller.rb route get 'books/new' invoke erb create app/views/books create app/views/books/new.html.erb invoke test_unit create test/controllers/books_controller_test.rb invoke helper create app/helpers/books_helper.rb invoke test_unit invoke assets invoke coffee create app/assets/javascripts/books.coffee invoke scss create app/assets/stylesheets/books.scss
- 投稿日:2020-07-31T10:58:03+09:00
カラムの追加と削除
カラムとは?
カラムとはデータベースの中のテーブルが持つ要素です。
例えば、ユーザーというテーブルの中の「名前、生年月日、住所」などの項目をカラムと言います。カラムの追加
新たに別のカラムを追加したいということはよくあると思います。
そんなときは以下のコマンドでカラムを追加です。$ rails g migration Addカラム名Toテーブル名 カラム名:型名例えば、「User」というテーブルに「name」というカラムを追加したい場合、
$ rails g migration AddNameToUsers name:string $ rails db:migrateここで「rails db:migrate」を忘れてしまうと、テーブルへ反映されませんので、
気をつけてください。カラムの削除
カラム名を間違えて登録した時など、カラムを削除したいこともあると思います。
カラムを追加する時とあまり変わりません。$ rails g migration Removeカラム名Fromテーブル名 カラム名:型名「User」というテーブルの「name」というカラムを削除したい場合、
$ rails g migration RemoveNameFromUsers name:string $ rails db:migrateここでも「rails db:migrate」は忘れずに。
- 投稿日:2020-07-31T09:40:32+09:00
【Rails】エラー解決 Unsupported argument type: 1 (Integer)
はじめに
今回は
Unsupported argument type: 1 (Integer)
こんなこと言われた時の対処方を記述します
お決まりのタイプミスによって発見したエラー文です笑解決策
intger型の1という引数は期待してません、という感じのエラー文です。
という事は違う物を期待してるところで整数の1を渡してしまっているという事です。
User.find_by(session[:user_id])犯人はこれでした!
find
と書くべきところを間違えてfind_by
と書いてますね、なのでfind_by
のカラム名を書くところにsession[:user_id]
が入っているせいで、今回は[1]という整数が入ってるのでそのまんま[1]って名前のカラムを探しに行こうとしてしまった、そんな感じみたいですね。↓こんな感じの事ですね!
User.find_by(1)という事で
User.find(session[:user_id])
find
に書き換えて解決!学び
find
をfind_by
と間違えると高確率でUnsupported argument type: ... (Integer)
が出ると思うのでこんな感じのエラーを見かけたらfind
周りチェックするのがいいかもですね!
- 投稿日:2020-07-31T01:03:28+09:00
railsでmodelを作成する方法
railsでmodelを作成する方法
modelはデータベースとのやりとりを行ってくれます。
modelを作成するコマンドはこんな感じです。$ rails g model モデル名モデル名の命名規則は、「User」のように、英数字の単数形で指定します。
また、先頭は必ず英大文字で記述します。実際に、modelを作成するためのコマンドを打つとこんな感じです。
$ rails g model User成功すると、、、
$ rails g model User Running via Spring preloader in process 4271 invoke active_record create db/migrate/2020072951856_create_users.rb create app/models/user.rb invoke test_unit create test/models/user_test.rb create test/fixtures/users.yml作成されるファイルは以下の4つです。
db/migrate/(作成日時)create_lists.rb:「マイグレーションファイル」というデータベースの設計図になるファイルです。
app/models/list.rb:モデルクラスはデータベースに対応したRubyのクラスです。
test/models/listtest.rb:モデルクラスのテストコードのひな形です。
test/fixtures/lists.yml:テストデータ作成のためのひな形です。
- 投稿日:2020-07-31T00:44:25+09:00
railsでルーティングを設定する方法
railsでルーティングを設定するには
routing(ルーティング)では、ユーザが特定のURLにアクセスした時に、
どのコントローラのどのアクションに処理を振り分けるかを定義します。
ルーティングは、URLとアクションを結びつける役目をしています。
例えば、「あるURLにアクセスがあった時に、homeコントローラのtopアクションの処理を振り分ける」という定義を、ルーティングに記述します。ルーティングの設定は、configフォルダ内のroutes.rbファイルに記述します。
routes.rbファイルは、Railsアプリを作成するときに自動作成されるファイルです。
こんな感じです。HTTPメソッド 'URL' => 'コントローラ#アクション'※HTTPメソッドについてはこちらの記事で説明しています。
https://qiita.com/yusuke1209kitamura/items/e29787bc2920a656d505わかりやすく、実際に書いてみます。
Rails.application.routes.draw do get 'top' => 'homes#top' endこの例の場合、URL「top」にアクセスすると、
homesコントローラのtopアクションが呼び出されるように設定しています。