- 投稿日:2020-01-22T23:43:23+09:00
railsサイトマップをサーチコンソールに送る方法
route.rb
get 'sitemap', to: redirect('https://s3-ap-northeast-1.amazonaws.com/バケット名/sitemaps/sitemap.xml.gz')sitemap.rb
SitemapGenerator::Sitemap.default_host = "サイトのurl" SitemapGenerator::Sitemap.sitemaps_host = "https://s3-ap-northeast-1.amazonaws.com/#{ENV['S3_BUCKET_NAME']}" SitemapGenerator::Sitemap.sitemaps_path = 'sitemaps/' SitemapGenerator::Sitemap.adapter = SitemapGenerator::AwsSdkAdapter.new( ENV['S3_BUCKET_NAME'], aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'], aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'], aws_region: 'ap-northeast-1' ) SitemapGenerator::Sitemap.create do add posts_path, changefreq: 'daily' posts = Post.published posts.find_each do |post| add post_path(post), lastmod: post.updated_at end endherokuに環境変数を設定する。
search console
ドメイン/sitemapで登録
- 投稿日:2020-01-22T23:26:45+09:00
JSON Web Token(JWT)を用いたAPIの認証の実装(Rails)
解決する課題
従来のWebアプリケーションでは、認証情報をCookiesを利用して保持し、ログイン状態を保つことを実現しています。
APIではブラウザを介さないことからCookiesを使用したセッションの保持は行えないため、認証時に生成したトークンを用いて認証済み(ログイン状態)であることを表現できます。
JSON Web Tokenの利用
認証時に生成するトークンは慣例通りJSON Web Token(JWT)を利用します。
Railsでは"jwt"というGemがあるので、簡単に扱うことができます。アプリケーションによりますが、controller/concernsに認証用モジュールを設け、そこにJWT関連の処理をまとめて記載すると扱いやすいです。
暗号化・復号化の実装
手始めに、暗号化・復号化の実装例は下記のようになります。
app/controller/concerns下に作成しています。jwt_authenticator.rbmodule JwtAuthenticator require "jwt" SECRET_KEY = Rails.application.secrets.secret_key_base # 暗号化処理 def encode(user_id) expires_in = 1.month.from_now.to_i # 再ログインを必要とするまでの期間を1ヶ月とした場合 preload = { user_id: user_id, exp: expires_in } JWT.encode(preload, SECRET_KEY_BASE, 'HS256') end # 復号化処理 def decode(encoded_token) decoded_dwt = JWT.decode(encoded_token, SECRET_KEY_BASE, true, algorithm: 'HS256') decoded_dwt.first end end暗号化処理では、ユーザーのIDをカスタムクレームとして含め、jwt標準のクレームのexpと合わせてPayloadを作成しています。
これを秘密鍵を用いて、HS256のアルゴリズムで暗号化します。復号化処理では、秘密鍵を用いて復号化を行います。
第三引数のTrueはトークンの検証を行うかどうかなので、Trueにしましょう。
復号化を行うと、配列が返却され、1つ目の要素がPayloadとなっているので、それを返却しています。ちなみに、もしPayloadに各種標準クレームを含めた場合、第四引数以降には標準クレームの検証を行うかどうか、verify_iat: trueのように指定できます。
この辺りの詳細はJWTについての資料を参考にしてください。
個人的にはこのサイトを参考にさせていただきました。
https://ruby-rails.hatenadiary.com/entry/20181118/1542521671ログインの実装
上記の暗号化処理を用いて生成したトークンをレスポンスヘッダに含めて渡します。
ログインを行うコントローラの実装例は下記です。sessions_controller.rbclass SessionsController < ApplicationController include JwtAuthenticator def create # ログインIDを元にユーザーを取得 @current_user = User.find_by(sign_in_id: params[:sign_in_id]) # パスワードによる認証 if @current_user&.authenticate(params[:password]) # jwtの発行 jwt_token = encode(@current_user.id) # レスポンスヘッダーにトークンを設定 response.headers['X-Authentication-Token'] = jwt_token # 任意のレスポンスを返す render json: @current_user else raise UnableAuthorizationError.new("ログインIDまたはパスワードが誤っています。") end end endID、パスワードによる認証ができた場合、レスポンスヘッダに生成したトークンを設定します。
例えばこのAPIを利用したアプリケーションでは、このヘッダからトークンを取得して、以降のAPIに含めて実行します。JWTの認証
リクエストヘッダーに含まれてきたJWTを認証する実装例は下記の通りです。
先ほどのモジュールに処理を追加しています。jwt_authenticator.rbmodule JwtAuthenticator require "jwt" SECRET_KEY = Rails.application.secrets.secret_key_base # ヘッダーの認証トークンを復号化してユーザー認証を行う def jwt_authenticate raise UnableAuthorizationError.new("認証情報が不足しています。") if request.headers['Authorization'].blank? # 下記のようにヘッダーに設定されているとして、トークンをヘッダーから取得する。 # headers['Authorization'] = "Bearer XXXXX..." encoded_token = request.headers['Authorization'].split('Bearer ').last # トークンを復号化する(トークンが復号できない場合、有効期限切れの場合はここで例外が発生します。) payload = decode(encoded_token) # Payloadから取得したユーザーIDでログインしているユーザー情報を取得 @current_user = User.find_by(id: payload[:user_id]) raise UnableAuthorizationError.new("認証できません。") if @current_user.blank? @current_user end # 暗号化処理 def encode(user_id) ... end # 復号化処理 def decode(encoded_token) ... end endこの認証処理を各コントローラで、before_actionなどで実装します。
users_controller.rbclass UsersController < ApplicationController include JwtAuthenticator before_action :jwt_authenticate, except: :create # 非ログイン状態で行うユーザー登録処理 def create user = User.new(user_params) if user.save render json: user else render json: user.errors end end # ログイン中でないと実行してはいけない処理 def show render json: @current_user end private def user_params params.require(:user).permit(:name, :sign_in_id, :password) end end応用
全てのControllerにbefore_actionを設定するのは面倒なので、
認証用のモジュールを下記のように実装すれば、includeして、jwt_authenticateを記述するだけでactionの前に認証を行うようにできます。jwt_authenticator.rbmodule JwtAuthenticator require "jwt" # ↓を必ずextendする extend ActiveSupport::Concern # jwt_authenticateを記載したコントローラにprepend_before_actionを定義する module ClassMethods def jwt_authenticate(**options) class_eval do prepend_before_action :jwt_authenticate!, options end end end ... endコントローラ側
users_controller.rbclass UsersController < ApplcationController include JwtAuthenticator jwt_authenticate except: :create ... endさらに、ApplicationControllerに"include JwtAuthenticator"を記載すれば、省くこともできます。
都合に合わせて実装しましょう。あとがき
実際に動作させている処理を元に記事を書きましたが、はしょったり部分的に切り出して書いた例なので、引用する際はご注意ください。
認証処理はアプリ開発最初の壁だと思います。
また、なあなあにしていたら後々に響いてくる部分でもあると思います。
少しでも参考になれば幸いです。
- 投稿日:2020-01-22T22:19:45+09:00
RESTfulとは。。。
Ruby on Rails初心者です。
RESTfulという言葉をよく耳にするので自己理解も兼ねてまとめたいと思います。RESTfulとは
RESTの規約に従った、Webサービスのこと。
このRESTは以下のような特徴を持っています。◉アドレス可能性
リソースをURIとして一意に指し示すことができる◉ステートレス性
一つ一つのリクエストに処理に必要な情報を全て含める性質(自己完結型)◉統一インターフェース
URIで指し示したリソースに対する操作を、GETやPOSTといった8つメソッドに絞り込み、限定的なインターフェースを行う◉接続性
リソースをリンクで接続し、一つの情報に他のリンクの情報なども含めることができることRESTfulにすることのメリット
○ URIの部分などで、美しくわかりやすいインターフェースを表現できる
○ 他の開発者が設計を理解しやすくなる
○ いちいちURLやHTTPメソッドを考えないで済む
○ サーバがクライアントの情報を共有しないことにより、スケーラビリティが向上する。
(サーバがクライアントの情報を記憶するようにしてしまうと(ステートフル)、クライアントが増えていった際にサーバを増加させる必要がありますが、その際にクライアントの情報をサーバ間で同期する必要があり、オーバヘッドが発生してしまいます。)まとめ
RESTfulな設計をしていくことで、わかりやすいWebアプリケーションをつくることができるようになる(と感じました)
- 投稿日:2020-01-22T21:44:47+09:00
TECH EXPERT 短期集中_転職コース 70期 3日目の振り返り
1/22 (水)
10時〜11時 自習
11時〜11時半 朝礼 昨日と同じ
11時40〜18時 FOCUS DAY 60分超集中→20分超整理
18時〜22時 自習 Railsに苦戦 マイグレーションファイルをミス
進捗率100%にできたが、理解度は50%以下・・・
- 投稿日:2020-01-22T19:19:18+09:00
Ruby on Railsとは、なんなのか簡単に説明してみる(自分なりの解釈)
- 投稿日:2020-01-22T19:19:16+09:00
[Ruby on Rails]データベースの作成、カラムの追加
いつも忘れるのでRubyonRailsでのデータベースの作成、カラムの追加についてメモ
データベース作成
まずはデータベースへの変更指示を記述するマイグレーションファイルを作成する
モデル(User)も同時に作成される。カラムは(パラメーター名):(変数の型)
で設定
コマンドラインでカラム設定しないでファイルに直書きでもOKterminalrails g model User name:text address:text age:integer
次にマイグレーションファイル内容を実行する
terminalrails db:migrate
上のコマンドの代わりにこっちでも実行できるけど違いは分かりません(調べます)
terminalbundle exec rake db:migrate
カラム追加
まずマイグレーションファイルを任意の分かりやすいファイル名で作成
terminalrails g migration add_occupation_to_users
次に作成したマイグレーションファイルに変更内容を書き込む
add_occupation_to_users.rbclass AddOccupationToUsers < ActiveRecord::Migration[5.2] def change add_column :users, :occupation, :string end endそしたら再びマイグレーションファイル実行
terminalrails db:migrate
- 投稿日:2020-01-22T18:14:35+09:00
Railsチュートリアル 第2章
この章では、scaffold機能を使ってコードを自動生成する方法などを学んだ。
scaffoldとは
本来、Railsでアプリケーションを作成するには、モデル、コントローラー、ビュー等を作り、ルーティングも作成する必要があるが、それをコマンド一つで一括で作成してくれるのがscaffold。
試しにscaffoldを試してみると
今回は、ユーザー情報(名前、メールアドレス)の登録・更新・削除が行える画面を作ってみる。
$ rails generate scaffold User name:string email:string invoke active_record create db/migrate/20200122063729_create_users.rb create app/models/user.rb ⇨モデル作成 invoke test_unit create test/models/user_test.rb create test/fixtures/users.yml invoke resource_route ⇨ルーティング作成 route resources :users invoke scaffold_controller create app/controllers/users_controller.rb ⇨コントローラー作成 invoke erb create app/views/users ⇨ビュー作成 create app/views/users/index.html.erb create app/views/users/edit.html.erb create app/views/users/show.html.erb create app/views/users/new.html.erb create app/views/users/_form.html.erb invoke test_unit create test/controllers/users_controller_test.rb invoke helper create app/helpers/users_helper.rb invoke test_unit invoke jbuilder create app/views/users/index.json.jbuilder create app/views/users/show.json.jbuilder create app/views/users/_user.json.jbuilder invoke test_unit create test/system/users_test.rb invoke assets invoke coffee create app/assets/javascripts/users.coffee invoke scss create app/assets/stylesheets/users.scss invoke scss create app/assets/stylesheets/scaffolds.scssconfig/routes.rb に「resources :users」が追加された事で、Railsで定義されている7つのアクションがセットで追加されていることがわかります。
$ rails routes Prefix Verb URI Pattern Controller#Action users GET /users(.:format) users#index POST /users(.:format) users#create new_user GET /users/new(.:format) users#new edit_user GET /users/:id/edit(.:format) users#edit user GET /users/:id(.:format) users#show PATCH /users/:id(.:format) users#update PUT /users/:id(.:format) users#update DELETE /users/:id(.:format) users#destroy root GET /正確に言うと、updateが2つ存在し、8つのアクションが作成されているが、PUTリクエストの方は昔の名残?か何かで実際にはPATCHが使われる。
また、7つのアクションが作成されると言ったが、usersコントローラーを見ると、7つ以上のアクションが自動で作成されているが、このcreate,update,destroyはページを出力せずベータベース上のユーザー情報の操作するだけのため。
一括で作成できたが、問題もたくさん
scaffoldコマンド一つで、ユーザーの新規登録、更新、削除が行える画面が作成できたが、この時点では下記のような問題が残っている。
- データの検証が行われていないので、空情報を登録できてしまう
- ユーザー認証が行われていないので、誰でも自由に登録や削除ができてしまう
- テストが書かれていない
- レイアウトが整っていない
scaffoldの取り消し
間違った名前などで作成してしまったなどした時の取り消し手順
$ rails destroy scaffold users但し、これだけではデータベースにまだテーブルが残ってしまうので、マイグレーションファイルを作成する。
rails g migration users作成したマイグレーションフィアるにusersテーブルの削除命令を書く。
class Users < ActiveRecord::Migration[5.1] def change drop_table :users end endあとはマイグレートして無事完了
$ rails db:migrate@記号で始まる変数
@で始まる変数をインスタンス変数と呼び、コントローラー内で宣言されたインスタンス変数はビューでも使えるようになる。
つまり、逆に@が付いていない変数はビューでは使えない。def index @users = User.all endこの章で失敗したこと
試しにscaffoldしたファイル群を削除するのをしたときにusersテーブルの削除するマイグレーションファイルが残ったまま、herokuにpushしてしまい、migrateしてもエラーが出ているのを5分ぐらい気づけなかった。。
- 投稿日:2020-01-22T17:16:55+09:00
jiraのapi
jiraのapi
basic認証とoauth認証があるみたいだが、oauth認証はaccess tokenを取得して、再取得するのが面倒そうなので、basic認証を使うことに。
が、Deprecatedになったみたい?
https://community.atlassian.com/t5/Confluence-questions/Trying-to-access-Confluence-using-Basic-Authentication/qaq-p/1268998api_tokenを使ってapi呼び出し
こっち見るとapi_tokenというのを使えばいいみたい
https://community.atlassian.com/t5/Confluence-questions/Trying-to-access-Confluence-using-Basic-Authentication/qaq-p/1268998ということでrubyだと以下で取れる。
jira-rubyというgemがあるが今の所対応してないので、自分で取るしかないみたいuser_name = "hogehoge@hoge.com" api_token = 'mogemogemoge' jira_api_endpoint = "https://hogemogehoge.atlassian.net" result_json = JSON.parse(`curl -u #{user_name}:#{api_token} #{jira_api_endpoint}`)
- 投稿日:2020-01-22T15:57:09+09:00
【初心者向け】Fizzbuzzをメソッドを使用して解く
Fizzbuzzの問題を応用し、数字の横にFizzbuzzを表示させてみた。
条件
・1~100までを表示させる
・3は数字の3とその横にfizzと表示
・5は数字の5とその横にbuzzと表示
・15は数字の15とその横にfizzbuzzと表示
・それぞれfizz,buzz,fizzbuzzのメソッドを使用すること擬似コードを書く
def fizzbuzz #15と表示 #15の横にfizzbuzzと表示させる end def fizz #3と表示 #3の横にfizzと表示させる end def buzz #5と表示 #5の横にbuzzと表示させる end 1~100までの繰り返し文 もし15で割って0なら fizzbuzzメソッドへ もし3で割って0なら fizzメソッドへ もし5で割って0なら buzzメソッドへ その他は 数字をそのまま表示 end endコーディングしていく
def fizzbuzz(num) print num num = "fizzbuzz" puts ":#{num}" end def fizz(num) print num num = "fizz" puts ":#{num}" end def buzz(num) print num num = "buzz" puts ":#{num}" end (1..100).each do |num| if num % 15 == 0 fizzbuzz(num) elsif num % 3 == 0 fizz(num) elsif num % 5 == 0 buzz(num) else puts num end endポイント
・引数のnumを除いてやってみると、Nameerrorが出ます。
・printは改行せずに表示してくれます。
・putsは改行します。動作確認
1 2 3:fizz 4 5:buzz 6:fizz 7 8 9:fizz 10:buzz 11 12:fizz 13 14 15:fizzbuzz 16 17 18:fizz 19 20:buzz 21:fizz 22 23 24:fizz 25:buzz 26 27:fizz 28 29 30:fizzbuzz 31 32 33:fizz 34 35:buzz 36:fizz 37 38 39:fizz 40:buzz 41 42:fizz 43 44 45:fizzbuzz 46 47 48:fizz 49 50:buzz 51:fizz 52 53 54:fizz 55:buzz 56 57:fizz 58 59 60:fizzbuzz 61 62 63:fizz 64 65:buzz 66:fizz 67 68 69:fizz 70:buzz 71 72:fizz 73 74 75:fizzbuzz 76 77 78:fizz 79 80:buzz 81:fizz 82 83 84:fizz 85:buzz 86 87:fizz 88 89 90:fizzbuzz 91 92 93:fizz 94 95:buzz 96:fizz 97 98 99:fizz 100:buzzこんなお遊びがお役に立てると幸いです。
ここからさらにFizzbuzzを遊んでいきます。
fizzbuzzの際は、さらにアホゥと叫ぶコードを追加していきます。っといっても引数を追加して表示させるだけなのですが、
fizzbuzzの際に、さらにアホゥと数字の横に並べて表示させる
def fizzbuzz(num, aho) print num num = "fizzbuzz" aho = "アホゥ!" print ":#{num}" puts "#{aho}" end def fizz(num) print num num = "fizz" puts ":#{num}" end def buzz(num) print num num = "buzz" puts ":#{num}" end (1..100).each do |num, aho| if num % 15 == 0 fizzbuzz(num, aho) elsif num % 3 == 0 fizz(num) elsif num % 5 == 0 buzz(num) else puts num end end動作確認(アホゥver)
1 2 3:fizz 4 5:buzz 6:fizz 7 8 9:fizz 10:buzz 11 12:fizz 13 14 15:fizzbuzzアホゥ! 16 17 18:fizz 19 20:buzz 21:fizz 22 23 24:fizz 25:buzz 26 27:fizz 28 29 30:fizzbuzzアホゥ! 31 32 33:fizz 34 35:buzz 36:fizz 37 38 39:fizz 40:buzz 41 42:fizz 43 44 45:fizzbuzzアホゥ! 46 47 48:fizz 49 50:buzz 51:fizz 52 53 54:fizz 55:buzz 56 57:fizz 58 59 60:fizzbuzzアホゥ! 61 62 63:fizz 64 65:buzz 66:fizz 67 68 69:fizz 70:buzz 71 72:fizz 73 74 75:fizzbuzzアホゥ! 76 77 78:fizz 79 80:buzz 81:fizz 82 83 84:fizz 85:buzz 86 87:fizz 88 89 90:fizzbuzzアホゥ! 91 92 93:fizz 94 95:buzz 96:fizz 97 98 99:fizz 100:buzzここは違うよ。または、ここはこうしたほうがセンスいいんじゃない?
等々ございましたらご指摘いただけますと幸いです。最後までみていただき、ありがとうございました。
- 投稿日:2020-01-22T15:14:08+09:00
Railsチュートリアル 第1章
Railsチュートリアルを進めていく上での備忘録。
環境
PC:MacBook Pro
IDE:AWSCloud9
Rilsバージョン:5.1.6
Rubyバージョン:2.6.3Cloud9を使用する場合、c9コマンドが使えると便利なので、インストールしておく。
$ npm install -g c9作業しやすい様にbashrcも変更しておく。
bashrc# .bashrc export PATH=$PATH:$HOME/.local/bin:$HOME/bin # load nvm export NVM_DIR="$HOME/.nvm" [ "$BASH_VERSION" ] && npm() { # hack: avoid slow npm sanity check in nvm if [ "$*" == "config get prefix" ]; then which node | sed "s/bin\/node//"; else $(which npm) "$@"; fi } # [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm rvm_silence_path_mismatch_check_flag=1 # prevent rvm complaints that nvm is first in PATH unset npm # end hack # User specific aliases and functions alias python=python3.6 # modifications needed only in interactive mode if [ "$PS1" != "" ]; then # Set default editor for git git config --global core.editor /usr/bin/nano # Turn on checkwinsize shopt -s checkwinsize # keep more history shopt -s histappend export HISTSIZE=100000 export HISTFILESIZE=100000 export PROMPT_COMMAND="history -a;" # Source for Git PS1 function git_type=$(type -t __git_ps1) if [ -z $git_type ] && [ -e "/usr/share/git-core/contrib/completion/git-prompt.sh" ]; then . /usr/share/git-core/contrib/completion/git-prompt.sh fi # Cloud9 default prompt _cloud9_prompt_user() { if [ "$C9_USER" = root ]; then echo "$USER" else echo "$C9_USER" fi } git_branch() { git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/' } git_color() { [[ -n $(git status --porcelain=v2 2>/dev/null) ]] && echo 31 || echo 33 } # PS1='\[\033[01;32m\]$(_cloud9_prompt_user)\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]$(__git_ps1 " (%s)" 2>/dev/null) $ ' #PS1="╭─○ \[\033[01;32m\]${C9_USER}\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]$(__git_ps1 " (%s)")╰─○ " PS1="╭─○ \[\033[\$(git_color)m\]\$(git_branch)\[\033[00m\]\[\033[01;34m\]\w\[\033[00m\]$(__git_ps1 " (%s)") ╰─○ " fi [[ -s "$HOME/.rvm/environments/default" ]] && source "$HOME/.rvm/environments/default" # Add RVM to PATH for scripting. Make sure this is the last PATH variable change. export PATH="$PATH:$HOME/.rvm/bin" peco-select-history() { declare l=$(HISTTIMEFORMAT= history | sort -k1,1nr | perl -ne 'BEGIN { my @lines = (); } s/^\s*\d+\s*//; $in=$_; if (!(grep {$in eq $_} @lines)) { push(@lines, $in); print $in; }' | peco --query "$READLINE_LINE") READLINE_LINE="$l" READLINE_POINT=${#l} } bind -x '"\C-r": peco-select-history' #alias hub-pr="hub pull-request | open" #alias git="hub" alias ping-loop="while true; do ping www.google.com; sleep 3; done;" alias gommit="git commit" alias tag-gen="ripper-tags -e -R -f TAGS" alias h="heroku" alias la="ls -a" alias lf="ls -F" alias ll="ls -l" alias lv="less" alias e="emacs -nw" alias g="git" alias ga="git add -A" alias gc="git commit -m" alias gp="git push" #alias gs="git status" alias gd="git diff" alias gl="git log --pretty='format:%Cblue[%ad] %Cgreen%an %Creset%s' --date=short" alias gr="git remote -v" alias v="vim" alias r="rails" alias bi="bundle install" alias be="bundle exec"変更したbashrcを反映する。
source ~/.bashrcGemとは
gem
Rubyで使用することのできる汎用性の高い機能をまとめたライブラリを管理するシステムの事を言う。また、それぞれのライブラリの事をgemという。
Bundler
Bundlerはgemを管理するためのgemです。
Gemfile
gemをインストールするための「設計図」のようなもの。
自身のアプリケーションに必要なgemを記述する。Gemfile.lock
実施にgemをインストールした後の、「結果図」のようなもの。
gem同士は関連しあっていることが多いので、Gemfileに書いてあるgemの他にも必要なgemが生じます。Bundlerは、それらを自動でインストールし、Gemfile.lockに記述する。bundle installとbundle updateの違い
bundle install
Gemfile.lockを元にgemのインストールを行う。
この時、Gemfile.lockに記述されていない、且つGemfileに記述されているgemが存在する場合、そのgemとそgemに関連するgemをインストール後、Gemfile.lockが更新される。bundle update
Gemfileを元にインストールを行う。
その後、Gemfile.lockを更新する。withoutオプション
$ bundle install --without 環境名 ⇨指定した環境のgemをインストールしなくできるまた、このオプションを一度実行すると、「.bundle/config」に設定が保存され、今後「bundle install」を実行する時に「--without」オプションを追加する必要がなくなる。
$ cat .bundle/config --- BUNDLE_WITHOUT: "production"githubへのプッシュ
$ git init ⇨初期化 $ git add -A ⇨プロジェクトのファイルをリポジトリに全て追加 $ git commit -m "Initialize repository" ⇨リポジトリにコミット ↓公開鍵が作成されている事 $ git remote add origin git@github.com:s-yoshi210/hello_app.git ⇨リポジトリ追加 $ git push -u origin master ⇨リポジトリへのプッシュHerokuへのデプロイ
$ source <(curl -sL https://cdn.learnenough.com/heroku_install) ⇨Herokuインストール $ heroku login --interactive ⇨Herokuログイン $ heroku keys:add ⇨SSHキー追加 $ heroku create ⇨Herokuサーバーにアプリケーションの実行場所を作成 $ git push heroku master ⇨HerokuにリポジトリをプッシュHerokuのアプリケーション名変更
$ heroku rename 任意のアプリ名 ⇨但し、既に誰かによって使われている名称は使用不可Herokuのアプリケーション削除
$ heroku apps:destroy --app アプリ名 --confirm アプリ名
- 投稿日:2020-01-22T13:44:33+09:00
トップレベルで定義したメソッドは全クラスのプライベートメソッドとなる
イントロダクション
西遊記より
孫悟空にお釈迦様は言われます「私の掌から飛び出すことができれば、お前を自由にしてやる」。悟空は筋斗雲に飛び乗り世界の端を目指します。ここまで来たら大丈夫だろうとそこの山に「悟空参上!」と書きました。お釈迦様に報告した所、お釈迦様の掌にはその文字が書いてありました。一見奇妙なコード
ある日、肥大化したクラスをリファクタリングしようと処理を分割していた時、不思議な現象に遭遇しました。
class Hoge def execute @str = "Hello Ruby!" hello end end def hello puts @str end hoge = Hoge.new hoge.execute # => Hello Ruby!このコードは問題なく動作して「Hello Ruby!」を出力します。
しかしなぜ分離独立している筈のhelloメソッド内部でHogeクラスのインスタンス変数strを参照できているのでしょうか?他の言語ならエラーになりそうなのに。何がおきているのか
まずRubyのトップレベルに書いたメソッドがどこに定義されるのかというと
Kernelモジュールのprivateに定義されます。
(追記:コメントにて指摘されていますが、正しくはObjectに定義されます)p Kernel.private_methods # => [:hello, ...]helloメソッドが追加されていることが確認できます。
このKernelモジュールはObjectクラスにてインクルードされ、さらにすべてのクラスはObjectを継承します。
この関係を確認してみましょう。p Hoge.ancestors # => [Hoge, Object, Kernel, BasicObject]ここまで来ればHogeクラスにもhelloメソッドが定義されていることに気が付くでしょう。
p Hoge.private_methods # => [:hello, ...]結論
トップレベルで定義したメソッドは全クラスのプライベートメソッドとなる
helloメソッドはHogeクラスから分離独立しているように見えるが、実際は内部に定義されていたのです。だから普通にインスタンス変数にもアクセスできたのです。
Rubyの基礎階層を理解していないと孫悟空の様にホワッ?となるエピソードでした。
- 投稿日:2020-01-22T12:57:51+09:00
Rubyメソッド集(不定期更新)
Rubyのメソッドに関して、まとめていきます。
*新しいメソッドを学習次第、追記・更新していきます。Ruby メソッド
文字列を分割/split
String型変数名.split("区切り文字", 分割後の要素数)splitメソッドは、対象となる文字列を指定した区切り文字によって分割し、
それぞれを配列の要素として格納します。例"Ruby, Rails, JavaScript".split”(",") #=>["Ruby", " Rails", " JavaScript"]先頭の小文字を大文字に変換/capitalize
文字列.capitalizecapitalizeメソッドは、先頭の小文字を大文字に変換したい場合に使用するメソッドです。
例rails.capitalize #=>"Rails"文字列を反転/reverse
reverseメソッドは、指定した文字列を反転して取得したい場合に使用するメソッドです。
文字列.reverse例"abcde".reverse #=>"edcba"文字列を大文字(小文字)に変換/upcase,downcase
upcase,downcaseメソッドは、指定した文字列を大文字(小文字)に変換して取得したい場合に使用するメソッドです。
文字列.upcase(downcase)例"Hello, world".upcase #=>"HELLO, WORLD" "HELLO, WORLD".downcase #=>"hello world"参照
【Java入門】文字列を分割するsplitメソッドの使い方(List化も解説)
https://www.sejuku.net/blog/14487はじめてのRuby!文字列を大文字⇔小文字に変換する方法まとめ
https://www.sejuku.net/blog/60402Rubyの文字列で使えるメソッド・使い方総まとめ
また何か見つけたら、追記していきます。
以上となります。最後までご覧いただき、ありがとうございました!
今後も学習した事項に関してQiitaに投稿していきますので、よろしくお願いします!
記述に何か誤りなどございましたら、お手数ですが、ご連絡いただけますと幸いです。
- 投稿日:2020-01-22T12:20:05+09:00
Rails6 のちょい足しな新機能を試す 117(puma pidfile編)
はじめに
Rails 6 に追加された新機能を試す第117段。 今回は、
puma pidfile
編です。
Rails 6 では、rails new
したときにconfig/puma.rb
にpidfile
の設定が追加されるようになりました。
pumactl
で制御できるようにするためのようです。なお、この修正は、Rails 5.2.4 にも反映されています。
Ruby 2.6.5, Rails 6.0.2.1, Rails 5.2.3, Rails 5.2.4.1 で確認しました。 (Rails 6.0.0 でこの修正が入っています。)
$ rails --version Rails 6.0.2.1Rails プロジェクトを作る
Rails プロジェクトを新たに作成します。
$ rails new rails_sandbox $ cd rails_sandbox
config/puma.rb
を確認する
config/puma.rb
を確認するとpidfile
の設定があることがわかります。config/puma.rb... # Specifies the `pidfile` that Puma will use. pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }試してみる
普通に、
rails s
でサーバーを起動します。$ bin/rails s
別のコンソールから、プロジェクトのディレクトリに移動して
pumactl status
を実行してみます。$ pumactl status Puma is started
リスタートしてみます。
$ pumactl restart Command restart sent success
rails s
を実行したコンソールで puma (rails) が再起動されました。=> Booting Puma => Rails 6.0.2.1 application starting in development => Run `rails server --help` for more startup options Puma starting in single mode... * Version 4.3.1 (ruby 2.6.5-p114), codename: Mysterious Traveller * Min threads: 5, max threads: 5 * Environment: development * Listening on tcp://127.0.0.1:3000 Use Ctrl-C to stop * Restarting... # <=== ココ => Booting Puma => Rails 6.0.2.1 application starting in development => Run `rails server --help` for more startup options Puma starting in single mode... * Version 4.3.1 (ruby 2.6.5-p114), codename: Mysterious Traveller * Min threads: 5, max threads: 5 * Environment: development * Listening on tcp://127.0.0.1:3000 Use Ctrl-C to stopRails 5 では
Rails 5.2.4.1 では、Rails 6 と同じ動作になりますが、 Rails 5.2.3 では、
pumactl status
を実行してもエラーメッセージが表示されます。$ pumactl status Neither pid nor control url available
参考情報
- 投稿日:2020-01-22T11:59:08+09:00
rails gするとundefined local variable or method `config' for main:Object (NameError)が出て困った話
はじめに
spring stop
すればいいよ!とか書いてあって対処したもののさっぱり解決しなかったので、色々試行錯誤した時の話です。どんなエラーが出たか
以下のようなエラーが出ました。
config
がなんか変らしいです。/Users/t-nakagawa/rails/config/application.rb:46:in `<top (required)>': undefined local variable or method `config' for main:Object (NameError) from /Users/t-nakagawa/rails/vendor/bundle/ruby/2.6.0/gems/spring-2.0.2/lib/spring/application.rb:92:in `require' from /Users/t-nakagawa/rails/vendor/bundle/ruby/2.6.0/gems/spring-2.0.2/lib/spring/application.rb:92:in `preload' from /Users/t-nakagawa/rails/vendor/bundle/ruby/2.6.0/gems/spring-2.0.2/lib/spring/application.rb:153:in `serve' from /Users/t-nakagawa/rails/vendor/bundle/ruby/2.6.0/gems/spring-2.0.2/lib/spring/application.rb:141:in `block in run' from /Users/t-nakagawa/rails/vendor/bundle/ruby/2.6.0/gems/spring-2.0.2/lib/spring/application.rb:135:in `loop' from /Users/t-nakagawa/rails/vendor/bundle/ruby/2.6.0/gems/spring-2.0.2/lib/spring/application.rb:135:in `run' from /Users/t-nakagawa/rails/vendor/bundle/ruby/2.6.0/gems/spring-2.0.2/lib/spring/application/boot.rb:19:in `<top (required)>' from /Users/t-nakagawa/.rbenv/versions/2.6.3/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require' from /Users/t-nakagawa/.rbenv/versions/2.6.3/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require' from -e:1:in `<main>'該当箇所のコード
spring2.0.2のコードを確認します。
パス関連でエラーを起こしているようなので、configフォルダが怪しいということが分かります。require Spring.application_root_path.join("config", "application")解決しなかった対処方法
spring stop
してはダメでした。これはこれで立ち上げておくとrails g
がエラーになるみたいなんで、停止しておいた方が無難だと思います。解決した対処方法
この作業をする直前にやった
config/application.rb
の作業が良くなくて上手くconfigが処理出来なかったようです。
一旦git restore
で切り戻してrails g
することで無事コマンドが終了してファイルが作成できました。終わりに
何か困った際は一旦切り戻しするの重要。
念の為、周りの人にspringのバージョンが同じであるかの確認とコマンドが成功しているかの確認は行いました。
みんな駄目ならこの環境自体が駄目で自分だけ駄目なら自分の変更による影響というのが分かるので、やっておきましょう。
- 投稿日:2020-01-22T11:41:29+09:00
docker-compose up出でるエラー
概要
いつものようにDocker-compose upするとサーバーが立ち上がらない。
具体的には、↓こんな感じでエラーが出ている。
〈注意すべきポイント〉
bundler: failed to load command: rails (/usr/local/bundle/bin/rails)
Bundler::GemNotFound: Could not find ast-2.4.0 in any of the sources解決策
docker-compose build
で解決!!原因(ここ重要!)
原因によっては対処法が変わってくる。
今回の場合は、前回このアプリを利用した時にgemを追加して
bundle install
したあとに、サーバーの立ち上げしていなかった。参考サイト
- 投稿日:2020-01-22T11:29:35+09:00
Twitter APIで取得したアイコン画像の大きさを変える【Ruby on Rails】
はじめに
TwitterAPIの取得にomniauthを使っています。
またomniauthの基本的な使い方については省略しています。
omniauthの基本的な使い方については別記事を参照してください。開発環境
Ruby 2.6.1
Ruby on Rails 6.0.1Twitterアイコン画像を取得する
app/controllers/twitter_controller.rbclass TwitterController < ApplicationController # 基本的なomniauthの使い方は省略 def twitter auth_hash = request.env["omniauth.auth"] @image_url = auth_hash[:info][:image] end endこのままでは48x48にリサイズされたアイコン画像のURLを取得してしまいます。
小さい!当然CSSなどで拡大してもボヤボヤになってしまいます。大きなTwitterアイコン画像の取得方法
omniauthの設定に使ったファイルを書き換えます。
config/initializers/omniauth.rbRails.application.config.middleware.use OmniAuth::Builder do provider :twitter, Rails.application.credentials.twitter[:key], Rails.application.credentials.twitter[:secret_key], # 以下を追加する { :image_size => "original" } endこうすることによって、本来のサイズでのアイコン画像のURLを取得できます。
参考
omniauth-twitter(GitHub):https://github.com/arunagw/omniauth-twitter
- 投稿日:2020-01-22T10:54:51+09:00
初級者向け アルゴリズムを解説(2)
初級者向け アルゴリズムを解説
これからアルゴリズムについて解説をしていきますが、こちらの解説はプログラミング初級者(「最近プログラミングを始めました!!」向けになります。また数回のシリーズに分けてプログラミングで使用されるアルゴリズムを解説していきます。なお、Rubyを使用してコーディングしています。
※このシリーズは「アルゴリズムを、はじめよう(著:伊藤静香)」を参考にしております。
シリーズ(1): 初級者向け アルゴリズムを解説(1)はこちら定番アルゴリズム
それでは前回の続きから始めましょう。前回、アルゴリズムは「問題や課題を解決するための手順を表現した考え方やアイディア」とお伝えしましたが、アルゴリズムを大きく分けると、探索・整列・数値計算・文字列検索の4つの種類があります。
そしてその種類ごとに基本的な処理手順を持っているアルゴリズムがあり、それらが定番アルゴリズムとなります。アルゴリズムの各種類の定番アルゴリズムは次の通りです。(一部抜粋)
- 探索
- 線形探索法
- 二分探索法
- ハッシュ探索法
- 整列
- 単純選択法
- 単純交換法
- 単純挿入法
- クイックソート
- 数値計算
- エラトステネスのふるい
- ユークリッドの互除法
- ガウスの消去法
- 文字列探索
- 力まかせの検索法
- KMP法
- BM法
今回は探索の線形探索法を説明します。なお、探索アルゴリズムは目的のデータを探し出すアルゴリズムで検索エンジンに使用されているアルゴリズムになります。
線形探索法(リニアサーチ)
線形探索法とは、先頭から順番に調べて探す探索アルゴリズムです。まずはイメージを掴んでいただきたいと思いますので、まず3つの枠に区切られた箱をイメージしてください。その各枠には数字が1つずつ入っていて、その数字は箱から出して見なければわからないようになっています。今回はその箱から1つの数字を探して見たいと思います。今回用意した箱と数字は次の通りです。
[0, 4, 1] (箱が3つの枠に仕切られ、中には0と4と1が見えないように入っているイメージです。)そして、今回は4の数字を探したいと思います。手順は次の通りです。
1. 先頭の枠を確認
2. 入っている数字は0(探したい数字と一致しない)
3. 次の枠に移動
4. 次の枠を確認
5. 入っている数字は4(探したい数字と一致した)
6. 探索終了
それではこれらの内容をコードにしていきましょう。
なお、線形探索法は反復構造(同じ処理を繰り返す)になっているため、必ず反復する処理を終了させる条件を付加してください。(万が一、探したい数字が箱の中にない場合、プログラムを終了させることができなくなります。)Rubyarray = [0, 4, 1] # ①サンプルとして適当な配列を準備 research_number = 4 # ②探索する数字を4を代入 i = 0 # ③要素番号0(先頭)から順に検索 loop { if i > array.length - 1 # ④反復する処理を終了させる条件 puts "探している数字はこの配列に存在しません。" break # loopから抜け出す処理(探索終了) elsif array[i] == request_number # ⑤探したい数値を確認する処理 puts "要素番号#{i}に4があります。" break # loopから抜け出す処理(探索終了) end i += 1 # ⑥次の枠を探索するために要素番号に1を加える処理(⑤で探したい数字が一致しなかった場合) }解説(丸付きの番号は上記コードのコメントに該当)
① 3つの数字が入った配列(箱)を用意しました。今回はこの配列に入っている数字を探索しています。
② 今回は4を探索したいので、変数(research_number)に4を代入しています。
③ 線形探索法では先頭から順番に探索するため、配列の先頭となる要素番号0をiへ代入しています。
--ここまでが、線形探索法の下準備、以下が実際のアルゴリズムになります。---
④ これは反復処理を終了させる条件になっています。
.lengthメソッドを使用することで配列の要素数(array.length)を調べ、そこから1を引くことで配列の最後の要素番号を取得しています。
つまり、iが探索可能な要素番号に収まっているかを確認し、もしiが探索可能な要素番号に収まっていないのであれば探索を強制的に終了させています。
もし、この配列に探したい数字が存在せず、また④の処理がない場合、永遠にiは増え続け、プログラムは終了しません。
⑤ 実際に配列から取り出した数字と探したい数字を確認している処理になります。もし、ここで数字が一致した場合、breakによりプログラムは終了します。
⑥ ⑤で数字が一致しなかった場合の処理になります。配列の次の要素を探索するためにiへ1を足しています。
なお、⑥の処理が終了したあとは④へ戻り、iが配列の要素数を超える、または一致する数字を探す出すまで④から⑥の処理が繰り返し行われます。次回予告
今回はここで終了です。
次回は探索アルゴリズムの二分探索法について説明していきたいと思います。(説明の内容がわかりやすくなるように、徐々に説明方法を修正していきます。)
- 投稿日:2020-01-22T10:34:05+09:00
【Rails】 DataTables 検索結果の保持方法
はじめに
これまでに Rails + DataTable 関連の記事を書いてきましたが、別のページから戻ってきた時に検索結果を保持していて欲しいなどのユーザーの要望があるかと思いますので、そのような細かい設定の変更方法について今回はまとめさせていただきます。
関連リンク
関連リンクを下記に載せておくので、必要であれば参考にしてください。。
- 【Rails】 DataTables 実装方法
- 【Rails】 DataTables 動的にカラムを変更する方法
検索結果の保持方法
次の2つを設定するだけで、検索結果を保持してくれるようになります。
- stateSave
- stateDuration
app/assets/javascripts/concern/datatables.coffeeclass @DataTables # *** 省略 *** drawTable: -> # *** 省略 *** # stateSave : 別のページから戻ってきた時に検索結果を保持するかどうかを設定可能(trueが保持) stateSave: true, # stateDuration : stateSave の検索結果の保持する時間を設定可能(1秒単位で設定可能) stateDuration: 60 * 15, # sec * min # *** 省略 ***まとめ
英語のドキュメントさえ読んで使いこなすことができれば、DataTablesはユーザーのニーズを柔軟に反映した高機能なテーブルを短時間で実装することができます。
Rails と組み合わせると爆速で開発が捗ると思っているので、ぜひ活用してみてください。
- 投稿日:2020-01-22T10:16:07+09:00
Ruby ぼっち演算子について
ぼっち演算子とは
早速本題に入っていきます。
ボッチ演算子とはRuby2.3から実装された機能です。
主に&.
のことを示します。
基本的な使い方は下記のような記述方法ですオブジェクト&.メソッドレシーバーとしての役割をオブジェクトに対してメソッドを実行した場合にそのレシーバーとしての役割を持つオブジェクトがnilだった場合にエラーが出てしまうのですが、そのレシーバーが空のまま実装したいという時もあると思います。
@nickname = current_user.nicknameこのような時です。このcurrent_userはログインしていない時はnilになってしまうのでログインしていないときにこのメソッドが実行されてしまうとエラーになってしまうのですがここでボッチ演算子を使うことでこのからのcurrent_userをnilという表記で出力することができます。
nil
で返すことでエラーが消え、current_userに何も入っていない時でもページを表示することができます。@nickname = current_user&.nickname書き方はこの通りです。メソッドの前に
&
をつけるだけです。こうすることでcurrent_userはnilを返すことができるようになります。少しわかりづらいかもしれないですが、nilだとエラーが出る状況だったのをnilと出力をすることでエラーが出なくなるということです。
ボッチ演算子を使うにあたっての注意点
なおぼっち演算子を使ってもエラーが出ることがあります。それは
NoMethodError(そんなメソッドないよ!)
というようなエラーです。この場合はメソッドが間違っている場合があり、メソッド名を見直す必要ががありそうです。ぼっち演算子の名前の由来
おそらく気になった方も多いと思いますが、ぼっち演算子のぼっちの部分は
&.
がひとりぼっちで座っている姿に見えることから名付けられたそうです。遊び心があって面白いですね。参考
- 投稿日:2020-01-22T00:25:04+09:00
DXOpalがマルチタッチに対応しました
このエントリはOpal Advent Calendar 2019の53日目(?)の記事です。
スマホでのマルチタッチに対応したDXOpal 1.4.4をリリースしました。
以下にデモがあります。スマホやタブレットなどのタッチ対応デバイスで開いてみてください。
タッチ関係のAPIのまとめを載せておきます。
タッチAPI(シングル)
- Input.touch_down? : タッチされているかを返す
- Input.touch_push? : タッチされたかを返す
- Input.touch_release? : タッチが離されたかを返す
指一本で操作できるようなゲームを作るときはこっちが便利です。
タッチAPI(マルチ)
- Input.touches
DXOpal::Touch
の配列を返す- Touchオブジェクトは.id, .x, .y, .dataをもつ。また、.released?で離されたかを返す
- .dataはハッシュで、自分の好きなデータを入れてよい
- Input.new_touches
DXOpal::Touch
の配列を返す(直前のフレームで発生したタッチのみ)マルチタッチに対応したいときはこっちを使います。以下は例です。
- 投稿日:2020-01-22T00:21:07+09:00
自動デプロイ(Capistrano)でエラー mkdir: ディレクトリ `/var/www' を作成できません: 許可がありません
Capistranoで自動デプロイをしていると、エラーが発生しました
テキストだと下記ですね
mkdir stdout: Nothing written mkdir stderr: mkdir: ディレクトリ `/var/www' を作成できません: 許可がありません mkdir: ディレクトリ `/var/www' を作成できません: 許可がありませんこのエラー"var/www/アプリ名"のディレクトリにしている場合は、パーミッションの問題等だと思いますが、、、
「 "var/www/アプリ名"使ってないんですけど!!!
なんでエラーが出るんだよ!!!
"www"が気に食わないから、別のフォルダ名にしてるんですけど!!!
他の記述も確認したけど、全部"var/www/アプリ名"書いてねええよ!!! 」という人向けに対処方法を解説します。
解決策
結論: Capistranoのデフォルト設定が"var/www/アプリ名"を読み込むので、オプション設定で変更する。
deploy.rb# 下記を挿入してください set :deploy_to, '/var/○○○(ディレクトリ名)/○○○(アプリ名)'これを挿入することで、EC2にあるアプリの保存場所を正しく認識され、Capistranoで読み込みが可能となります。
あとは自動デプロイを実行しましょう
# アプリケーションのディレクトリで実行する $ bundle exec cap production deploy今度はうまくいくはずです。
[参考](https://capistranorb.com/documentation/getting-started/configuration/)
- 投稿日:2020-01-22T00:15:50+09:00
TECH EXPERT 短期集中_転職コース 70期 2日目の振り返り
1月21日(火)
2日目の振り返り10〜11時 HTML CSS 振り返り&確認テスト ←ボロボロのため2回やる
11〜11半 朝礼 瞑想5分・ミニドリル15分・メモ書き10分70期から「超集中」の取り組みをしており、1月21〜23日まで11時40〜18時までポモドーロテクニック ←ググって・・・
11時40分〜18時 Rudyに突入 最初は楽勝と思っていたら、ifあたりから雲行きが怪しくなる。文系の自分を恨みたい。結局頭が終始フワフワして、内容はいらず。
18時〜22時 Rudyをひたすら進めるも、whileあたりで死亡。 カリキュラム進捗率100%をきる。
■反省点
集中し切れていない時間が多々あり、フワフワしていた。
パラシュート勉強法及び60%理解を目指していたら20%理解の上にパラシュートが墜落した。あと約38日間持つかどうか不安だが、明日はカリキュラムを理解する努力をしたい。