20200327のRubyに関する記事は7件です。

yieldとproc

yieldとproc

今まで何度もブロックを使ってきた
しかし、今まで使ってきたのは既存のメソッド(each,mapなど)

自分でもブロックで使うメソッドは定義できるのか?

【結論】できる

ここからはブロックを利用するメソッドの定義、処理を引数や変数として渡す方法をまとめる

各エフェクトにcallというメソッドを実装する

yield→ブロックを利用するメソッドの定義をする

渡されたブロックを実行するためにメソッドないでyieldを使う

def greeting
  puts 'おはよう'
  yield
  puts 'こんばんは'
end

greeting do
  puts 'こんにちは'
end
=> おはよう
   こんにちは
   こんばんは

yieldは引数をブロックに渡したり、戻り値を受け取って出力もできる

ブロックを明示的にメソッドの引数として受け取るには?
→引数名の前に&をつける

ブロックの引数はメソッド定義につき一つしか指定できない
また、他の引数がある場合はブロックの引数を必ず最後に指定する

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ツイッター風Railsアプリをデプロイする(前編:unicornのみで取り急ぎ繋げよう)

この記事の基本的な方針

この記事は、過去記事で作ったアプリをEC2でデプロイします。
手を動かしながら読みたいようでしたら、以下でこのアプリを手に入れてください。

Terminal
$ git clone https://github.com/annaPanda8170/cheaptweet.git
$ bundle install
$ bundle exec rake db:create
$ bundle exec rake db:migrate

これ自体の作り方は、こちら
Rails5.2.4.2_でのみ動作確認しています。
基本解説はしません。手順のみ示します。

想定する読み手

既に一度Railsアプリをチュートリアルやスクール等で作りデプロイしたこのある方を想定しています。
Mac使用で、パソコンの環境構築は完了し、AWSのアカウントを持っていることが前提です。

具体的な手順

①インスタンスを作り、ssh接続でログインする

 instance.png

ami.png

type.png

key.png

ela.png

add.png

rela.png

check.png

11.png

22.png

33.png

Terminal(ローカル)
# ホームディレクトリ直下に.ssh/隠しディレクトリを事前に作ってます

