MRからエンジニアへ

プログラミング初心者がご飯を食べれるようになるまで

【RSpec】system specモジュールの作成

初心者ということもあり、用語についても調べてアウトプットしていきます!

初心者の同志の方の勉強の一助になれれば幸いです♪

 

それでは頑張っていきましょう

 

RSpec】system specモジュールの作成



RSpecを記述していると、各スペックで共通したものが出てきます。 loginとかです。 moduleを作成しincludeしていきます!

spec/support/login_macros.rb

module LoginMacros
  def login_as(user)
    visit root_path
    click_link 'Login'
    fill_in 'Email', with: user.email
    fill_in 'Password', with: 'password'
    click_button 'Login'
  end
end



作成しました!

spec/rails_helper.rb

#コメントアウトを外す
Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f }



RSpec.configure do |config|

#追記
  config.include LoginMacros
end


supportディレクトリを読み込めるように定義。 モジュールを使用できるようにします。


以下実際にモジュールを使用していきます。

spec/system/user_sessions_rspec.rb


require 'rails_helper'

RSpec.describe 'UserSessions', type: :system do

  #ローカル変数を定義
  let(:user) { create(:user) }

  describe 'ログイン後' do
    context 'ログアウトボタンをクリック' do
      it 'ログアウト処理が成功する' do
        login_as(user)
        click_link 'Logout'
        expect(page).to have_content "ログアウトt"
        expect(current_path).to eq root_path
      end
    end
  end
end

【Github】草を生やす(コミット履歴一括変更)

初心者ということもあり、用語についても調べてアウトプットしていきます!

初心者の同志の方の勉強の一助になれれば幸いです♪

 

それでは頑張っていきましょう

 

Github】草を生やす(コミット履歴一括変更)

 

色々な記事を読んで実践したが、草が全然生えない!!
という時に参考にして欲しいです。私の解決した方法を記録します。
(実践した方法は下に書いておきます。)

まず、コミットのAuthorとCommitterを確認します。

$ git log --pretty=full
commit 文字列
Author: 名前 <your.email@example.com>
Commit: 名前 <your.email@example.com>

   コミット内容



git logで確認してみるとメールアドレスが不一致。
なんだこのふざけたメールアドレスは〜と思って原因を探ったら、
Railsチュートリアルの最初のgithubの設定をそのまま書いてました。
(私の純粋さが仇となりました)

解決策


今までのコミット履歴(83コミット)を全て変える方法です。

$ git filter-branch -f --env-filter "GIT_AUTHOR_NAME='Githubに登録した名前'; GIT_AUTHOR_EMAIL='Githubに登録したメールアドレス'; GIT_COMMITTER_NAME='Githubに登録した名前'; GIT_COMMITTER_EMAIL='Githubに登録したメールアドレス';" HEAD


名前とメールアドレスを間違わないようにこの一行にまとめる。


qiita.com

$ git push -f

草生えました! (やはり私の純粋さが原因)



実践した方法

ローカルのメールアドレスを確認

$ git config user.email


ローカルのメールアドレスを変更

$ git config user.email メールアドレス


グローバルのメールアドレスを確認

$ git config --global user.email "メールアドレス"


グローバルのメールアドレスを変更

$ git config --global user.email "メールアドレス"



このメールアドレスはGithubに登録されているメールアドレスと一致させてください。

【Rails】パスワードリセット機能の実装

初心者ということもあり、用語についても調べてアウトプットしていきます!

初心者の同志の方の勉強の一助になれれば幸いです♪

 

それでは頑張っていきましょう

 

パスワードリセット機能の実装

 

Sorceryのreset_passwordモジュールを使って実装していきます。

github.com

$rails g sorcery:install reset_password --only-submodules

実行するとmigrationファイルが作成されます。

#migrationファイル

class SorceryResetPassword < ActiveRecord::Migration
  def change
    add_column :users, :reset_password_token, :string, default: nil
    add_column :users, :reset_password_token_expires_at, :datetime, default: nil
    add_column :users, :reset_password_email_sent_at, :datetime, default: nil
  end
end
$bundle exec rails db:migrate

バリデーションの追加

#user.rb

validates :reset_password_token, uniqueness: true, allow_nil: true

