- 投稿日:2020-05-19T23:54:40+09:00
[rails]deviseのヘルパーメソッドbefore_action :authenticate_user!の使い方
before_action :authenticate_user!について
deviseを簡単に説明すると、ログイン系をやってくれるgemです。
そのdeviseのヘルパーメソッドauthenticate_user!メソッドは、コントローラーにbefore_actionで記載することで、そのコントローラーで行われる処理はログインユーザーのみ実行可能とすることができるメソッドです。
before_action :authenticate_user!の使い方
authenticate_user!メソッドはコントローラーに記載します。
例class PostsController < ApplicationController before_action :authenticate_user! def index end endこのように記載するとposts_controllerでの処理をすることができるのはログインユーザーのみとなります。
一部の処理を未ログインユーザーでも行えるようにする
例
class PostsController < ApplicationController before_action :authenticate_user!, only: [:show] def index end def show end endこのように記載することで、showアクションのみを未ログインユーザーが使用できないようにできます。
間違いなどがありましたらご指摘いただければ幸いです。
最後までご覧いただきありがとうございました。
- 投稿日:2020-05-19T23:28:30+09:00
駆け出しエンジニアのためのRuby便利メソッド
はじめに
駆け出しエンジニアの私が、AtCoderやpaizaでアルゴリズム問題を解いていく中で、とても便利だったメソッドを書き残す。
puts, p, printの違い
自分の言葉で説明しようと思ったが、web上に山ほど記事があったので、止めることにする。
【Ruby超入門】print、puts、pの違い
https://yukimasablog.com/ruby-print-puts-p
【Ruby】p, puts, printメソッドの違い
https://qiita.com/rkkmshde/items/daf75aca9675f5a01d17デバッグの時に使いこなせると、複雑なコードを書く時にかなり効率よくエラーやその原因に気づける。
三項演算子
if 〜 else 〜 end
をもっと効率よく書くことができる。number = 24 if number.even? n = "偶数" else n = "奇数" end puts n # => 偶数この処理が、、、
number = 24 n = number.even? ? "偶数" : "奇数" puts n # => 偶数こうなる。
条件 ? (条件がtrueだった時の処理) : (条件がfalseだった時の処理)
という構造だ。
map
# 入力値 # 12 30 40 input = gets.split.map(&:to_i) # 出力値 # [12, 30, 40] # という風な配列になる。入力値の数値や文字列を一つ一つの要素に分けて配列にしたい時に使うことができる。
"&:"メソッドの説明については、今回は割愛させていただく。
詳しくは、
https://qiita.com/soma_sekimoto/items/a828b8f88b78aac2e7df
こちらの記事を参考に。any? と all? と one?
繰り返し処理を使って条件を満たしているかどうかを確かめたい時に、これらのメソッドがとても役に立つ。
これを知らなかった頃は、全てeachで代用しようとしていたので、コードがとんでもないことになってしまっていた。
array = [30, 14, 23, 15] array.any? {|num| num % 7 == 0} # 7で割り切れる要素(14)がある # => trueany?: 各要素の中で、1つでも条件に合うものがあればtrueを返す。
all?: 全ての要素が条件に合えばtrueを返す。
one?: 各要素の中で、条件に合うものが一つだけであればtrueを返す。
reduce
(1..10).reduce(5) {|a, n| a + n} # => 5 + 1 = 6, この6が次の処理のaとなる。 # つまり、2回目の処理は、6 + 2となる。 # 処理結果 => 60reduceメソッドでは、ブロック処理内の引数を2つ(aとn)設定する。
aは初期値(ここでは5)、nは各要素(ここでは、1から10の整数)になる。between?
23.between?(0, 30) # => true 'G'.between?('A', 'F') # => false指定した値(ここでは、23 と 'G')が範囲内(0〜30 と A〜F)に入っているかどうかを判断するメソッド
index
array = ["ruby", "java", "php"] p array.index("java") # => 1 # "java"のindex番号が返される。transpose
配列に要素として他の配列が格納されている場合に、配列を行列と見なし、行と列を入れ替えるメソッド
array = [[1,2,3,4], [5,6,7,8], [9,10,11,12]] p array.transpose # => [[1,5,9], [2,6,10], [3,7,11], [4,8,12]]行と列の考え方を使うアルゴリズム問題でとても活躍してくれた。
chars
greeting = "hello" p greeting.chars # => ["h", "e", "l", "l", "o"]上記のように、文字列を1文字ずつに分割して配列として返す。
また、こういう書き方もできる。
num = "19800".chars.map(&:to_i) p num # => [1, 9, 8, 0, 0]桁ごとの数字を処理したい時などに使える。
zip
複数の配列を同時に処理したい時は、このzipメソッドが便利だ。
number = [1, 2, 3, 4, 5] alphabet = ["a", "b", "c", "d", "e"] p number.zip(alphabet) number.zip(alphabet) do |num, alpha| p num p alpha end # => [[1, "a"], [2, "b"], [3, "c"], [4, "d"], [5, "e"]] # => 1 # => "a" # => 2 # => "b" ... # => 5 # => "e"上記のように、配列として返すこともできるし、複数の配列にeachメソッドを用いたような処理の仕方もできる。
select, reject
select: {}ブロック内の式がtrueになる要素だけを抽出する。
reject: {}ブロック内の式がfalseになる要素だけを抽出する。p [1, 2, 3, 4, 5, 6].select { |n| n % 2 == 0 } p [1, 2, 3, 4, 5, 6].reject { |n| n % 2 == 0 } # => [2, 4, 6] # => [1, 3, 5]おわりに
rubyは他の言語と比べると、メソッドの数が多いので、直感的なコードが書けることに気がつき、さらにrubyが好きになった。
皆さんもぜひ、rubyを用いてアルゴリズムを書く際は、参考にしてもらいたい。
- 投稿日:2020-05-19T23:13:43+09:00
Railsでグループ機能(掲示板)を作ってみた
Railsでグループ機能(掲示板風)の作成
<開発環境>
1. ruby 2.6.3
2. Rails 5.1.6
3. AWS Cloud9
4. GitHub
6. sqlite3(develop環境)設計構想
ユーザーは自由にグループを作成でき、また他のユーザーが作成したグループに所属することもできます。
また、グループに参加したメンバーはグループ内で自由に発言することも可能になります。この仕組みをテーブルに落とし込むと、
ユーザーとグループは多対多の関係になるので中間テーブルを用いることとします。
そして、ユーザーとグループ内での投稿も多対多の関係となる為、こちらも中間テーブルを用います。
ER図はこんな感じになりました。(手書きですいません・・・)
モデル
先ほどのER図は以下のようなアソシエーションとなりました。
group.rbclass Group < ApplicationRecord validates :name, presence: true, uniqueness: true has_many :group_users has_many :users, through: :group_users has_many :groupposts accepts_nested_attributes_for :group_users endgroup_user.rbclass GroupUser < ApplicationRecord belongs_to :group belongs_to :user endgrouppost.rbclass Grouppost < ApplicationRecord belongs_to :group belongs_to :user endコントローラー
groups_controller.rbclass GroupsController < ApplicationController def new @group = Group.new @group.users << current_user end def create if Group.create(group_params) redirect_to groups_path, notice: 'グループを作成しました' else render :new end end def index @groups = Group.all.order(updated_at: :desc) end def show @group = Group.find_by(id: params[:id]) if !@group.users.include?(current_user) @group.users << current_user end @groupposts = Grouppost.where(group_id: @group.id).all end private def group_params params.require(:group).permit(:name, :user_id []) end def grouppost_params params.require(:grouppost).permit(:content) end end基本的な設計はユーザー周りと同じです。
def show . . if !@group.users.include?(current_user) @group.users << current_user end endこのようにグループのリンクを踏んだ人がそのグループに所属できるようにしています。
grouppost_controller.rbclass GrouppostsController < ApplicationController def new @grouppost = current_user.groupposts.new @group = Group.find_by(id: params[:group_id]) end def create @group = Group.find_by(id: params[:group_id]) @grouppost = current_user.groupposts.new(grouppost_params) @grouppost.group_id = params[:group_id] if @grouppost.save redirect_to group_path(@group.id) end end private def grouppost_params params.require(:grouppost).permit(:content) end endこちらも以前作成した投稿機能と同じ形にしています。
以上で2chちっくなグループ機能(掲示板風)が完成しました。
今後の課題としては、グループ作成時に鍵をかけることができ、招待制のグループを作ることができるようにしたいと考えています。
- 投稿日:2020-05-19T23:01:13+09:00
paizaランクDの達成方法
はじめに
paizaランクDを達成するにはどうすれば良いか?
目安を解説しました。前提
筆者がRubyを主に学習しているので、Rubyで解説しています。
実行
例えば、好きな数値を入力して、それを出力するには次のようなコードを書きます。
x = gets.chomp.to_i puts x二つ以上の数値を入力するには、
gets
を少し書き換える必要があります。x = gets.split().map(&:to_i) puts x
split
メソッドを使えば、複数の入力値を配列として取得できます。
map
メソッドを使えば、配列の中身を簡単に変換することができます。
引数を&:to_i
とすれば、入力値を全て数値として取得できます。ここで、入力した値を二つの場合、一つ目の入力値と二つ目の入力値の差を求めるには次のようにします。
x = gets.split().map(&:to_i) puts x[0] -x[1]xは配列として取得されているので、入力された値の差を計算するには、配列の要素同士の演算子を利用すれば良いです。
以上の事が使いこなせれば。paizaランクDの達成するのは目前です。
- 投稿日:2020-05-19T22:58:22+09:00
個人アプリの制作日記
本日の積み上げ
①個人アプリの構想
②DB設計①個人アプリの構想
■ 個人アプリ名:スタサポ <= 突っ込まれるかも
■ どんなアプリか
ユーザーがメンターさんにわからないところをすぐに聞けるマッチングアプリ▶ 手立て
質問したいときに質問フォーマットにそってユーザーがメンターさんにビデオ通話を申し込む。
グループチャットを通じて勉強し合う。
ユーザーやメンター評価を搭載している。
自分の学びをアウトプットがすることができる。▶ 経緯
昨今はコロナウィルスの影響でオンライン学習が増えている。が動画だけの学習だと受け身になりがちで質問
したいところが聞けない。
1対1のビデオチャットなら好きな質問ができると考えた。
某スクールの学びを通して、わからないところだけ聞く自分がわかっていることを
遠慮なく聞けるサービスに感動から。▶ ユーザー側のメリット
周りに気にしないで、わからないところだけ聞きたい。
動画では整理されていて分かりやすいが、その場の疑問が解決しずらい。
自分がどこまで分かっているのアウトプットしながら確認ができる。
自宅で簡単に取り組むことができる。
コメントや評価を通じて自分の理解度を可視化でき、承認欲求が満たされる。▶メンター視点でのメリット
隙間時間に行うことができる。
教えることに携わりたい人が気軽な気持ちでできる。(その場にいればよい)
その人だけに教えることができる。
誰かに知識を伝える・教えること一番のアウトプット。▶実装したいこと
ビデオ通話での応答
コメント機能
ログイン機能(メンター・生徒)
評価機能(メンター・生徒)
応答可能かどうか
質問フォーム
非同期通信(ビデオ通話、メッセージ)
今日の積み上げページ(アウトプット)■開発環境
rails 5.0.7.2
ruby 2.5.1
gem device② DB設計
usersテーブル
Column Type Options
name string null: false, unique: true
email string null: false, unique: true
password string null: false
my-image string
introduction text
profile text
subject string
rate float
Association
has_many :groups_users
has_many :groups, through: :user_groups
has_many :messages
has_many :tweets
has_many :teaches
groupsテーブル
Column Type Options
name string null: false, unique: true
Association
has_many :user_groups
has_many :users, through: :user_groups
has_many :messages
user_groupsテーブル
Column Type Options
group_id integer null: false, foreign_key: true
user_id integer null: false, foreign_key: true
Association
belongs_to :group
belongs_to :user
groupmessagesテーブル
Column Type Options
comment text null: false
image string
group_id integer null: false, foreign_key: true
user_id integer null: false, foreign_key: true
Association
belongs_to :group
belongs_to :user
Tweetsテーブル
Column Type Options
title string null: false
body text null: false
image string
user_id integer null: false, foreign_key: true
Association
belongs_to :user
tweetmessagesテーブル
Column Type Options
comment text null: false
image string
tweet_id integer null: false, foreign_key: true
user_id integer null: false, foreign_key: true
Association
belongs_to :tweet
belongs_to :user
teachテーブル
Column Type Options
title string
image string
body text
user_id integer null: false, foreign_key: true
Association
has_many :teach_tags
has_many :tags, through: :teach_tags
teach_tagsテーブル
Column Type Options
title string
image string
teach_id integer null: false, foreign_key: true
tag_id integer null: false, foreign_key: true
Association
belongs_to : teach
belongs_to :tag
tegsテーブル
Column Type Options
text string
Association
has_many :teach_tags
has_many :teaches, through: :teach_tags
- 投稿日:2020-05-19T22:24:54+09:00
RailsにFixturesで初期データを入れるためのyamlをCSVから作るスクリプト
Railsのデータベースにデータを投入する方法はfixtures用のyamlファイルを作って、railsコマンドで入れる方法などがよく知られています。
ですが、現実的にはExcelなどで元データを用意してCSV等で扱うことが多いと思われます。
yamlコンバータなども試してみたけどfixtures keyを入れるのがうまくいかなかったので、自分で作りました。
エスケープ文字の処理とかなにもやってないので、元データがそういうものを扱う場合は適宜加工してください。たとえば、1行目にカラム名が入ったこんな感じのCSVファイルがあったとして。
fruits.csvid,item,price 1,りんご,100 2,みかん,80 3,バナナ,60 4,メロン,2000 5,いちご,300Fixturesで扱うにはこういうyamlファイルが必要になります。
fruits.ymldata1: id: 1 item: りんご price: 100 data2: id: 2 item: みかん price: 80 data3: id: 3 item: バナナ price: 60 data4: id: 4 item: メロン price: 2000 data5: id: 5 item: いちご price: 300
data1:
のところがfixtures keyというやつで、データベースには反映されないけど、レコードごとにハッシュとしてユニークな値をつけなければいけないようです。スクリプトはこんな感じです。
ExcelからCSVに変換したら、UTF-8でBOMが付いてしまったので、ファイルをopenするときにオプションが付いてます。csv2yaml.rb#!/use/bin/env ruby filename = ARGV[0] # UTF-8のBOMを消すオプション file = open(filename, 'r:BOM|UTF-8') # CSVファイルの先頭行を取得 column = file.gets.chomp.split(",") # fixtures keyのプレフィックス(data)とそのあとに付けるカウンタ(num) prefix = "data" num = 1 str = "" file.each do |line| unless line.strip == "" ## 空白行を無視する str += "#{prefix}#{num}:\n" (0 .. column.length - 1).each do |i| str += " #{column[i]}: #{line.chomp.split(",")[i]}\n" end str += "\n" num += 1 end end print strShellから実行する時はこんな感じです。
$ ./csv2yaml.rb fruits.csv > fruits.yml500行くらいのCSVデータの変換して問題なかったし、fixturesでも取り込めたので大丈夫なようです。
カラムが異なる複数のCSVファイルでも変換できました。yamlのライブラリなどを使えばもっと簡単に作れるかも。
- 投稿日:2020-05-19T22:14:06+09:00
deviseを導入したが更にカラムを増やしたい時
deviseを使ってみて
deviseを導入したがカラムこれだけって時ありませんか?
今回はカラムの追加方法について説明します!!
1.usersテーブルにカラムを追加します
今回はnameカラムを追加します。
ターミナルで以下のコマンドを実行しましょう。$ rails g migration AddNameToUsers name:string $ rails db:migrate2.application_controller.rbを編集
application_controller.rbを以下のように編集しましょう。
これでユーザー登録時にnameカラムが保存されるようになりました。app/controllers/application_controller.rbclass ApplicationController < ActionController::Base before_action :configure_permitted_parameters, if: :devise_controller? protected def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up, keys: [:name]) end end※今のままでは登録時にしかnameカラムが入っていないので、編集でnameを変更しても変更されません。
3.編集時に追加したカラムの編集もできるようにしましょう!
app/controllers/application_controller.rbclass ApplicationController < ActionController::Base before_action :configure_permitted_parameters, if: :devise_controller? protected def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up, keys: [:name]) <!-- 以下のように編集時の対応する記述も追加してあげましょう --> devise_parameter_sanitizer.permit(:account_update, keys: [:name]) end endこれで編集時にデータが反映される様になりました
この記事が少しでも参考になれば嬉しいです
- 投稿日:2020-05-19T21:47:32+09:00
active_hashの使い方について!!
某プログラミングスクールでフリマアプリを作成する際にactive_hashを使ってみたので是非見て下さい!!
初学者の書いた記事ですが参考になれば嬉しいですそもそもactive_hashとは?
・DBにデータとして保存しておくほど重要ではない。
・基本的に変更されない。
・Active_Recordのように読み込み専用情報をまとめたハッシュを扱うことができるものです。1.gem 'active_hash'をインストール
アプリのGemfileに以下を記述
gem 'active_hash'ターミナルでbundle installを実行
$ bundle install2.Active_Hash::Baseを継承しているモデルを作成する
ActiveHash::Baseを継承したモデルを自作する。
今回は良くactive_hashが利用される事の多いprefecture(都道府県)モデルを作成していきます。
app/models/prefecture.rbという感じで自作します。
prefecture.rbclass Prefecture < ActiveHash::Base self.data = [ {id: 1, name: '北海道'}, {id: 2, name: '青森県'}, {id: 3, name: '岩手県'}, {id: 4, name: '宮城県'}, {id: 5, name: '秋田県'}, {id: 6, name: '山形県'}, {id: 7, name: '福島県'}, {id: 8, name: '茨城県'}, {id: 9, name: '栃木県'}, {id: 10, name: '群馬県'}, {id: 11, name: '埼玉県'}, {id: 12, name: '千葉県'}, {id: 13, name: '東京都'}, {id: 14, name: '神奈川県'}, {id: 15, name: '新潟県'}, {id: 16, name: '富山県'}, {id: 17, name: '石川県'}, {id: 18, name: '福井県'}, {id: 19, name: '山梨県'}, {id: 20, name: '長野県'}, {id: 21, name: '岐阜県'}, {id: 22, name: '静岡県'}, {id: 23, name: '愛知県'}, {id: 24, name: '三重県'}, {id: 25, name: '滋賀県'}, {id: 26, name: '京都府'}, {id: 27, name: '大阪府'}, {id: 28, name: '兵庫県'}, {id: 29, name: '奈良県'}, {id: 30, name: '和歌山県'}, {id: 31, name: '鳥取県'}, {id: 32, name: '島根県'}, {id: 33, name: '岡山県'}, {id: 34, name: '広島県'}, {id: 35, name: '山口県'}, {id: 36, name: '徳島県'}, {id: 37, name: '香川県'}, {id: 38, name: '愛媛県'}, {id: 39, name: '高知県'}, {id: 40, name: '福岡県'}, {id: 41, name: '佐賀県'}, {id: 42, name: '長崎県'}, {id: 43, name: '熊本県'}, {id: 44, name: '大分県'}, {id: 45, name: '宮崎県'}, {id: 46, name: '鹿児島県'}, {id: 47, name: '沖縄県'} ] end3.アソシエーションを組みます
今回はフリマアプリを作成しているので、商品の配送先を登録するときに都道府県をactive_hashを使って表示します。
product.rbにアソシエーションを組んでいきます。product.rbclass Product < ApplicationRecord extend ActiveHash::Associations::ActiveRecordExtensions belongs_to_active_hash :prefecture end4.表示します
商品を登録するフォームなどでcollection_selectを使う際は以下のように表示できます。
= f.collection_select :prefecture_id, Prefecture.all, :id, :name, {prompt:"選択してください"}, {class:""}5.登録した情報を表示したいとき
= @product.prefecture.nameこの様な感じでactive_hashを使う事ができます!!
最後まで見て頂きありがとうございます
少しでも参考になって頂ければ嬉しいです
- 投稿日:2020-05-19T21:20:35+09:00
Ruby と Python と numpy で解く AtCoder ABC054 B 行列演算
はじめに
AtCoder Problems の Recommendation を利用して、過去の問題を解いています。
AtCoder さん、AtCoder Problems さん、ありがとうございます。今回のお題
AtCoder Beginner Contest B - Template Matching
Difficulty: 828今回のテーマ、行列演算
2次元配列ですが、行列のライブラリを使用すると演算が簡単になることがあります。
Ruby
ruby.rbrequire 'matrix' class Matrix # v2.3 では代入不可 def []=(i, j, x) @rows[i][j]=x end end n, m = gets.split.map(&:to_i) rows = Array.new(n + m){gets.chomp.chars.map{|c| (c == '#') ? 1 : 0}} a = Matrix.rows(rows.shift(n)) b = Matrix.rows(rows) (n - m + 1).times do |i| (n - m + 1).times do |j| if a.minor(i, m, j, m) == b puts "Yes" exit end end end puts "No"matrix.rbrequire 'matrix' class Matrix # v2.3 では代入不可 def []=(i, j, x) @rows[i][j]=x end end
require 'matrix'
で行列のライブラリを呼び出します。
ローカル環境のv2.7.1
では行列の要素に代入できるのですが、AtCoder環境のv2.3.3
では代入できないのでメソッドを追加しています。
標準ライブラリに対してもこういうことができるのがRubyの面白い所でもあります。minor.rbif a.minor(i, m, j, m) == b
minor
で部分行列を取得し行列の比較を行っています。error.rb(n - m).times do |i| (n - m).times do |j| (n - m + 1).times do |i| (n - m + 1).times do |j|
1 x 1
の行列の時、行列の比較がうまくいかないので、それに対応した処理が入っています。(n - m)
は間違いで(n - m + 1)
が正解でした。追記
2次元配列版については、コメント欄を参照願います。Python
import numpy n, m = map(int, input().split()) a = numpy.zeros([n, n], dtype=int) b = numpy.zeros([m, m], dtype=int) for i in range(n): s = input() for j in range(n): if s[j] == '#': a[i, j] = 1 for i in range(m): s = input() for j in range(m): if s[j] == '#': b[i, j] = 1 for i in range(n - m + 1): for j in range(n - m + 1): if numpy.all(a[i: i + m, j: j + m] == b): print("Yes") exit() print("No")all.pyif numpy.all(a[i: i + m, j: j + m] == b):numpyの行列の比較は、例えば
[[True, True], [True, True]]
を返しますので、all関数を用いて全てTrue
かどうかを調べています。
Ruby (Matrix) Ruby (Array) Python (numpy) コード長 (Byte) 420 288 534 実行時間 (ms) 22 10 166 メモリ (KB) 3196 1788 12512 まとめ
- ABC 054 B を解いた
- Ruby に詳しくなった
- Python に詳しくなった
- numpy に詳しくなった
- 投稿日:2020-05-19T20:04:36+09:00
0 から始める Jekyll 超入門 #1 - 環境構築編
この記事は 0 から始める Jekyll 超入門 の 1番目の記事です。
- #1 環境構築編 <- 今回
- #2 独自テーマ作成編
はじめに
このシリーズでやること
- とりあえず Jekyll でサイトを作ってみる
- 自分でテンプレートを作ってみる
- 完成したサイトを netlify にデプロイして公開してみる
対象
- 独自のデザインで 0から Jekyll でサイトを作りたい人
前提知識
- HTML, CSS はなんとなくわかる
- JavaScript も存在くらいは知ってる
- markdown の書き方がわかる
- 静的サイトジェネレータが何をするかわかっている
- git を使える
- CUIでの操作もなんとなくできる
なお Ruby をインストールする必要がありますが、本シリーズはプラグインの作成などまで含めるとは考えていないので、
とりあえず Ruby がかける/わかる 必要はありません。Jekyll を動かすために必要な環境(必須)
環境構築についてはそれほど難しくも無いと思うので、ここでは説明はしません。
- Ruby v2.5.0 以上 :
ruby -v
で確認できます。- RubyGems :
gem -v
で確認できます。- GCC と make :
gcc -v
/g++ -v
とmake -v
で確認できます。Jekyll の公式 Docs より。
https://jekyllrb.com/docs/installation/#requirementsプロジェクトを作成してみる
まずはプロジェクトを作成するところから始まります。
適当な場所にプロジェクト用のフォルダを作成してみてください。
以下、プロジェクト用のフォルダをプロジェクトルート
とか作業ルートディレクトリで
とか適当な言葉で読んでいますが、全て読み替えてください。必要なライブラリのインストール
bundler というツールを使います。これによってプロジェクトごとの gem の管理が簡単になります。
以下を作業用ルートディレクトリで実行します。$ gem install bundler $ bundle initGemfile というファイルが生成されたら成功です。
次に、Gemfile を以下のように編集します。Gemfile# frozen_string_literal: true source "https://rubygems.org" git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } gem "jekyll"できたら以下を実行します。
$ bundle config set path 'vendor/bundle' $ bundle install
vendor/bundle
に色々とファイルが増えていくと思うので、じっと見守ります。(結構時間がかかります)
完了したら、次を実行します。$ bundle exec jekyll -v次のように返ってくれば成功です。
jekyll x.x.xJekyll プロジェクトの作成
Jekyll プロジェクトの作成をします。次のコマンドを実行します。
$ bundle exec jekyll new . --force $ bundle install少々省略していますがだいたいこんな感じの構成になると思います。
./ ├── 404.html ├── Gemfile ├── Gemfile.lock ├── _config.yml ├── _posts │ └── 2020-05-19-welcome-to-jekyll.markdown ├── about.markdown └── index.markdownこれでプロジェクトの作成は完了です。試しに動かしてみましょう。
次のコマンドを実行します。$ bundle exec jekyll s ...中略 ... Auto-regeneration: enabled for '<path-to-project-folder>' Server address: http://127.0.0.1:4000/ Server running... press ctrl-c to stop.このような形になれば成功しています。
試しに http://localhost:4000/ にアクセスしてみましょう。
デフォルトだと minima というテーマが適用されているので、すでにしっかりとしたページが生成されているはずです。ちなみに jekyll は静的サイトジェネレータですので、実行することによって、静的なサイトのソースコードが吐き出されます。
/_site
をみると、吐き出されたサイトのソースコードをみることができます。Jekyll Admin を追加してみる
Jekyll では Jekyll Admin というプラグイン(ツール)を使用することによって、 CMS のような管理画面を使って記事を管理したりすることができます。
なくても動きますが、比較的わかりやすく扱えるので導入してみましょう。gemfile を編集します。
Gemfilesource "https://rubygems.org" gem "jekyll", "~> 4.0.1" # .. 略 .. group :jekyll_plugins do gem "jekyll-feed", "~> 0.12" gem "jekyll-admin" # <- 追加 end # .. 略 .. gem "wdm", "~> 0.1.1", :install_if => Gem.win_platform?Gemfile を編集した場合は、以下のコマンドを実行することによってインストールすることができます。
$ bundle install完了した後再び実行してみます。
$ bundle exec jekyll shttp://localhost:4000/admin にアクセスしてみましょう。
このような画面になっている場合成功です。
※なお、この画面にアクセスできるのはローカル環境でjekyll s
をしてサーバーを立ち上げている時のみなのでご安心ください。横のタブから posts という画面をみてみると、記事の確認ができると思います。
記事を追加してみる
お試し的に、記事を追加してみましょう。
Jekyll では/_posts
ディレクトリ配下に md ファイルを追加することで、記事を追加することができますが、その他にも Jekyll Admin からも記事を追加できます。Jekyll Admin も最終的には自動で
/_ppsts
にファイルを作成するので実際やっていることは変わりませんが、設定やファイルの命名などを自動でやってくれたりするので、初めは Jekyll Admin を利用するのが良いかもしれません。今回は Jekyll Admin 経由で追加してみます。
Jekyll Admin の横のタブから posts ページを開き、 New Posts を押すことで新しいページを追加することができます。タイトルにタイトルを入力して、 Body に記事の内容を書きます。
Jekyll は基本的に markdown記法で書きます。
markdown についてはたくさん記事が上がっているので、ここでは説明を省きます。
こんな感じです。完成したら最後に、"New metadata field" をクリックして、 Key に layout と打ち込み、
"post" を選択します。これは自動でインストールされているテーマ(minima)の post レイアウトを使用する、という意味になります。
詳細は後ほど説明しますので、ここではおまじない(ど定番のごまかしの言葉)という軽い感じでOKです。ここまで完了したら、 Create をクリックします。
View というボタンが出てくると思うので、それもクリックすると、無事記事が追加されていることがわかると思います。とりあえず環境構築とプロジェクトの作成ができたので、今回はこの辺にしようかと思います。
現時点では、まだ minima という標準で用意されるテーマを使用していますが、
自分の好きなようなデザインにしたい!という方もたくさんおられると思います。GitHub などでたくさんテーマが公開されてたりするので、お好みのものを探してみるのも一手です。
ですが、やはり自分が作ってこそ!というところもあると思います。次回では、自分で記事を作る方法を解説しようと思います。
(頑張って書くぞ!!!それではまた今度!
- 投稿日:2020-05-19T18:50:56+09:00
Rails AWSデプロイ エラー遭遇まとめ
参考文献
- EC2サーバにRuby環境構築
- (デプロイ編①)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで
- AWS構築 格闘日記-2 忘備録
- AWSのEC2で行うAmazon Linux2(MySQL5.7)環境構築
- gem install rmagickでchecking for Magick-config... noがでる解決方法
- Amazon LinuxでRMagick 3.0.0 がインストールできない
- EC2にyumでNginxをインストールしようとしたらできなかった話
- AWS+Nginx+Unicornを利用してRailsアプリをデプロイしてみた。〜その1〜
Rubyインストール編
rbenv インストールエラー
$ rbenv install -v 2.6.5 configure: error: in `/tmp/ruby-build.202005191817.10626/ruby-2.6.5': configure: error: no acceptable C compiler found in $PATH解決コマンド
$ sudo yum install gcc openssl-devel $ sudo yum install -y gcc-6 bzip2 openssl-devel libyaml-devel libffi-devel readline-devel zlib-devel gdbm-devel ncurses-devel $ sudo yum erase ruby.noarch $ sudo yum install gccMySQL編
root初期パスワード在り処
$ cat /var/log/mysqld.log | grep password A temporary password is generated for root@localhost: ************初期パスワードログイン
$ mysql_secure_installation Enter password for user root: ************ New password: ************ Re-enter new password: ***********RMgick編
RMagickインストールエラー
$ bundle install --path vendor/bundle An error occurred while installing rmagick (3.0.0), and Bundler cannot continue. Make sure that `gem install rmagick -v '3.0.0' --source 'https://rubygems.org/'`解決コマンド
$ sudo yum -y install ImageMagick $ sudo yum -y install ImageMagick-develNginx編
Nginxインストールエラー
$ sudo yum install nginx 読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd パッケージ nginx は利用できません。 エラー: 何もしません解決コマンド
$ sudo amazon-linux-extras install nginx1.12 or $ sudo yum install http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm -y $ sudo yum install nginx -ynginx.conf設定後のpostメソッド対策
$ cd /var/lib $ sudo chmod -R 775 nginx
- 投稿日:2020-05-19T18:13:54+09:00
現在作業しているCurrentBranchにMasterBranchの情報を反映させたい時
背景
プログラミングスクールにてフリマアプリをチーム開発している時でした。
現在作業しているブランチにマスターブランチの情報を持ってきたい・・・・
こんな時の解決法を今回紹介します。
以下の4つのコマンドをターミナルで入力するだけで大丈夫です!!
※注意点
コマンドを実行する前の注意点として、編集途中のファイル等がある場合は、一度コミット&プッシュして何もない状態にしておきましょう。
<!-- 開発中ブランチからmasterブランチへ移動 --> $ git checkout master <!-- リモートのmasterを反映 --> $ git pull origin master <!-- masterブランチから開発中のブランチへ移動 --> $ git checkout 開発中のブランチ名 <!-- maserの内容を開発中ブランチに取り込む --> $ git merge origin masterこれで作業ブランチにマスターブランチの情報が反映されていると思います!!
最後まで記事を読んで頂きましてありがとうございます!!
参考になれば幸いです
- 投稿日:2020-05-19T17:59:24+09:00
atomのerbでrailsのコードが上手く反応してくれない
ruby on railsを勉強している初心者です。progateのruby on rails のすべて終了後、自分でコードを書いているのですが、index.html.erbに<% >を追加したところ、以下のhtmlコードはすべて反応しなくなりました。このような時はどのような対応をすればよいでしょうか。atomでコードを書いています。
- 投稿日:2020-05-19T17:50:45+09:00
AtCoderでRuby学習7【Contest168 Triple Dots】
はじめに
Ruby学習の一環として「競技プログラミング(競プロ)」に挑戦します。
そのための学習の中で学んだことをアウトプットしていきます。
今回は「AtCoder Beginners Contest168」の二問目(Triple Dots)より。
https://atcoder.jp/contests/abc168/tasks/abc168_b今回の自分の解答と、解答に使ったメソッド・記法を紹介していきます。
問題
英小文字からなる文字列 S があります。
S の長さが K 以下であれば、Sをそのまま出力。
S の長さが K を上回るのであれば、先頭から K 文字だけを切り出し、末尾に"..."を加えて出力すること。制約
・K は1以上100以下の整数
・S は英小文字からなる文字列
・S の長さは1以上100以下入力は以下の形で与えられる。
K S 入力例 7 nikoandsolstice出力例 # 上記例の場合 => nikoand...解答
まずは僕が最初に書いたコードです。
k = gets.to_i s = gets.chomp print s.length > k ? "#{s[0...k]}..." : sAtcoderへの挑戦を初めて、初期の頃に学んだ三項演算子を使っての解答です。
AtCoder Beginners SelectionでRuby学習【Product】様々な解法から学ぶ
文字列がの長さをlengthメソッドで出した上で K と比較し、
K より大きかった場合式展開を使って"..."を加えて出力、K 未満だった場合はそのまま出力という流れです。では、今回使ったメソッド、記法について以下にまとめます。
lengthメソッド(Stringクラス)
文字列の長さを返します。
#例 print "test".length => 4ちなみに、Arrayクラスのlengthメソッドは要素の数を返します。
文字列の一部を取得する方法①[first...end]
文字列の中から、開始位置(first)から終了位置(end)で挟まれた範囲を文字列として返します。
位置の指定は、1文字目の前を「0」として、1文字目と2文字目の間が「1」という形で指定出来ます。a = "test" #位置指定方法(イメージ) 0 t 1 e 2 s 3 t 4 #例 print a[0...3] => tes #上記の位置指定方法での、0から3の間を文字列として返す文字列の一部を取得する方法②[first, length]
ちなみに、[1, 3]という形で指定すると、「1」の位置から3文字を返します。
a = "test" #例 print a[1, 3] => est終了位置を位置指定ではなく、開始位置からの文字数という形で指定したい場合に使います。
最後に
以上、「AtCoder Beginners Contest168」の二問目(Triple Dots)から学んだメソッドをご紹介しました。
もし間違いなどございましたら、ご指摘いただけると嬉しいです。
- 投稿日:2020-05-19T17:46:49+09:00
Dockerの開発環境で通常の開発言語のコマンドで実行する方法
Dockerの開発環境ではDockerの開発環境特有のコマンドでの操作が必要になりますが、スクリプト言語のコマンドをローカル環境で実行するときと同じコマンドで開発ができる方法を紹介します。
前提
Docker 19.03.8
Ruby 2.5
Rails 5.2Dockerとローカルの開発環境で実行するときの違い
例えば以下のRuby on Railsの開発で用いられるコマンド
$ rails db:migrateこのコマンドをDockerで実行する場合
$ docker-compose run web rails db:migrateこのようなコマンドになります。
それ以外にも操作方法がありますが、Ruby on Railsで開発するならRubyやRailsの通常のコマンドの方が楽ですよね。その場合は以下の手順でコマンドを実行します。Rubyの通常のコマンドで開発を行うための準備
Dockerを立ち上げます。
$ docker-compose startコンテナ名を調べます。
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a9b19e00552e recipegram_web "entrypoint.sh bash …" 44 hours ago Up 11 seconds 0.0.0.0:3000->3000/tcp recipegram_web_1 975875c12c76 postgres "docker-entrypoint.s…" 46 hours ago Up 12 seconds 5432/tcp recipegram_db_1コンテナ名を入れて下記のコマンドを実行します。
$ docker exec -it a9b19e00552e bashそうするとこのように切り替わるのでこの状態で今回であればRubyやRailsの実行コマンドで開発が行えます^_^
root@a9b19e00552e:/myapp#
- 投稿日:2020-05-19T17:25:22+09:00
大学生Railsエンジニアが、1人でWebとアプリをリリースするまでの3ヶ月間の話
Qiita初投稿なのでお手柔らかに。
自分は大学生ながら都内のスタートアップでエンジニアをしています。
普段はRailsでのWebサービス開発がメインで、SwiftもKotlinも触ったことすらありませんでした。
経験ゼロのReact NativeとExpoでリリースまでに得た知見を残していきます。
開発したサービス
SportsLab | スポーツをより深く楽しめる新しいメディアコメントと共にスポーツのニュースを読めるサービスです。
Webとアプリの両方を1人で開発・運用しています。スタートアップあるあるですね笑。
使用技術
ざっくり使用している技術を紹介します。
Web: Rails 5.0, jQuery
アプリ: React Native, Expo, (TypeScript)
インフラ: ElasticBeanstalk(AWS)
認証: Firebase Auth
CI: Circle CI
スタートアップではよくある感じの技術構成だと思います。
Railsのエコシステムや周辺ライブラリの豊富さには助けられました。
アプリについては僕がSwiftやKotlinをかけないため泣く泣くReact Nativeを採用しました。
開発スケジュールを振り返る
開発の時間軸としては
12/24
記念すべきfirst commit
1/1
年明けにEC2にデプロイ
1/2
ドメインを取得してWeb版をローンチ
1/4
アプリを開発開始
2/1
Appleに初めて申請
2/13
朝起きたらアプリが公開されてました!
2/20
安定版がストアで公開される一人で開発して良かった事
今までのJSの経験を生かす事が出来た
React Native & Expoを採用した事でSwift, Kotlinを勉強する事なく純粋にJavaScript(TypeScript)を書くだけでモバイルアプリを開発できた、というのが一番ですね。
OTAアップデートで簡単に更新できる
また、ExpoにはOTAアップデート機能があるのでそちらを使えばストアに申請する事なくユーザのアプリを強制的にアップデートできるのも魅力の1つです。
デザインについても Native Base や React Native Elements といったUIライブラリが揃っているのでCSSをほとんど書く事なく開発を進められたのも大きかったです。
一人で開発して辛かった事
気軽にストア申請できない
ユーザによって使うアプリのバージョンがまちまちになってしまうので、API側でルーティングの変更などの仕様を変えられないのが辛いです。
TypeScript難しい?
React Nativeは完全に独学で、今も付け焼き刃の状態でコードを書いているのでアプリの挙動が不安定なのがネックでした。
少しでもバグを減らすためにTypeScriptを導入しましたが、動的型付けであるRubyしか書いてこなかったので、そもそも型ってなんですか?というレベルで、TypeScriptの恩恵を十分に受けられてないです。
これから勉強していきます!
ファイルの肥大化
useEffectで通信処理をViewにベタガキしてるのでファイルが巨大化してカオスofカオス。
Reduxや, Redux-sageなどのミドルウェアの学習と導入が待たれる。。。(そう言えば、つい最近FaceBookが新しい状態管理ライブラリを出してきましたね!)
申請が通らない!!!
最初App Storeの申請で数週間悩まされました。理由はこいつでした。
4.2 minimum functionality We found that the usefulness of your app is limited by the minimal features it includes.どうも調べたところ
お前の作ったアプリは⚪️ミだからアウト!
っていう意味らしいです。Push通知実装したり、記事の検索機能つけたりいろいろしたのですがダメでした。
ではどうやって通したかというと・・・
ウォークスルーを実装しました!!!
それだけです。
正直なんで通ったのか分からないです。
どうやら
アプリでないと得られないUX
を訴求したのが良かったっぽいです。同じ理由でリジェクトされてる人が一人でも多く救われますように。
ExpoをアップグレードしたらFacebookでログインできなくなった
ふと朝起きると同僚からSlackで同僚からメンションが来ていました。
Facebookでログインしようとするとアプリがクラッシュするんだけど
報告を受けた瞬間、顔面蒼白になりました。
急いで調査を開始するも、全く原因を特定できませんでした。
焦りを加速させたのはSentry経由でSlackにエラー通知も流れてこないという事でした。
つまり具体的にどこのコードでクラッシュしてるのか検討がつかない。
公式ドキュメント通りに実装してるし、どこが悪いのか悩む日々。
分からなさすぎてExpoにIssueまで立てちゃう始末。
Problem login with Facebook and Firebase
そのあともう一度Expo37のchangelogを調べていくと・・・ありました!!!
https://github.com/expo/expo/pull/7931/files
読んでいくと、途中にこんな記述が。
- In the Expo Client, all of your Facebook API calls will be made with Expo's Facebook App ID. This means you will not see any related ad info in your Facebook developer page while running your project in the Expo Client. - To use your app's own Facebook App ID (and thus see any related ad info in your Facebook developer page), you'll need to [build a standalone app](../../distribution/building-standalone-apps/).どうやら開発環境ではFacebookログインはできなくなったようです。
なのでビルドして動作確認する必要があるようでした。
ちなみに僕はこれに気付かず
Possible Unhandled Promise Rejection (id: 0): [Error: Unsuccessful debug_token response from Facebook: {"error":{"message":"(#100) The App_id in the input_token did not match the Viewing App","type":"OAuthException","code":100,"fbtrace_id":"********"}}]というエラーを3日間眺める羽目になりました。。。
1人でRailsでAPIを作った感想
JSONの整形にはActive Model Serializerが神
デフォルトでインストールされてるjbuilderは評判悪そうなのでActive Model Serializerを採用しました。
スター数も多いし大丈夫そうって思ってた矢先、更新が止まるという。。。
しばらくはこれで行く予定です。
Netflixが出してるfast_jsonapiっていうのが来てるらしいのですが学習コストが高そうなので断念しました。
Active Moel SerializerはActive Recordベースでかけるため直感的ですがSerializer側に値を渡す時のやり方が分からなくて最初苦労しました。
検索してもヒットするのが古いバージョンの記事ばかりで諦めかけていた、そのとき!
ActiveModelSerializers(0.10系)のインスタンス生成時に引数を渡してSerializerクラス内で使う方法
こちらの記事を発見しました。これに全て書いてあります。神!!!
重い腰を上げてFat Controllerを解決
あと初心者Railsエンジニアあるあるですね。
これどうしようかつい最近まで悩んでいたのですが
こちらを参考にさせて頂きました。
POROでサービスクラス(上記の記事ではWorkflows)を作ってそこに切り出そうというアプローチです。
あとControllerを分けてCRUDしかメソッドが作成されないようにする。
試してみましたがいい感じです。自分の書き方が合ってるか自信ありませんが。。。
突然のDockerの導入
実はWeb版のCSSは弊社のCEOが自ら書いています。
で、そのCEOのPCで環境構築しようとしたらなぜか環境構築で詰まりまして。。。
試行錯誤した結果、初めてDockerなるものを導入しました。
と言っても、開発環境でDockerfile書いただけです。
本番環境でのECSやFargateを使ったDockerの運用はリリース後のお楽しみという事で・・・。
Docker for Mac予想以上に重かった!
PCは高いやつを買おうと心に決めました。
こんな感じです!
最後に
今も一人でアプリ、バックエンド、インフラまで面倒見てます!
一緒にコードかきたい方は僕のTwitterアカウントまでDMどうぞ!!!
https://twitter.com/Katsukiniwa
- 投稿日:2020-05-19T16:00:02+09:00
AtCoderでRuby学習6【Contest168 Therefore】
はじめに
Ruby学習の一環として「競技プログラミング(競プロ)」に挑戦します。
そのための学習の中で学んだことをアウトプットしていきます。
今回は「AtCoder Beginners Contest168」の一問目(Therefore)より。
https://atcoder.jp/contests/abc168/tasks/abc168_a自分が使った解法と、公式から公開された解説をもとにまとめていきます。
問題
日本語で鉛筆を数える時には数の後ろに助数詞として「本」がつきます。
この助数詞はどんな数につくかで読み方が異なります。
999以下の整数について、「N本」と言う時の「本」の読み方は、・Nの1の位が「2,4,5,7,9」の時は'hon'
・Nの1の位が「0,1,6,8」の時は'pon'
・Nの1の位が「3」の時は'bon'Nが与えられるので、対応する「本」の読み方を出力しなさい。
制約
Nは999以下の正の整数入力は以下の形で与えられる。
N # 例 16上記の例だと最大2回割ることができるので
出力例 # 上記例の場合 => pon解答①
まずは僕が最初に書いたコードです。
a = gets.to_i.modulo(10) if [2,4,5,7,9].include?(a) print "hon" elsif [0,1,6,8].include?(a) print "pon" else print "bon" endmoduloメソッドを使って、入力から一の位のみを受け取り、
if文とinclude?メソッドで判定を行っていきます。
include?メソッドについては、以下の記事について一度書いたので、
AtCoder Beginners SelectionでRuby学習【Some Sums】使えるメソッドを増やす
ここでは、moduloメソッドについて触れておきます。moduloメソッド
指定した数で割った余りを返します。
解答では、整数を10で割ることで一の位を余りとして取り出しています。#例 13.modulo(4) => 1 42.modulo(10) => 2解答② case文
コンテスト後に配布された解説では、
case文による、より直感的に記述できる方法が紹介されています。以下ではcase文で解答した後に、case文の紹介をしていきます。
n = gets.to_i.modulo(10) case n when 2,4,5,7,9 print 'hon' when 0,1,6,8 print 'pon' else print 'bon' end最初の解答では、条件を配列に入れてinclude?メソッドで判定をしていましたが、
case文を使うことで、「一の位がもし2,4,5,7,9だったら…」と考えたままのコードが書けています。
確かにこっちの方が良さそうです。case文
一つの値に対して複数の候補の中から一致するものを探す時に便利です。
whenで指定するものに一致するかどうかを「===」演算子によって判定します。case object when value1 # object === value1の時に実行する文 when value2 # object === value2の時に実行する文 else # 全てに合致しなかった場合に実行する文 endここで出てきた「===」演算子は、
上記で言うobjectが文字列や数値の場合は、「==」として、
正規表現の場合は「=~」として、
範囲の場合はinclude?のようにその中にvalueを含むかと、言う形で判定してくれるようです。
柔軟で、使い勝手が良さそうです。最後に
以上、「AtCoder Beginners Contest168」の一問目(Therefore)から学んだメソッドをご紹介しました。
もし間違いなどございましたら、ご指摘いただけると嬉しいです。
- 投稿日:2020-05-19T15:15:48+09:00
【Rails】gem devise インストール時の流れ
はじめに
Qiita初投稿です。
拙い文章で恐縮ですが、ご一読いただけますと幸いです。
よろしくお願いします。ユーザー管理機能のためのgem deviseをインストール
1. Gemfileの最終行に以下のように追記
Gemfile# 省略 gem 'devise' # 最終行に追記してください2. ターミナルで
bundle install
を実行ターミナル$ bundle install3. Gemfile.lockで
devise
がインストールされたか確認Gemfile.lock# 省略 devisedeviseの適用
インストールが完了したら、devise専用のコマンドを利用して設定ファイルを作成
4. ターミナルで
rails g devise:install
を実行ターミナル# deviseの設定ファイルを作成 $ rails g devise:install新規作成されるファイル
- config/initializers/devise.rb
- config/locales/devise.en.yml
5. ターミナルで
rails g devise user
を実行ターミナル# deviseコマンドでモデルを作成 $ rails g devise user新規作成されるファイル
- app/models/user.rb
- db/migrate/20XXXXXXXXXXXX_devise_create_users.rb
- test/fixtures/users.yml
- test/models/user_test.rb
また、config/routes.rbに
devise_for :users
の記述が自動的に追記されます。config/routes.rbRails.application.routes.draw do devise_for :users # 省略6. ターミナルで
rails db:migrate
を実行ターミナル# 作成されたマイグレーションファイルを実行 $ rails db:migrate7. ターミナルで
rails g devise:views
を実行ターミナル# devise用のビューを作成 $ rails g devise:views新規作成されるファイル
- app/views/devise/shared
- app/views/devise/shared/_error_messages.html.erb
- app/views/devise/shared/_links.html.erb
- app/views/devise/confirmations
- app/views/devise/confirmations/new.html.erb
- app/views/devise/passwords
- app/views/devise/passwords/edit.html.erb
- app/views/devise/passwords/new.html.erb
- app/views/devise/registrations
- app/views/devise/registrations/edit.html.erb
- app/views/devise/registrations/new.html.erb
- app/views/devise/sessions
- app/views/devise/sessions/new.html.erb
- app/views/devise/unlocks
- app/views/devise/unlocks/new.html.erb
- app/views/devise/mailer
- app/views/devise/mailer/confirmation_instructions.html.erb
- app/views/devise/mailer/email_changed.html.erb
- app/views/devise/mailer/password_change.html.erb
- app/views/devise/mailer/reset_password_instructions.html.erb
- app/views/devise/mailer/unlock_instructions.html.erb
以上、
gem devise
のインストール時の流れを説明させて頂きました。
少しでも多くの方の参考になれば幸いです。
- 投稿日:2020-05-19T12:51:06+09:00
Ruby public protected private
- 投稿日:2020-05-19T12:48:13+09:00
OSX Catalinaにアップデート後、sassできなくなった
似たような状況に見舞われた同様記事ありますが個人用にもメモ。
状況と解決方法
表題の通りなんですが、OSXをCatalinaにアップデート後、sassコマンドを打つと以下のようなエラーが出た。
bash: /usr/local/bin/sass: /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/bin/ruby: bad interpreter: No such file or directoryどうやらCatalinaにアップデートするとOSにビルトインされているRubyのバージョンが上がって古いのが削除されていることが原因のよう。
以下の記事を参考に
rbenv
をインストール後、別のバージョンのRubyを入れてそこにパスを通すと解決!!https://qiita.com/nishina555/items/63ebd4a508a09c481150
余談
実際はPhpstormのプラグインからの実行でエラーが出てて、慌ててPhpstormのサポートに連絡したらSCSSの実行はPhpstormとは関係ないですよー、と言われた。そらそうだ。(ビルトインな気がしたがそうではないみたい)
でそのメールにRuby Sassは非推奨なのでDart Sass使ってくださいねー、と親切なアドバイスも。
Dartに切り替えたほうが良いかなー。
- 投稿日:2020-05-19T11:26:37+09:00
RSpec3のフォーマッタの基本と自作入門
概要
RSpec
を実行したときに標準出力される内容は、使用するフォーマッタで決定します。本記事ではRSpec3
におけるフォーマッタの基本を抑えてから、カスタムフォーマットを実装して体験をしてみる。バージョン情報
version ruby 2.6.5 rspec 3.9.1 使用するテスト対象コード
本記事では以下のシンプルなクラスを対象にテストを実行します。
class Calculator def initialize(initial_value) @answer = initial_value end def add(number) @answer += number end def sub(number) @answer -= number end end使用するテストコード
前項の
Calculator
クラスのシンプルな単体テストを用意します。コメントを記載している通り、4つのテストケースのうち1つは意図的に落ちるものを含んでいます。クラスを使う側は引き算の結果が負数にならないものだと想定していたという設定です。
describe Calculator do subject { described_class.new(initial_value) } describe '#add 足し算' do context '初期値が0の場合' do let(:initial_value) { 0 } it '10を足すと10が戻る' do expect(subject.add(10)).to eq 10 end end context '初期値が5の場合' do let(:initial_value) { 5 } it '10を足すと15が戻る' do expect(subject.add(10)).to eq 15 end end end describe '#sub 引き算' do context '初期値が0の場合' do let(:initial_value) { 0 } # 落ちるテスト it '10を引くと0が戻る' do expect(subject.sub(10)).to eq 0 end end context '初期値が30の場合' do let(:initial_value) { 30 } it '10を引くと20が戻る' do expect(subject.sub(10)).to eq 20 end end end endビルトインフォーマッタについて
Rspec3
では最初から使えるいくつかのビルトインフォーマッタが用意されています。デフォルトでは後述のProgressフォーマッタが使用されますが、
--format
または単に-f
オプションを用いて、フォーマッタを指定することで使い分けることができます。Progress formatter
デフォルトのフォーマッタです。テストごとに成功の場合は
.
を、失敗の場合はF
をリアルタイムに表示していき、最後に失敗したテストのレポートを表示します。$ rspec -f p spec/calculator_spec.rb..F. Failures: 1) Calculator#sub 引き算 初期値が0の場合 10を引くと0が戻る Failure/Error: expect(subject.sub(10)).to eq 0 expected: 0 got: -10 (compared using ==) # ./spec/calculator_spec.rb:41:in `block (4 levels) in <top (required)>' Finished in 0.06725 seconds (files took 2.14 seconds to load) 4 examples, 1 failure Failed examples: rspec ./spec/calculator_spec.rb:40 # Calculator#sub 引き算 初期値が0の場合 10を引くと0が戻るDocumentation formatter
テストコードに基づくドキュメントを出力します。
RSpec
は振る舞い駆動でテストを記述できるので、このフォーマッタを意識してテストを書くことで、テスト結果をそのままドキュメントとして利用することができます。$ rspec -f d spec/calculator_spec.rbCalculator #add 足し算 初期値が0の場合 10を足すと10が戻る 初期値が5の場合 10を足すと15が戻る #sub 引き算 初期値が0の場合 10を引くと0が戻る (FAILED - 1) 初期値が30の場合 10を引くと20が戻る Failures: 1) Calculator#sub 引き算 初期値が0の場合 10を引くと0が戻る Failure/Error: expect(subject.sub(10)).to eq 0 expected: 0 got: -10 (compared using ==) # ./spec/calculator_spec.rb:42:in `block (4 levels) in <top (required)>' Finished in 0.12273 seconds (files took 2.53 seconds to load) 4 examples, 1 failure Failed examples: rspec ./spec/calculator_spec.rb:41 # Calculator#sub 引き算 初期値が0の場合 10を引くと0が戻るjson formatter
テスト結果を、元ソースコードの情報などのメタデータを含めたJSON形式で出力します。通常はこのまま利用するのでなく、他の解析ツールなどに受け渡してテストレポートの見える化を行ったりします。
$ rspec -f j spec/calculator_spec.rb{ "version": "3.9.1", "examples": [ { "id": "./spec/calculator_spec.rb[1:1:1:1]", "description": "10を足すと10が戻る", "full_description": "Calculator#add 足し算 初期値が0の場合 10を足すと10が戻る", "status": "passed", "file_path": "./spec/calculator_spec.rb", "line_number": 22, "run_time": 0.0069776, "pending_message": null }, { "id": "./spec/calculator_spec.rb[1:1:2:1]", "description": "10を足すと15が戻る", "full_description": "Calculator#add 足し算 初期値が5の場合 10を足すと15が戻る", "status": "passed", "file_path": "./spec/calculator_spec.rb", "line_number": 30, "run_time": 0.0001513, "pending_message": null }, { "id": "./spec/calculator_spec.rb[1:2:1:1]", "description": "10を引くと0が戻る", "full_description": "Calculator#sub 引き算 初期値が0の場合 10を引くと0が戻る", "status": "failed", "file_path": "./spec/calculator_spec.rb", "line_number": 41, "run_time": 0.0454084, "pending_message": null, "exception": { "class": "RSpec::Expectations::ExpectationNotMetError", "message": "\nexpected: 0\n got: -10\n\n(compared using ==)\n", "backtrace": [ "/usr/local/bundle/gems/rspec-support-3.9.2/lib/rspec/support.rb:97:in `block in <module:Support>'", "/usr/local/bundle/gems/rspec-support-3.9.2/lib/rspec/support.rb:106:in `notify_failure'", "(以下略)" ] } }, { "id": "./spec/calculator_spec.rb[1:2:2:1]", "description": "10を引くと20が戻る", "full_description": "Calculator#sub 引き算 初期値が30の場合 10を引くと20が戻る", "status": "passed", "file_path": "./spec/calculator_spec.rb", "line_number": 49, "run_time": 0.0002024, "pending_message": null } ], "summary": { "duration": 0.0632882, "example_count": 4, "failure_count": 1, "pending_count": 0, "errors_outside_of_examples_count": 0 }, "summary_line": "4 examples, 1 failure" }(※実際のJSONは整形されていません)
html formatter
$ rspec -f h spec/calculator_spec.rbテスト結果をHTMLで出力します。そのままだとタダのHTMLテキストなので、保存してブラウザで開くと以下のように結果を確認できます。
フォーマッタを自作する
これまで
-f
オプションを使って、フォーマッタの指定をしてきましたが、ここにその他のフォーマッタのクラス名を指定することで、任意のフォーマッタを利用することができます。自作フォーマッタを動かしてみる
まずは最低限のフォーマッタを作成してみます。
my_formatter.rbclass MyFormatter RSpec::Core::Formatters.register self, :example_passed, :example_failed def initialize(output) @output = output end def example_passed(notification) @output << "【#{notification.example.description}】\t成功!!\n" end def example_failed(notification) @output << "【#{notification.example.description}】\t失敗!!\n" end end以下のように、
-r
オプションでrequireするファイルを指定し、そこで読み込まれたクラスをフォーマッタに指定します。$ rspec -r ./my_formatter.rb -f MyFormatter spec/calculator_spec.rb良い感じに独自のフォーマットでテスト結果が出力されました!
【10を足すと10が戻る】 成功!! 【10を足すと15が戻る】 成功!! 【10を引くと0が戻る】 失敗!! 【10を引くと20が戻る】 成功!!カスタムフォーマットクラスについて
上記のカスタムクラスでは
RSpec::Core::Formatters.register self, :example_passed, :example_failedという見慣れないコードがはじめに出てきます。
これはRpsecが通知する情報のうち、どの分類についてこのフォーマッタで受け取るかを宣言しており、ここでは
example_passed
example_failed
の2種類を受け取っています。そして、受け取った通知ごとに、同様のメソッドを実装し、そこで通知内容を元に出力内容を決定しているわけですね。
def example_passed(notification) @output << "【#{notification.example.description}】\t成功!!\n" endちなみに全ての通知を受け取りたいからってこの行を省略すると以下のような警告が出ます。警告内容の通り、現在はちゃんと
register
メソッドを通さないとイケないようですね。Deprecation Warnings: The MyFormatter formatter uses the deprecated formatter interface not supported directly by RSpec 3. To continue to use this formatter you must install the `rspec-legacy_formatters` gem, which provides support for legacy formatters or upgrade the formatter to a compatible version. Formatter added at: /usr/local/bundle/gems/rspec-core-3.9.1/exe/rspec:4:in `<top (required)>' If you need more of the backtrace for any of these deprecations to identify where to make the necessary changes, you can configure `config.raise_errors_for_deprecations!`, and it will turn the deprecation warnings into errors, giving you the full backtrace. 1 deprecation warning total通知の種類
RSpec::Core::Formatters.register
で受け取れる通知は以下のようなものがあります(全てではありません)
名称 タイミング 引数 start テストスイート開始時 StartNotification stop テストスイート終了時 ExamplesNotification example_group_started テストグループ開始時 GroupNotification example_started テスト開始時 ExampleNotification example_passed テスト成功時 ExampleNotification example_failed テスト失敗時 FailedExampleNotification start
def start(notification) puts "読み込み時間: #{notification.load_time}" puts "項目数: #{notification.count}" end読み込み時間: 1.757944 項目数: 4stop
終了時に実施した全てのテスト内容を確認することができます。
def stop(notification) puts "#{notification.failed_examples.count}/#{notification.examples.count}個のテストに失敗しました" end1/4個のテストに失敗しましたexample_group_started
GroupNotification
は、 ExampleGroup つまりdescribe
やcontext
といったテストのグループのオブジェクトを取得できます。def example_group_started(notification) puts "[#{notification.group.metadata[:scoped_id]}] #{notification.group.description}" end[1] Calculator [1:1] #add 足し算 [1:1:1] 初期値が0の場合 [1:1:2] 初期値が5の場合 [1:2] #sub 引き算 [1:2:1] 初期値が0の場合 [1:2:2] 初期値が30の場合example_started
ExampleNotification
は、個々のテストを表すExampleを取得できます。def example_started(notification) puts "#{notification.example.description}:\t#{notification.example.location}" end10を足すと10が戻る: ./spec/calculator_spec.rb:22 10を足すと15が戻る: ./spec/calculator_spec.rb:30 10を引くと0が戻る: ./spec/calculator_spec.rb:41 10を引くと20が戻る: ./spec/calculator_spec.rb:49example_passed
example_started
と同じくExampleが取得できるが、こちらはテスト成功後のExample
なので、実行結果のExecutionResultを利用できます。def example_passed(notification) example = notification.example result = example.execution_result puts "[#{example.description}] run_time: #{result.run_time}" end[10を足すと10が戻る] run_time: 0.0019845 [10を足すと15が戻る] run_time: 0.0001931 [10を引くと20が戻る] run_time: 0.0001662example_failed
概ね
example_passed
と同じですが、FailedExampleNotification
では具体的な失敗理由を取得することができます。def example_failed(notification) puts "[#{notification.description}]" puts notification.exception end[Calculator#sub 引き算 初期値が0の場合 10を引くと0が戻る] expected: 0 got: -10 (compared using ==)ちなみにエラー通知の内容はReporter というまた別概念が関わってきますが本記事では割愛します。
ビルドインフォーマッタっぽいものを再現する
前項で紹介した仕組みを使って、ビルトインフォーマッタの一つあるドキュメンテーションっぽいフォーマッタを作ってみましょう。
(あくまで「っぽいもの」です)
class MyFormatter RSpec::Core::Formatters.register self, :start, :example_group_started, :example_passed, :example_failed, :stop def initialize(output) @output = output end def start(notification) @load_time = notification.load_time end def example_group_started(notification) group = notification.group description = group.description output_with_space(description, get_nest_num(group.metadata)) end def example_passed(notification) example = notification.example description = example.description output_with_space(description, get_nest_num(example.metadata)) end def example_failed(notification) example = notification.example description = "#{example.description} (FAILED)" output_with_space(description, get_nest_num(example.metadata)) end def stop(notification) failure_notifications = notification.failure_notifications @output.puts "\nFailures: \n\n" if failure_notifications.present? failure_notifications.each_with_index do |fn, i| @output.puts "#{i + 1}) #{fn.description}" @output.puts fn.exception @output.puts "# #{fn.formatted_backtrace.first}" end total_run_time = notification.examples.sum { |e| e.execution_result.run_time } @output.puts "\n" @output.puts "Finished in #{total_run_time} seconds (files took #{@load_time} seconds to load)" @output.puts "#{notification.examples.count} examples, #{notification.failed_examples.count} failure" end private def get_nest_num(metadata) metadata[:scoped_id].count(':') end def output_with_space(description, nest_num) @output.puts "#{' ' * nest_num}#{description}" end end実行結果
$ rspec -r ./my_formatter.rb -f MyFormatter spec/calculator_spec.rbCalculator #add 足し算 初期値が0の場合 10を足すと10が戻る 初期値が5の場合 10を足すと15が戻る #sub 引き算 初期値が0の場合 10を引くと0が戻る (FAILED) 初期値が30の場合 10を引くと20が戻る Failures: 1) Calculator#sub 引き算 初期値が0の場合 10を引くと0が戻る expected: 0 got: -10 (compared using ==) # ./spec/calculator_spec.rb:42:in `block (4 levels) in <top (required)>' Finished in 0.084687 seconds (files took 1.7904404 seconds to load) 4 examples, 1 failureやや冗長なコードにはなりましたが、結果はそれっぽいんじゃないでしょうか??
- 投稿日:2020-05-19T11:14:20+09:00
Ruby on rails を初心者向けに解説② ~リンクの作成~
はじめに
今回は前回の記事の続きになります。
頑張っていきましょう。
ルーティングの変更
ルーティングは自分の好きなように設定することができます。
例えば、
/pocomaru
と書いたときに、home#top
(homeコントローラーのtopアクション)が行われるようにしましょう。ルーティングを以下のように変更します。
routes.rbRails.application.routes.draw do get "pocomaru" => "home#top" endこの状態で、以下のようにURLを打ちます。
http://localhost:3000/pocomaruこのようにすると、
http://localhost:3000/pocomaru
というURLはhome#top
(homeコントローラーのtopアクション)という命令に置き換えられます。ルーティングは、localhost:3000以降のURLに対して行います。
実行すると、以下の画面になりました。
リンクの作成
それでは、リンクを作成していきましょう。
top.html.erbというファイルに、test.html.erbファイルへのリンクを張ります。
test.html.erbファイルの中身は次のようにします。
test.html.erb<h1>テスト</h1>このファイルへのリンクを作成していきましょう。
リンクをクリックすると別のファイルになぜ飛ぶか
しかし、リンクをクリックして、それがユーザーに送られるとはどういうことでしょうか。
一度、何が起きているのかを考えてみましょう。以下の図をみてください。
リンクをクリックして別のファイルに飛ぶということは、上の図の赤く囲った部分の話になります。
ユーザーがURLをサーバーに送り、そのURLに応じてコントローラーがviewファイルを探し出し、アクションに書いてある処理をした後、viewファイルをユーザーに送ります。
このように、ユーザーがサーバーにviewファイルを要求することを
getリクエストを送る
と呼びます。ユーザーがURLをサーバーに送る動作は様々です。リンクが貼られている文字をクリックしたり、IDを打ち込んだ後に
送信
などと書かれたボタンを押したりする、などがあります。そのようなURLが送られてきた後、サーバーはルーティングにより翻訳を行うのでしたね。
ルーティングにより、どのコントローラーのどのアクションを行うかを指定します。
また、これらのアクションは、viewファイルに対応しています。
例えば、ルーティングにより
homeコントローラーのtopアクション
が呼ばれると、app >> views 配下のhomeディレクトリのtop.html.erbファイルが呼ばれます。つまり、何故リンクをクリックすると別ファイルに飛ぶのかを考えると以下のように答えることができます。
リンクをクリックすると、URLがルーティングにより変換され、どのコントローラーのどのアクションを行うかが指定され、そのアクションに応じたviewsファイルがユーザーに送られてくるから
実際にリンクを作成
Ruby on railsのリンクの作成方法は大きく分けて以下の2つがあります。
- htmlのaタグのhrefで指定する
- Railsのlink_toメソッドを使う
せっかくなので、2つの方法で実装してみましょう。
top.html.erbファイルを以下のように書き換えました。
top.html.erb<h1>Hello World</h1> <a href="test">test by href</a> <%= link_to("test by link_to", "test") %>二行目のリンクの書き方は、典型的なhtmlのリンクの書き方ですね。
三行目の書き方に注目してください。
<%= %>
という形で囲むと、これはRubyのコードだよ!
と伝えることになります。link_toを使ったコードは、htmlのコードではなくRubyのコードなので、このように囲む必要があります。ちなみに、
<% %>
で囲っても、Railsのコードであると伝えることになります。<%%>で囲むのか、<%=%>で囲むのかについて解説と、link_toの使い方の解説を以下で行います。
<%= %>と<% %>の違い
実は.html.erbのerbとは
Embedded RuBy
の略称になります。つまり、Rubyを埋め込んだhtmlファイルであるという意味です。つまり、このhtml.erbファイルの内部にはRubyのスクリプトを埋め込むことができます。
<%= %>と<% %>の2つは、html.erbファイルにおいてrubyのコードを書くときに使うことになります。
しかし、htmlファイルにrubyスクリプトを埋め込むときに、別にブラウザに表示する必要がない処理を行う場合があります。
そのようなときに、この2つを使い分ける必要があります。ざっくりと以下のように覚えてください。
- ブラウザに表示させたいときは
<%= %>
を使う- ブラウザに表示させたくないときは
<% %>
を使うlink_toの使い方
link_toはRubyのコードであるので、
<% %>
か<%= %>
で囲む必要があります。今回はクリックしたらどこかに飛ぶリンクを作成したいので、当然ブラウザに表示する必要があります。
<%= %>
で囲みましょう。link_toは、第一引数に
ブラウザに表示する文字
を取り、第二引数にURL
を取ります。今回は、
test
というURLを取ることにしました。ここからは、ユーザーからリンクがクリックされた、つまりURLが送られてきたときに、test.html.erbファイルを送る方法について解説します。
まず、最初にルーティングを変更しましょう。
ルーティングを変更
以下のようにルーティングを変更してください。
routes.rbRails.application.routes.draw do get "pocomaru" => "home#top" get "test" => "home#test" end新しく、
test
とうURLが送られてきた場合にhome#top
というルーティングに変換するコードを追記しました。つまり、ユーザーからtestというURLがクリックされると、homeコントローラーのtopアクションが実行されるようになります。
次は、homeコントローラーにtopアクションを追記しましょう。
コントローラーにアクションを追記
homeコントローラにtestアクションを追記しましょう。
hoem_controller.rbclass HomeController < ApplicationController def top end def test end endこのようなコードが追記されることで、ユーザーから
home#test
というルーティングが呼ばれたときに、homeコントローラーのtestアクションを行い、view >> home >> test.html.erbファイルをユーザに送り返すことができるようになります。終わりに
今回はここまでになります。
ここまでお付き合い頂きありがとうございました。
- 投稿日:2020-05-19T10:54:29+09:00
Railsデータベース基礎
テーブル
表形式の収納場所でデータベースの中にいくつも作成することができる。
データベースが存在していても、このテーブルがなければデータを保存することはできません。レコードとカラム
テーブルは表形式になっていますが、その横一行のことをレコードと言います。また。縦一列のことをカラムと言います。
テーブルのレコードを特定するために、idというカラムが用意されています。DOA
DOAとはデータ中心アプローチのことで、プログラムよりも前にデータ設計を先に行う方法のことです。
サービス開発がより効率的になることが期待されます。データベース設計
手順としては
1.テーブルの抽出
途中でテーブルを追加すると関係性を見直さなければいけなくなる。
予約語は使わないように。2.テーブルの定義
各テーブルが持つカラムを決める。途中で追加するとコードを書き直したり、ビューを変更しなくてはいけない場合が出てくるからです。
予約語は使わないように。3.テーブル構造を整理
同じカラム名を同じテーブル内に作ってはいけません。
そのような場合は別でテーブルを作りましょう。
EX)同じテーブルに imageカラム、 image2カラムなど。この場合はimageテーブルを作る。4.ER図の作成
テーブル同士の関係をわかりやすく表した図。
IE表記法という書き方で書く。モデル
モデルの命名規則
モデルクラス名は先頭は大文字の単数形
モデルクラスのファイル名は、先頭小文字の単数形
テーブル名は先頭小文字の複数形
EX)Animal モデルクラス名
animal モデルクラスのファイル名
animals テーブル名これらモデルファイルとテーブルを作成するコマンドがあります。
それがrails g model
コマンドです。このコマンドの後に作成したいモデルクラスの名前を全て小文字で続けます。
EX)rails g model animalこのコマンドを叩くとテーブルが作成されると言いましたが、テーブルの設計図ができているだけでテーブル自体はまだできていません。テーブルの設計図のことをマイグレーションファイルと言います。
マイグレーションファイル
changeメソッドを使って作成するカラムを指定できます。
カラムの型
integer 数字 idなど
string 少なめの文字 ユーザー名、パスワード
text 多めの文字 投稿文
boolean 真か偽か 真偽フラグ
datetime 日付と時刻 作成日時、更新日時マイグレーションファイルの設定
2020XXXXXXXXXXXXXXXX_create_XXXX.rbclass CreateXxxxxx < ActiveRecord::Migration[5.2] def change create_table :xxxxs do |t| t.string :name t.text :text t.text :image t.timestamps null: false end end endマイグレーションファイルの実行
rake db:migrate
このコマンドを行うと、ファイルが更新されます。
スキーマファイルには最新のマイグレーションファイルのバージョンが記録される。
schema_migrations
はデータベースの変更履歴のようなもので、どのマイグレーションファイルまでが実行されているかが記録されています。マイグレーションファイルはschema_migrationsと齟齬が生じる恐れがあるので消してはいけません。
マイグレーションファイルは一度rake db:migrate
で実行してしまうと、中身を書き換えて再実行はできません。
rake db:rollback
でデータベースの状態を最新のmigrationファイルを実行する前に戻せます。Active Record
Active RecordはRubyのGemの一種です。このGemはRailsにデフォルトでインストールされており、このGemのおかげでモデルとテーブルをつなぎ合わせられています。そのことによりRailsからテーブルのレコードにアクセスできます。
Actice Recordを利用するにはApplicationRecordというクラスを継承する必要があります。
ApplicationRecordを継承することでallメソッド、newメソッド、saveメソッド、findメソッドなどが利用できるようになります。SQL
データベースに保存されているデータをデータベースに要求するときに使う言語です。
RailsではActive Recordのおかげで簡単にデータを要求することができます。
- 投稿日:2020-05-19T10:23:43+09:00
Ruby と Python と networkx で解く AtCoder ABC168 C 隣接リスト
はじめに
AtCoder Problems の Recommendation を利用して、過去の問題を解いています。
AtCoder さん、AtCoder Problems さん、ありがとうございます。今回のお題
AtCoder Beginner Contest D - .. (Double Dots)
Difficulty: 750今回のテーマ、隣接リスト
隣接リストから幅優先探索をするのですが、部屋1に近い部屋から道しるべを記録し、記録した部屋をスキップすることにより最短経路を取得します。
Ruby
ruby.rbn, m = gets.split.map(&:to_i) a = Array.new(n){[]} m.times do x, y = gets.split.map(&:to_i) a[x - 1] << y - 1 a[y - 1] << x - 1 end c = Array.new(n){0} que = [] que << 0 while que.size > 0 e = que.shift a[e].each do |i| next if c[i] > 0 c[i] = e + 1 que << i end end puts "Yes", c[1..-1]index.rba[x - 1] << y - 1 a[y - 1] << x - 1配列のインデックスが
0
から始まることに適応させています。Python
pypy.pyfrom collections import deque n, m = map(int, input().split()) a = [[] for _ in range(n)] for i in range(m): x, y = map(int, input().split()) a[x - 1].append(y - 1) a[y - 1].append(x - 1) c = [0] * n que = deque([]) que.append(0) while len(que) > 0: e = que.popleft() for i in a[e]: if c[i] > 0: continue c[i] = e + 1 que.append(i) print("Yes") for i in range(1, n): print(c[i])Python (networkx)
networkx.pyimport networkx n, m = map(int, input().split()) g = networkx.Graph() g.add_nodes_from(list(range(n))) for i in range(1, m + 1): a, b = map(int, input().split()) g.add_edge(a, b) #print(g.nodes()) #print(g.edges()) print("Yes") for i in range(2, n + 1): print(networkx.shortest_path(g, 1, i)[-2])shortest_path.pyprint(networkx.shortest_path(g, 1, i)[-2])
networkx.shortest_path
で最短経路が取得できます。幅優先探索なんていりません
幸い、この問題ではTLE
になりますが、networkx
凄いですね。
Ruby Python PyPy Python (networkx) コード長 (Byte) 335 459 459 321 実行時間 (ms) 335 696 451 TLE メモリ (KB) 32748 36920 94388 187248 まとめ
- ABC 168 D を解いた
- Ruby に詳しくなった
- Python に詳しくなった
- networkx に詳しくなった
参照したサイト
networkx Tutorial
Python3 キュー操作 (collections.deque)
PythonでABC168Dを解く
- 投稿日:2020-05-19T10:23:43+09:00
Ruby と Python と networkx で解く AtCoder ABC168 D 隣接リスト
はじめに
AtCoder Problems の Recommendation を利用して、過去の問題を解いています。
AtCoder さん、AtCoder Problems さん、ありがとうございます。今回のお題
AtCoder Beginner Contest D - .. (Double Dots)
Difficulty: 750今回のテーマ、隣接リスト
隣接リストから幅優先探索をするのですが、部屋1に近い部屋から道しるべを記録し、記録した部屋をスキップすることにより最短経路を取得します。
Ruby
ruby.rbn, m = gets.split.map(&:to_i) a = Array.new(n){[]} m.times do x, y = gets.split.map(&:to_i) a[x - 1] << y - 1 a[y - 1] << x - 1 end c = Array.new(n){0} que = [] que << 0 while que.size > 0 e = que.shift a[e].each do |i| next if c[i] > 0 c[i] = e + 1 que << i end end puts "Yes", c[1..-1]index.rba[x - 1] << y - 1 a[y - 1] << x - 1配列のインデックスが
0
から始まることに適応させています。Python
pypy.pyfrom collections import deque n, m = map(int, input().split()) a = [[] for _ in range(n)] for i in range(m): x, y = map(int, input().split()) a[x - 1].append(y - 1) a[y - 1].append(x - 1) c = [0] * n que = deque([]) que.append(0) while len(que) > 0: e = que.popleft() for i in a[e]: if c[i] > 0: continue c[i] = e + 1 que.append(i) print("Yes") for i in range(1, n): print(c[i])Python (networkx)
networkx.pyimport networkx n, m = map(int, input().split()) g = networkx.Graph() g.add_nodes_from(list(range(n))) for i in range(1, m + 1): a, b = map(int, input().split()) g.add_edge(a, b) #print(g.nodes()) #print(g.edges()) print("Yes") for i in range(2, n + 1): print(networkx.shortest_path(g, 1, i)[-2])shortest_path.pyprint(networkx.shortest_path(g, 1, i)[-2])
networkx.shortest_path
で最短経路が取得できます。幅優先探索なんていりません
幸い、この問題ではTLE
になりますが、networkx
凄いですね。
Ruby Python PyPy Python (networkx) コード長 (Byte) 335 459 459 321 実行時間 (ms) 335 696 451 TLE メモリ (KB) 32748 36920 94388 187248 まとめ
- ABC 168 D を解いた
- Ruby に詳しくなった
- Python に詳しくなった
- networkx に詳しくなった
参照したサイト
networkx Tutorial
Python3 キュー操作 (collections.deque)
PythonでABC168Dを解く
- 投稿日:2020-05-19T10:08:14+09:00
Deviseで認証メールを手動で送信したい
再送方法
Qiita - deviseの確認メールの実装で困ったとき
RubyDoc - Module: Devise::Models::Confirmableほぼここに書いてあるとおりで、Devise参照先も書いてあるとおりなんですがこれです。
User.find(1).send_confirmation_instructions # manually send instructionsこの操作をするシチュエーション
- メーラー側でなんらかの不具合がありメールが送信されなかった
- Workerが止まってしまいメール送信用のキューをロストした
等が考えられます。
結構運用中に発生しがちで毎回どうやって再送するんだっけ?って調べてたので書きました。以上です。
- 投稿日:2020-05-19T09:41:20+09:00
[Rails5] Rspec -validation編-
はじめに
今回はModelのvalidationを対象にRspecを書きます
・name,email,passwordがあれば有効である事
・name,email,passwordが無ければ無効である事以上の2点をテストしたいと思います。
1. テスト対象
validates :name, presence: true, validates :email, presence: true, validates :password, presence: true,テスト対象はUser登録時のvalidationを対象にします。
今回はvalidationの有効性のみ検証したいので、上記の様に簡素なコードとします。2.実装
require 'rails_helper' Rspec.decribe User, type: model do describe '#validates' do context '名前、メアド、パスワードが正しければ' do it '有効である事' do @user = User.new ({ name: "テスト太郎", email: "xxx@yyy.jp", password: "111111", }) expect(@user).to be_valid end end context '名前、メアド、パスワードが正しくなければ' do it 'validateされる事' do @user = User.new ({ name: "", email: "", password: "", }) expect(@user.valid?).to be_falsy end end end endインスタンス変数にそれぞれ正しいオブジェクトと正しくないオブジェクトを代入します。
validationgが有効であるかテストする為にbe_valid(プレディカットマッチャ)を使い、反対に有効では無い時はfalseが返ってくる事を確認する為にbe_falsyを使っています。
*オブジェクトを作る時のnewメソッド直後の波括弧はvalue,括弧はkeyそれぞれに与えてあげないといけない見たいです。個人的にちょっと嵌りました。
3.テスト結果
2 examples, 0 failures通りましたね。
validation対象のRspecはシンプルな記述ができるので理解し易いと感じました。
最後に
今回はまとめて実装して見ましたが本来各カラム毎にテストを走らせる必要があると思います。
それとコード叩いてて思ったのは自分自身、各括弧 (){}[] をそれぞれ感覚で使っていたので改めて理解する必要があるなと感じました。また記事にしたいと思います。
ps→
日本うなぎの稚魚はオーストラリアから海流に乗ってやってくるらしい。
- 投稿日:2020-05-19T08:41:00+09:00
【備忘録】Rails3ルーティング確認
はじめに
今回はタイトルの通りにRailsにおけるルーティングの確認方法を残します。
触れているシステムのバージョンが古いため、Webブラウザでの確認が出来ずに詰まりました・・・。環境
Rails 3.0.19
docker-compose version 2Dockerコンテナからコマンドで確認する
1. サービス用コンテナを起動する
docker-compose up -d-d:デタッチド・モード: バックグラウンドでコンテナを実行し、新しいコンテナ名を表示
2. railsがインストールされているコンテナに入る(今回はappコンテナ)
docker-compose run app /bin/bashdockerやRailsにバージョンによって、コマンドが変わります。
直近で多く見られるコマンドは以下の通り。docker-compose exec app bash3. ルーティング確認コマンドを実行する
[root@[コンテナID] trunk]# bundle exec rake routes上記コマンドですと全件出力されてしまい見づらいため、grepコマンドを利用すると見やすいです。
[root@[コンテナID] trunk]# bundle exec rake routes | grep [絞り込みたい文字列]参考