$ cd
# 別に移動しなくても問題ないが、隠しディレクトリに入れといた方が無難
$ mv Downloads/****鍵の名前****.pem .ssh/

$ cd .ssh/

# ****鍵の名前****.pemのファイルに関して所有者のみ読み出し・書き込みの権限を与える意
# (所有者も実行権限がなく、所有者グループとその他はなんの権限もない)
$ chmod 600 ****鍵の名前****.pem

# ログイン
$ ssh -i ****鍵の名前****.pem ec2-user@****ここはElasticIP****
Output
Are you sure you want to continue connecting (yes/no)?
Terminal(ローカル)
yes
Output
Warning: Permanently added '54.250.55.251' (ECDSA) to the list of known hosts.

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/

②諸々インストールと、GitHub連携

Terminal(EC2)
# もしアップデートしろと言われたら以下を実行
# アップデートしろと言われてなくてやっても問題ないので一応やってもいいかも
$ sudo yum -y update

# 諸々基本インストール

$ sudo yum -y install git make gcc-c++ patch libyaml-devel libffi-devel libicu-devel zlib-devel readline-devel libxml2-devel libxslt-devel ImageMagick ImageMagick-devel openssl-devel libcurl libcurl-devel curl
$ sudo curl -sL https://rpm.nodesource.com/setup_6.x | sudo bash -
$ sudo yum -y install nodejs  # 今回はJSは使ってないが一応

# 諸々Ruby・Rails関係インストール

$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv 
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ source .bash_profile
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
$ rbenv rehash 
# 自身のRubyのバージョンを確認して以下。結構時間かかります
$ rbenv install 2.5.1
$ rbenv global 2.5.1
$ rbenv rehash
# 確認は
# ruby -v

# MySQLインストール
$ sudo yum -y install mysql56-server mysql56-devel mysql56

# MySQL起動
$ sudo service mysqld start
# 確認は
# sudo service mysqld status

# MySQLパスワード設定
$ sudo /usr/libexec/mysql56/mysqladmin -u root password
# 確認は
# mysql -u root -p

# SSH鍵ペア関連

# 鍵ペア作成
$ ssh-keygen -t rsa -b 4096
# この後何も入力せずにEnter三回
# 鍵ペア表示
$ cat ~/.ssh/id_rsa.pub
# 表示された値を ssh-rsa から最後までまるまるコピー
webBrowser
https://github.com/

git.png

ee.png

ssh.png

Terminal(EC2)
$ ssh -T git@github.com
Output
Are you sure you want to continue connecting (yes/no)?
Terminal(EC2)
yes

③unicorn導入

Gemfile
# 省略
group :production do
  gem 'unicorn', '5.4.1'
end
# 省略
Terminal(ローカル)
$ bundle install

config/unicorn.rbを作成

config/unicorn.rb
app_path = File.expand_path('../../', __FILE__)
worker_processes 1
working_directory app_path
pid "#{app_path}/tmp/pids/unicorn.pid"
listen 3000
stderr_path "#{app_path}/log/unicorn.stderr.log"
stdout_path "#{app_path}/log/unicorn.stdout.log"
timeout 60
preload_app true
GC.respond_to?(:copy_on_write_friendly=) && GC.copy_on_write_friendly = true
check_client_connection false
run_once = true
before_fork do |server, worker|
  defined?(ActiveRecord::Base) && ActiveRecord::Base.connection.disconnect!
  if run_once
    run_once = false 
  end
  old_pid = "#{server.config[:pid]}.oldbin"
  if File.exist?(old_pid) && server.pid != old_pid
    begin
      sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
      Process.kill(sig, File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH => e
      logger.error e
    end
  end
end
after_fork do |_server, _worker|
  defined?(ActiveRecord::Base) && ActiveRecord::Base.establish_connection
end
config/environments/production.rb
# 以下をコメントアウトする
# config.assets.js_compressor = :uglifier     
config/database.yml
#production:
#  <<: *default
#  database: ***名前***_production
#  username: ***名前***
#  password: <%= ENV['***名前***_DATABASE_PASSWORD'] %>

#    |
#    V

production:
  <<: *default
  database: '***名前***'_production
  username: root
  password: <%= ENV['DATABASE_PASSWORD'] %>
  socket: /var/lib/mysql/mysql.sock

プッシュしてmasterにマージする

Terminal(EC2)
$ cd
$ sudo mkdir /var/www/
$ sudo chown ec2-user /var/www/
$ cd /var/www/

gggit.png

Terminal(EC2)
$ git clone ***上でコピーしたGitHubのURL***

④Swap領域の追加

Terminal(EC2)
$ cd
$ sudo dd if=/dev/zero of=/swapfile1 bs=1M count=512
$ sudo chmod 600 /swapfile1
$ sudo mkswap /swapfile1
$ sudo swapon /swapfile1
$ sudo sh -c 'echo "/swapfile1  none        swap    sw              0   0" >> /etc/fstab'
Terminal(EC2)
$ cd  /var/www/***アプリ名***
# ローカルでバンドラーのバージョンを確認
$ gem install bundler -v ***確認したバージョン***
$ bundle install

$ rake secret
#出てきたキーをコピー
$ sudo vim /etc/environment
/etc/environment
DATABASE_PASSWORD='***MySQLのパスワード***'
SECRET_KEY_BASE='***先程コピーしたキー***'
Terminal
# 再ログイン
$ exit
$ ssh -i ****鍵の名前****.pem ec2-user@***ここはElasticIP***

#上の環境変数の確認は
# env | grep SECRET_KEY_BASE
# env | grep DATABASE_PASSWORD

juki.png

juki2.png

ポート範囲が3000、ソースが0.0.0.0/0

juki4.png

Terminal(EC2)
$ cd /var/www/***アプリ名***
$ rails db:create RAILS_ENV=production
$ rails db:migrate RAILS_ENV=production
$ bundle exec unicorn_rails -c config/unicorn.rb -E production -D
$ rails assets:precompile RAILS_ENV=production

# 起動
$ RAILS_SERVE_STATIC_FILES=1 unicorn_rails -c config/unicorn.rb -E production -D
webBrowser
http://***ここはElasticIP***:3000

以上でとりあえず、繋がるはずです。
ただ、非常に遅いですね。

パワーアップして通常のアプリとして動作させるにはNginxが必要です。
マージをコマンド一つで本番環境まで反映させるにはCapistranoが必要です。
これらの導入は後編で。

もし困ったら

①ログ確認

/var/www/***アプリ名***/log/unicorn.stderr.logtailcatlessvimあたりのコマンドで確認する。