・uniquenessは属性の値が一意であることを検証。
・allow_nilは、対象の値がnilの場合にバリデーションをスキップ。(reset_password_tokenはnilになるため、allow_nil: trueがないとユニーク制約に引っかかる)

Malerの作成

$ rails g mailer UserMailer reset_password_email
# config/initializers/sorcery.rb

Rails.application.config.sorcery.submodules = [:reset_password]

Rails.application.config.sorcery.configure do |config|
  config.user_config do |user|
    user.reset_password_mailer = UserMailer
  end
end

・reset_passwordをサブモジュールに追加
・UserMailerを定義

#app/mailers/user_mailer.rb

class UserMailer < ApplicationMailer
  default from: 'test@test.com' 

  def reset_password_email(user)
    @user = User.find(user.id)
    @url = edit_password_reset_url(@user.reset_password_token) 
    mail(to: user.email, subject: 'パスワードリセット')
  end
end

・送信元のメールアドレスを指定
・@urlでメールに記載するパスワードリセット用URLを定義
・宛先、件名を指定

Malerのビュー

# app/views/user_mailer/reset_password_email.text.erb

Hello, <%= @user.email %>
===============================================
 
You have requested to reset your password.

To choose a new password, just follow this link: <%= @url %>.
 
Have a great day!

app/views/layouts/mailer.html.erbも一緒にファイルが作成されているはず、 全てのクライアントがHTMLメールを受信出来る訳では無いので、両方作成し送信します。

コントローラー作成

$ rails g controller PasswordResets new create edit update
# app/controllers/password_resets_controller.rb

class PasswordResetsController < ApplicationController
  skip_before_action :require_login

  def new; end



#パスワードリセット対象のメールアドレスを申請して、リセットの対象を作成する

  def create 
    @user = User.find_by_email(params[:email])

    # ユーザーのメールアドレスがDBに存在すれば、パスワードをリセットするURL(ランダムトークン・有効期限を含む)をメールでユーザーに送信する
    @user.deliver_reset_password_instructions! if @user

    # 存在しないメールアドレスだとしてもこのメッセージを出力させる
    redirect_to(root_path, :notice => 'Instructions have been sent to your email.')
  end
    


#パスワードリセット用のメールのURLをクリックして、新しいパスワードを入力する 

  def edit
    @token = params[:id]
    @user = User.load_from_reset_password_token(params[:id])

    if @user.blank?
      not_authenticated
      return
    end
  end
      


#パスワードリセット(edit)ページにて、『更新する』ボタンでパスワードを変更する

  def update
    @token = params[:id]
    @user = User.load_from_reset_password_token(params[:id])

    if @user.blank?
      not_authenticated
      return
    end

    #パスワード確認の検証を機能させる
    @user.password_confirmation = params[:user][:password_confirmation]

    #一時トークンをクリアし、パスワードを更新する
    if @user.change_password(params[:user][:password])
      redirect_to(root_path, :notice => 'Password was successfully updated.')
    else
      render :action => "edit"
    end
  end
end

letter_opener_webでメールを確認

gem 'letter_opener_web'

をGemfileに追加することで、メールが実際に送受信されるかWebで見ることができるようになります。

bundle install
#config/routes.rb

mount LetterOpenerWeb::Engine, at: '/letter_opener' if Rails.env.development?

を追加します。

#config/environments/development.rb

Rails.application.configure do

  config.action_mailer.perform_caching = false
  config.action_mailer.default_url_options = { host: 'localhost:3000' }
  config.action_mailer.delivery_method = :letter_opener_web

end

設定できたので下記のURLから確認します。

http://localhost:3000/letter_opener

メールは送られているでしょうか? 本日はパスワードリセット機能を実装しました!

【エラー】 rails g config:install


初心者ということもあり、用語についても調べてアウトプットしていきます!

 

初心者の同志の方の勉強の一助になれれば幸いです♪

 

それでは頑張っていきましょう

今回はエラーです。 プログラミングにエラーは付き物ですね!

 

【エラー】 rails g config:install

$rails g config:install

Running via Spring preloader in process 34538
Could not find generator 'config:install'. Maybe you meant 'sorcery:install', 'draper:install' or 'rspec:install'
Run `rails generate --help` for more options.

ググるとspringが起動しているとエラーが起きるようです。