②unicornの再起動

Terminal(EC2)
$ ps aux | grep unicorn
$ kill ***ユニコーンのPID***
$ RAILS_SERVE_STATIC_FILES=1 unicorn_rails -c config/unicorn.rb -E production -D
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Kinx 実現技術 - Garbage Collection

Garbage Collection

はじめに

「見た目は JavaScript、頭脳(中身)は Ruby、(安定感は AC/DC)」 でお届けしているスクリプト言語 Kinx。作ったものの紹介だけではなく実現のために使った技術を紹介していくのも貢献。その道の人には当たり前でも、そうでない人にも興味をもって貰えるかもしれない。

前回のテーマは JIT。今回のテーマは Garbage Collection。

GC は特別なことはしていない、というよりむしろ複雑なことはせずに、シンプルにしました。一番の目的はリソース管理というのも勿論あるものの、フリー・オブジェクトのキャッシングにある。malloc/free の回数を減らす。これが結構パフォーマンスに影響する。

実現手法

マーク・アンド・スイープ

ストップ・ザ・ワールドのマーク・アンド・スイープで、一旦全ての処理を止めて GC する。(あえて Kinx の)疑似コードであらわすと次のような感じ。

function mark(p) {
    // Stop the recursive check
    return if (p.mark);
    p.mark = true;

    // Check the mark recursively
    p.innerObjects.each(mark);
}

function markAndSweep(stack, context) {
    // Initialization
    context.aliveList.each(&(p) => { p.mark = false; });

    // Mark
    stack.each(mark);

    // Sweep
    context.aliveList = context.aliveList.filter(&(p) => {
        if (!p.mark) {
            context.deadList.push(p);
        }
        return p.mark;
    });
}

マーク

まず、マークと呼ばれるフェーズで生きているオブジェクト全てにマークを付けていく。ここでマークを漏らすと生きているのに回収されてしまっておかしくなるので漏らさないように。例のレキシカル・スコープや、関数オブジェクトに括り付いたフレーム等も全て対象。

マークの際のルートとなるのはスタック。スタック上のオブジェクトをルートに参照を全て辿って到達するオブジェクトに対し、片っ端からマークしていく。オブジェクトは循環参照しているケースがあるので、一度マークを付けたら次にまた到達したときには何もしないようにガードしておく。

また、Kinx ではスタック以外のルートとして以下がある。

  • 独立して保持している例外オブジェクト。
  • 正規表現リテラルの管理リスト。

晴れて全てのオブジェクトにマークが付いたら、スイープのフェーズに入る。

スイープ

オブジェクトは全て alive リストと dead リストで管理されている。ただし、alive の方は線形リスト、dead の方はベクターである。

なぜなら、alive リストは死んだオブジェクトを途中から引っこ抜いていく形で使われるのに対し、dead リストは死んだオブジェクトの再利用に使われるだけなので途中から引っこ抜くことがないため。こんな感じ。

aliveList -> obj1 -> obj2 -> obj3 -> obj4 -> obj5 -> ... -> objN -> ...
                             ~~~~ dead!
                           ↓
                                ,---> To deadList
                               /
aliveList -> obj1 -> obj2    obj3    obj4 -> obj5 -> ... -> objN -> ...
                      |               ↑
                      `---------------'

Kinx ではオブジェクト・サイズごとに全て異なるアロケーターを持ち、別々の alive/dead リストで管理することにしてある。そうすることで、オブジェクト再利用時の処理を dead リストからの pop 一発でいけるようにしている。

スイープ・フェーズでは alive リスト全てチェックし、マークの付いていないオブジェクトをリストから外して dead リストに push。

gctick

回収オブジェクトが多くないと GC するのは無駄。なので、まずは一定間隔で GC するようになっている。そのカウンタとして gctick が用意してある。一定回数インストラクションを実行したら GC がキックされる。

今後 GC 中のオブジェクト状況をプロファイルして gctick の値をコントロールしようとは思っている。

雑感

本来管理すべきリソースはメモリだけではない。ファイル・ディスクリプタやソケット等 open/close が伴うものは適切にリソース管理しなくてはならない。

C++ では RAII という機構でほぼほぼ気にせず華麗にリソース管理できるようにしていたのが、メモリ以外は try-finally で自分で管理する必要性が出てきているのはもしかして退化なのでは?、といささか感じなくもない。

C++
std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(filename, "r"), fclose);

に対して、

Kinx
function open(filename, mode, func) {
    var f;
    try {
        f = new File(filename, mode);
        return func(f);
    } finally {
        f.close();
    }
}

。。。C++ のほうが簡単に書けるな。

まあ、GC するときに close するようにはしてはいるもののタイミングは予測不能。その性質上、予測不能でも問題ないものにしか適用できない。また、迂闊にオブジェクトが残ったりするとシステム側でリソース数に上限があったりするから、ちゃんと解放してあげないといけない。これを GC 的アルゴリズムの(予測不可能な世界の)中で実現するのは難しい。参照カウンタくらいか。

実は Kinx でも XML ドキュメント等は GC の時に解放されるが、解放するかどうかの判断は参照カウンタで実現している。XML ドキュメントは自身が管理する XML ノードから参照されているため、全ての管理対象 XML ノードがフリー状態になっていないと解放できない。したがって参照カウンタ。以下がソース。

今後

今後、GC を改善するとしたら以下のような感じ。ただし、GC のような裏方は本来の仕事を邪魔しない程度に関わるのが筋。GC が明らかにボトルネックになっているといったケース、その機能が言語本来の機能要求を満たすのに必要、という以外、優先度を上げるべきではないだろう。

  • gctick コントロール
  • Force GC ... これは必要。
  • native 中の GC
  • インクリメンタル GC

おわりに

Garbage Collection は学術的にも奥が深く、ハマったらここだけでも相当なパワーが必要な領域。現実的な範囲で実用上の要求事項が満たせるレベルで動作させることを一番に考えてこういう実装に。

余裕ができたら高度な GC を取り入れても良いとは思うが、何事もプロファイルが重要。手を付けるならちゃんとボトルネックになってることを確認してからですね。

尚、GC 関連の処理は以下のソースにあります。

では、次は Fiber の予定。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Ruby】getsメソッドの入力値は改行付きの文字列である

背景

某転職テストのスキルチェックを受けた結果がボロボロで悔しくなり、某スキルチェックサイトで毎日コーディングして訓練しようと思い始めた所、あまりにも単純な問題で詰まり悲しみに包まれかけたのでアウトプットします。

また、Railsエンジニア志望なのでRubyのコードを書いていきます。

どことは書いてはないですがスキルチェックの内容は外部流出厳禁なので、一応似たような形に書き換えてます。

getsメソッド

getsメソッドはユーザーがキーボードで入力した値を文字列として取得するメソッド。

という説明自体は間違っていないのですが、

sample.rb
# 入力した値が"Hello"だった場合、”World"を出力しましょう。
input = gets #Helloを入力する
if input == "Hello"
  puts "World"
else
  puts "Helloではありません"
end
> "Helloではありません"

のように、間違いなくHelloを入力しているのにfalseが返ってくるんですね。えぇー!?って思いますやん。
調べた所、getsメソッドは正確に言うと、

入力した値の末尾に改行が付与された文字列として取得するメソッド

となります。

ターミナル(irb)
irb(main):001:0> input = gets
Hello
=> "Hello\n" #末尾に\nが付く

マジか…:sob:
このように1分で解けそうな問題なのに原因が分からず、結局50分掛かりました。ぐやじい〜〜

と言うことで、今回の問題のソリューションはこれ。

sample.rb
# 入力した値が"Hello"だった場合、”World"を出力しましょう。
input = gets.chomp # ここー!!!!
if input == "Hello"
  puts "World"
else
  puts "Helloではありません"
end
> "World"

chompを付けることで改行をなくせるんですね。
基礎中の基礎とはいえ普段使わないメソッドだから勉強になりました:hugging:

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

関連する質問を表示したい(Q&Aサイト)

現在ポートフォリオとして大学受験をテーマにしたQ&Aサイトを作成しています

関連する質問を表示する機能の実装に手間取ったので、自分用にまとめ。

何をもって関連とするか

質問同士を関連づけるための基準が必要ですが、今回は質問にカテゴリーを紐付け、同じカテゴリーに属するものを関連する質問とします

モデル

models/question.rb
  has_many :category_relationships
  has_many :categories, through: :category_relationships, source: :category
models/category_relationship.rb
belongs_to :question
belongs_to :category
models/category.rb
  has_many :category_relationships
  has_many :questions, through: :category_relationships, source: :question

実装

実現したい動き

questionモデルのインスタンスメソッドとして、関連する質問を取得するrelated_questionsメソッドを追加します

  1. 特定の質問から、カテゴリーを取得
  2. そのカテゴリー毎の質問を取得
  3. 上記の操作で得た質問の配列を「関連する質問」とし、そのいくつかをランダムで表示する(今回は4つ)
  4. 質問の重複と、レシーバーとなる質問自身を含まないように配慮

このような形で実装していきたいと思います

1.特定の質問から、カテゴリーを取得

  1. CategoryRelationshipテーブルから、question_idがレシーバーと等しいレコードを取得
  2. そのレコードからカテゴリーを取得
  3. 上記の結果をrelated_categoriesという変数にいれる

可読性を考慮して、selfをつけておきます

models/question.rb
def related_questions
  related_categories = CategoryRelationship.where(question_id: self.id).map(&:category)
end

2.カテゴリー毎の質問を取得

  1. 質問を入れておくために、related_questionsというからの配列を定義
  2. related_categories内のカテゴリー一つ一つから、関連する質問を取得する
  3. その質問をrelated_questionsに入れていく
models/question.rb
def related_questions
  related_categories = CategoryRelationship.where(question_id: self.id).map(&:category)
  # ここから
  related_questions = []
  related_categories.each do |category|
    category.questions.each do |question|
      related_questions << question
    end
  end
  # ここまで追加
end

eachがネストしちゃってますが…とりあえず動くのでこのままで。
より良い方法を思いついたら追記します

3.ランダムで取得

明示的にreturnをつけておきます

models/question.rb
def related_questions
  related_categories = CategoryRelationship.where(question_id: self.id).map(&:category)
  related_questions = []
  related_categories.each do |category|
    category.questions.each do |question|
      related_questions << question
    end
  end
  # ここから
  return related_questions.sample(4)
  # ここまで追加
end

4.重複を避ける

このままでは複数のタグをつけている質問が重複して取得される可能性がありますね
related_questions.distinct.sample(4)
的なことをしたいんですが、配列に対してdistinctを使うとエラーが発生します

Question.first.related_questions.distinct.sample(4)
=> NoMethodError: undefined method `distinct' for #<Array:xxxxx>