(最後にspringの解説を載せるのでここでは省略します。)

psコマンドで現在実行中のプロセスを一覧表示してみます。

$ps

  spring起動中でした。

killコマンドを使用してspringをダウンさせます。  

$kill -9 [springのPID]

ではもう一度。 

$rails g config:install

Running via Spring preloader in process 34600
create config/initializers/config.rb
create config/settings.yml
create config/settings.local.yml
create config/settings
create config/settings/development.yml
create config/settings/production.yml
create config/settings/test.yml
append .gitignore

できた!



springとは?


Spring is a Rails application preloader. It speeds up development by keeping your application running in the background so you don't need to boot it every time you run a test, rake task or migration.

github.com



SpringはRailsアプリケーションのプリローダーです。 アプリケーションをバックグラウンドで実行し続けることで開発をスピードアップするため、test、rake task、またはmigrationを実行するたびにアプリケーションを起動する必要はありません。とのことです。

rails cやrails sなども高速化してくれているようですが、今回は裏目にでて競合してしまったようです。

【Rails】多対多のアソシエーション


初心者ということもあり、用語についても調べてアウトプットしていきます!

初心者の同志の方の勉強の一助になれれば幸いです♪

 

それでは頑張っていきましょう

 

多対多のアソシエーション

タスクにお気に入り機能を付けたい!
多対多のアソシエーションを実装していきます。

最初に完成形を示します。

user.rb

has_many :tasks, dependent: :destroy
has_many :favorites, dependent: :destroy
has_many :task_favorites, through: :favorites, source: :task

task.rb

has_many :favorites, dependent: :destroy
belongs_to :user

favorite.rb

belongs_to :user
belongs_to :task

初学者としてはtask_favorites?どこから来たの? って感じです。

task.rbとfavorite.rbはまあ分かるなって感じですね。 問題はuser.rbの部分です。

user.rb

has_many :tasks, dependent: :destroy
has_many :favorites, dependent: :destroy
has_many :task_favorites, through: :favorites, source: :task
has_many :task_favorites, through: :favorites, source: :task

のところ。本当は、has_many :tasks, through: :favoritesと書きたいのです。

しかし、

has_many :tasks, through: :favorites

と書いてしまうと、user.rbの一番上のhas_many :tasksと記載が同じになってしまいますよね。

同じになると何がいけないかって、

railsでは後に書いた方が上書きされてしまうからです。

例えば、current_user.tasks とかいても、favoriteしたtaskをとってきてしまいます。

違う名前を付けて、多対多のアソシエーションを実装していきます!

【Rails】AWS 本番環境での画像アップデート(13章)

Ruby on Rails チュートリアルの復習です。

初心者ということもあり、用語についても調べてアウトプットしていきます!

初心者の同志の方の勉強の一助になれれば幸いです♪

 

それでは頑張っていきましょう

 

AWS 本番環境での画像アップデート(13章)

 

Rails 6.1.0

Railsチュートリアル 6.0(第6版)



Railsチュートリアル順調に進んでいたかと思ったら、下記のところ躓きました。

$ git push heroku user-microposts:master
$ heroku pg:reset DATABASE
$ heroku run rails db:migrate
$ heroku run rails db:seed

よしよし。

本番環境にアクセスっと。あれ!?HerokuのApplication errorの画面が... で、色々調べたところ

$ heroku run rails c

を試すと、

Missing service adapter for "S3" (RuntimeError)

が出ました。上に上にさかのぼると、

can't activate aws-sdk-s3 (~> 1.48), already activated aws-sdk-s3-1.46.0.
 Make sure all dependencies are added to Gemfile. (Gem::LoadError)

というエラーが出ているのが分かりました。

ほうほう。


チュートリアルと同様にaws-sdk s3 1.46.0でGemfileを書き換えましたが、1.48.0じゃないとダメなようです。

rails 6.1.0だからバージョンが違うんですかね。~> 1.48に変更したら上手くいきました!

ご挨拶

 

はじめまして。

ペン子と申します。

 

異業種からエンジニアを目指して日々奮闘しております。

Ruby on Rails を中心に投稿していきます。

気持ちが乗ってきたらプラスαで日常のことを書きます。

 

よろしくお願いします!