配列から重複を取り除いてくれるメソッドを探してみたところ、uniqというメソッドを発見しました
https://docs.ruby-lang.org/ja/latest/method/Array/i/uniq.html

これを使いましょう

models/question.rb
def related_questions
  related_categories = CategoryRelationship.where(question_id: self.id).map(&:category)
  related_questions = []
  related_categories.each do |category|
    category.questions.each do |question|
      related_questions << question
    end
  end
  return related_questions.uniq.sample(4) #この行に追記
end

5.レシーバー自身を含めない

このままではrelated_questions内にレシーバー自身が含まれてます
related_questions.distinct.where.not(questions_id: self.id).sample(4)
的なことをしたいんですが、配列に対してwhereを使うと上と同じエラーが発生します

ここは素直にif文を使っていきます

models/question.rb
def related_questions
  related_categories = CategoryRelationship.where(question_id: self.id).map(&:category)
  related_questions = []
  related_categories.each do |category|
    category.questions.each do |question|
      related_questions << question unless question == self #この行に追記
    end
  end
  return related_questions.uniq.sample(4)
end

これでメソッドは完成です!
N+1対策もやっておきたいところです

表示するまでの部分は省略します

最後に

最初に書きましたが、何をもって関連とするのかが重要な気がします
他のサイトの関連するものを表示する機能ってどうなってるんですかね…
同じカテゴリー内でPV数、いいね数を基準にする形の実装もやってみたいです

おかしい部分への指摘やアドバイスなどいただけると嬉しいです

自分のポートフォリオでは今回の実装とコードが少し異なるのですが、大体同じ流れで実装してます。
テストも書いてるので良かったらのぞいてみてください
https://github.com/YutoKashiwagi/Ukarimi/pull/93/files
こっちのコードについての意見も大歓迎です!(むしろこっちに対するレビューが欲しいです)

読んでいただきありがとうございました!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【爆速成長!】プログラミング駆け出し〜オリジナルポートフォリオ作成までに参考にしたサイト一覧

はじめに

完全未経験の30歳文系が、プログラマー転職に向けて活動してきました。
2019年8月に初めてProgateでプログラミングに触れてから、約5ヶ月。
2020年3月現在、オリジナルポートフォリオの完成まで至りました。

最初の頃は右も左もホンッットに何も分からない状態でした。
その当時を思い返すと、少しは成長したのかなーって思います。

分からないことは即調べて、有益に感じたサイトやQiitaの記事は全てお気に入りに入れていました。

そこで、これまで参考にさせて頂いたサイトを一つにまとめてみます。
※カテゴリー別にまとめてみました

参考になったサイト

学習方法・概念・その他有益なもの

未経験者には全てが黒魔術に見える呪いがある
https://qiita.com/mackey0022/items/73f77873facc22e22c8c

不思議の国のSE用語
https://qiita.com/t_nakayama0714/items/478a8ed3a9ae143ad854

質問は恥ではないし役に立つ
https://qiita.com/seki_uk/items/4001423b3cd3db0dada7

プログラミング初心者歓迎!「エラーが出ました。どうすればいいですか?」から卒業するための基本と極意(解説動画付き)
https://qiita.com/jnchito/items/056325421b7e36f02335

コード関連

良いコードを書く技術(まとめ)
https://qiita.com/NoriakiOshita/items/e60ab5bb01b90d927ae5

CSSのクラス名を決めるときに使うリストをつくりました
https://qiita.com/manabuyasuda/items/dbb76ed36970bec95470

Naming -名前付け-
https://qiita.com/Koki_jp/items/f3d3e824f98d182d4100

コマンド関連

Macのターミナルコマンド一覧(基本編)
https://qiita.com/ryouzi/items/f9dee1540a04a0bfb9a3

Linuxターミナルコマンド一覧(中級編)
https://qiita.com/ryouzi/items/73f63f09573b7b4e246c

HTML関連

SEO対策として最低限押さえておきたいHTML/HTML5マークアップの大事な6つのポイント
https://creive.me/archives/8814

HTMLのtableでテーブルを作る方法と応用テクニックを解説
https://webliker.info/02035/

CSS関連

もう迷わない!CSS Flexboxの使い方を徹底解説
https://webdesign-trends.net/entry/8148#i-2

カラーコード一覧表
http://www.netyasun.com/home/color.html

上下中央揃えのCSSまとめ
Flexboxがたった3行で最も手軽
https://ics.media/entry/17522/

Bootstrap関連

とほほのBootstrap 4入門
http://www.tohoho-web.com/bootstrap/index.html

Bootstrapのグリッドシステムの使い方を初心者に向けておさらいする
http://websae.net/twitter-bootstrap-grid-system-21060224/

Bootstrap4カラムの位置を調整【カラムのオフセット】
https://webnetamemo.com/coding/bootstrap4/201902227791

Ruby/Rails関連

【Ruby/Ruby on Rails】重要用語・基礎知識まとめ【プログラミング学習開始128日目】
https://qiita.com/fuku_tech/items/4d2517ec5bbd53726997

[Ruby] privateメソッドの本質とそれを理解するメリット
https://qiita.com/kidach1/items/055021ce42fe2a49fd66

Railsのモデル検索あれこれ
https://qiita.com/tono0123/items/576a4a4659b51860f304

【Rails】form_forの使い方を徹底解説!
https://pikawaka.com/rails/form_for

bundler、bundle execについて ※自分用メモ
https://qiita.com/dawn_628/items/1821d4eef22b9f45eea8

rails generate migrationコマンドまとめ
https://qiita.com/zaru/items/cde2c46b6126867a1a64

Railsバリデーションまとめ
https://qiita.com/h1kita/items/772b81a1cc066e67930e

Railsのバリデーションエラーのメッセージの日本語化
https://qiita.com/Ushinji/items/242bfba84df7a5a67d5b

[Rails]不要になったmodelの削除方法
https://bokuranotameno.com/post-9880/

Rails で includes して N+1 問題対策
https://qiita.com/hirotakasasaki/items/e0be0b3fd7b0eb350327

Rails5.2から追加された credentials.yml.enc のキホン
https://qiita.com/NaokiIshimura/items/2a179f2ab910992c4d39

git関連

Gitコマンド早見表
https://qiita.com/kohga/items/dccf135b0af395f69144

君には1時間でGitについて知ってもらう(with VSCode)
https://qiita.com/jesus_isao/items/63557eba36819faa4ad9

git commit を取り消して元に戻す方法、徹底まとめ
http://www-creators.com/archives/1116

[Git] .gitignoreの仕様詳解
https://qiita.com/anqooqie/items/110957797b3d5280c44f

GitHubで特定のファイルやフォルダを管理対象から除外する方法
https://fantastech.net/gitignore

DB関連

4ステップで作成する、DB論理設計の手順とチェックポイントまとめ
https://qiita.com/nishina555/items/a79ece1b54faf7240fac

【DB設計の基礎】DBとは?〜論理設計
https://qiita.com/yosemite2307/items/33f42f4337c8ee9b0a9d

よく使うMySQLコマンド集
https://qiita.com/CyberMergina/items/f889519e6be19c46f5f4

若手プログラマー必読!5分で理解できるER図の書き方5ステップ
https://it-koala.com/entity-relationship-diagram-1897

Devise関連

Devise+OmniAuthでユーザ認証を実装する手順
https://qiita.com/zenizh/items/94aec2d94a2b4e9a1d0b

[Rails] deviseの使い方(rails5版)
https://qiita.com/cigalecigales/items/f4274088f20832252374

【Rails】deviseの使い方を徹底解説!
https://pikawaka.com/rails/devise

Rspec関連

使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」
https://qiita.com/jnchito/items/42193d066bd61c740612

Rails5でコントローラのテストをController specからRequest specに移行する
https://qiita.com/t2kojima/items/ad7a8ade9e7a99fb4384

Solidus関連

Solidus - Productsまわりの概念まとめ
https://forest-valley17.hatenablog.com/entry/2018/10/10/094742

docker関連

【図解】Dockerの全体像を理解する -前編-
https://qiita.com/etaroid/items/b1024c7d200a75b992fc

Dockerの基礎をまとめてみた ~ 第一章:コンテナ?Dockerとは?
https://qiita.com/supaiku2452/items/8b06b774c0e2fce7df92

コンテナ開発の始め方
https://qiita.com/niisan-tokyo/items/bcb89c9de82ba465d200

Docker、ボリューム(Volume)について真面目に調べた
https://qiita.com/gounx2/items/23b0dc8b8b95cc629f32

docker-composeを使うと複数コンテナの管理が便利に
https://qiita.com/y_hokkey/items/d51e69c6ff4015e85fce

いまさらだけどDockerに入門したので分かりやすくまとめてみた
https://qiita.com/gold-kou/items/44860fbda1a34a001fc1

docker-compose コマンドまとめ
https://qiita.com/wasanx25/items/d47caf37b79e855af95f

Rubocop関連

Railsの品質を上げるRuboCopとは?インストールや使い方を紹介!
https://kitsune.blog/rails-rubocop

AWS関連

(下準備編)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで
https://qiita.com/naoki_mochizuki/items/f795fe3e661a3349a7ce

無料!かつ最短?で Ruby on Rails on Docker on AWS のアプリを公開するぞ。
https://qiita.com/at-946/items/1e8acea19cc0b9f31b98

サーバー・本番環境関連

なぜrailsの本番環境ではUnicorn,Nginxを使うのか?  ~ Rack,Unicorn,Nginxの連携について ~【Ruby On Railsでwebサービス運営】
https://qiita.com/takahiro1127/items/fcb81753eaf381b4b33c

RailsアプリをAWS、unicorn、nginxで手動デプロイして独自ドメインを紐づけるまで
https://qiita.com/happytarou0228/items/3771b13217483c35965d

最後に

個人的には、特にAWSや本番環境構築に大苦戦しました。
駆け出しエンジニアの皆さんに、少しでも役立てもらえたら幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails6 のちょい足しな新機能を試す 125(endless range bug fix編)

はじめに

Rails 6 に追加された新機能を試す第125段。 今回は、endless range bug fix 編です。
Rails 6.0.0 では、 (1..) などのエンドレスな Range で include? メソッドを呼ぶと RangeError が発生するバグがありました。

Rails 6.0.1 以降では修正されています。

Ruby 2.6.5, Rails 6.0.1, Rails 6.0.0 で確認しました。

$ rails --version
Rails 6.0.1

今回は、 rails new して、 app ディレクトリの下にファイルを作って確認してみます。

Rails プロジェクトを作る

Rails プロジェクトを新たに作成します。

$ rails new rails_sandbox
$ cd rails_sandbox

スクリプトを作成する

Range#include? を実行するスクリプトを作成します。

scripts/endless_range.rb
p (1..).include?(2)

Ruby 2.6.5 では

エラーになりません。

$ ruby -v scripts/endless_range.rb
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-linux-musl]
true

Rails 6.0.1 では

Rails 6.0.1 (以降) では、エラーになりません。

$ bin/rails runner scripts/endless_range.rb
Running via Spring preloader in process 263
true

Rails 6.0.0 では

RangeError が発生します。

$ bin/rails runner scripts/endless_range.rb
...
         2: from scripts/endless_range.rb:1:in `<main>'
         1: from /usr/local/bundle/gems/activesupport-6.0.0/lib/active_support/core_ext/range/include_time_with_zone.rb:14:in `include?'
/usr/local/bundle/gems/activesupport-6.0.0/lib/active_support/core_ext/range/include_time_with_zone.rb:14:in `last': cannot get the last element of endless range (RangeError)

試したソース

https://github.com/suketa/rails_sandbox/tree/try125_endless_range

参考情報

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む